/*! *****************************************************************************
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.
***************************************************************************** */

var TypeScript;
(function (TypeScript) {
    TypeScript.DiagnosticCode = {
        error_TS_0_1: "error TS{0}: {1}",
        warning_TS_0_1: "warning TS{0}: {1}",
        Unrecognized_escape_sequence: "Unrecognized escape sequence.",
        Unexpected_character_0: "Unexpected character {0}.",
        Missing_close_quote_character: "Missing close quote character.",
        Identifier_expected: "Identifier expected.",
        _0_keyword_expected: "'{0}' keyword expected.",
        _0_expected: "'{0}' expected.",
        Identifier_expected_0_is_a_keyword: "Identifier expected; '{0}' is a keyword.",
        Automatic_semicolon_insertion_not_allowed: "Automatic semicolon insertion not allowed.",
        Unexpected_token_0_expected: "Unexpected token; '{0}' expected.",
        Trailing_separator_not_allowed: "Trailing separator not allowed.",
        AsteriskSlash_expected: "'*/' expected.",
        public_or_private_modifier_must_precede_static: "'public' or 'private' modifier must precede 'static'.",
        Unexpected_token: "Unexpected token.",
        Catch_clause_parameter_cannot_have_a_type_annotation: "Catch clause parameter cannot have a type annotation.",
        Rest_parameter_must_be_last_in_list: "Rest parameter must be last in list.",
        Parameter_cannot_have_question_mark_and_initializer: "Parameter cannot have question mark and initializer.",
        Required_parameter_cannot_follow_optional_parameter: "Required parameter cannot follow optional parameter.",
        Index_signatures_cannot_have_rest_parameters: "Index signatures cannot have rest parameters.",
        Index_signature_parameter_cannot_have_accessibility_modifiers: "Index signature parameter cannot have accessibility modifiers.",
        Index_signature_parameter_cannot_have_a_question_mark: "Index signature parameter cannot have a question mark.",
        Index_signature_parameter_cannot_have_an_initializer: "Index signature parameter cannot have an initializer.",
        Index_signature_must_have_a_type_annotation: "Index signature must have a type annotation.",
        Index_signature_parameter_must_have_a_type_annotation: "Index signature parameter must have a type annotation.",
        Index_signature_parameter_type_must_be_string_or_number: "Index signature parameter type must be 'string' or 'number'.",
        extends_clause_already_seen: "'extends' clause already seen.",
        extends_clause_must_precede_implements_clause: "'extends' clause must precede 'implements' clause.",
        Classes_can_only_extend_a_single_class: "Classes can only extend a single class.",
        implements_clause_already_seen: "'implements' clause already seen.",
        Accessibility_modifier_already_seen: "Accessibility modifier already seen.",
        _0_modifier_must_precede_1_modifier: "'{0}' modifier must precede '{1}' modifier.",
        _0_modifier_already_seen: "'{0}' modifier already seen.",
        _0_modifier_cannot_appear_on_a_class_element: "'{0}' modifier cannot appear on a class element.",
        Interface_declaration_cannot_have_implements_clause: "Interface declaration cannot have 'implements' clause.",
        super_invocation_cannot_have_type_arguments: "'super' invocation cannot have type arguments.",
        Only_ambient_modules_can_use_quoted_names: "Only ambient modules can use quoted names.",
        Statements_are_not_allowed_in_ambient_contexts: "Statements are not allowed in ambient contexts.",
        Implementations_are_not_allowed_in_ambient_contexts: "Implementations are not allowed in ambient contexts.",
        declare_modifier_not_allowed_for_code_already_in_an_ambient_context: "'declare' modifier not allowed for code already in an ambient context.",
        Initializers_are_not_allowed_in_ambient_contexts: "Initializers are not allowed in ambient contexts.",
        Parameter_property_declarations_can_only_be_used_in_a_non_ambient_constructor_declaration: "Parameter property declarations can only be used in a non-ambient constructor declaration.",
        Function_implementation_expected: "Function implementation expected.",
        Constructor_implementation_expected: "Constructor implementation expected.",
        Function_overload_name_must_be_0: "Function overload name must be '{0}'.",
        _0_modifier_cannot_appear_on_a_module_element: "'{0}' modifier cannot appear on a module element.",
        declare_modifier_cannot_appear_on_an_interface_declaration: "'declare' modifier cannot appear on an interface declaration.",
        declare_modifier_required_for_top_level_element: "'declare' modifier required for top level element.",
        Rest_parameter_cannot_be_optional: "Rest parameter cannot be optional.",
        Rest_parameter_cannot_have_an_initializer: "Rest parameter cannot have an initializer.",
        set_accessor_must_have_one_and_only_one_parameter: "'set' accessor must have one and only one parameter.",
        set_accessor_parameter_cannot_be_optional: "'set' accessor parameter cannot be optional.",
        set_accessor_parameter_cannot_have_an_initializer: "'set' accessor parameter cannot have an initializer.",
        set_accessor_cannot_have_rest_parameter: "'set' accessor cannot have rest parameter.",
        get_accessor_cannot_have_parameters: "'get' accessor cannot have parameters.",
        Modifiers_cannot_appear_here: "Modifiers cannot appear here.",
        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: "Accessors are only available when targeting ECMAScript 5 and higher.",
        Class_name_cannot_be_0: "Class name cannot be '{0}'.",
        Interface_name_cannot_be_0: "Interface name cannot be '{0}'.",
        Enum_name_cannot_be_0: "Enum name cannot be '{0}'.",
        Module_name_cannot_be_0: "Module name cannot be '{0}'.",
        Enum_member_must_have_initializer: "Enum member must have initializer.",
        Export_assignment_cannot_be_used_in_internal_modules: "Export assignment cannot be used in internal modules.",
        Export_assignment_not_allowed_in_module_with_exported_element: "Export assignment not allowed in module with exported element.",
        Module_cannot_have_multiple_export_assignments: "Module cannot have multiple export assignments.",
        Ambient_enum_elements_can_only_have_integer_literal_initializers: "Ambient enum elements can only have integer literal initializers.",
        module_class_interface_enum_import_or_statement: "module, class, interface, enum, import or statement",
        constructor_function_accessor_or_variable: "constructor, function, accessor or variable",
        statement: "statement",
        case_or_default_clause: "case or default clause",
        identifier: "identifier",
        call_construct_index_property_or_function_signature: "call, construct, index, property or function signature",
        expression: "expression",
        type_name: "type name",
        property_or_accessor: "property or accessor",
        parameter: "parameter",
        type: "type",
        type_parameter: "type parameter",
        declare_modifier_not_allowed_on_import_declaration: "'declare' modifier not allowed on import declaration.",
        Function_overload_must_be_static: "Function overload must be static.",
        Function_overload_must_not_be_static: "Function overload must not be static.",
        Parameter_property_declarations_cannot_be_used_in_a_constructor_overload: "Parameter property declarations cannot be used in a constructor overload.",
        Invalid_reference_directive_syntax: "Invalid 'reference' directive syntax.",
        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher: "Octal literals are not available when targeting ECMAScript 5 and higher.",
        Accessors_are_not_allowed_in_ambient_contexts: "Accessors are not allowed in ambient contexts.",
        _0_modifier_cannot_appear_on_a_constructor_declaration: "'{0}' modifier cannot appear on a constructor declaration.",
        _0_modifier_cannot_appear_on_a_parameter: "'{0}' modifier cannot appear on a parameter.",
        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: "Only a single variable declaration is allowed in a 'for...in' statement.",
        Type_parameters_cannot_appear_on_a_constructor_declaration: "Type parameters cannot appear on a constructor declaration.",
        Type_annotation_cannot_appear_on_a_constructor_declaration: "Type annotation cannot appear on a constructor declaration.",
        Duplicate_identifier_0: "Duplicate identifier '{0}'.",
        The_name_0_does_not_exist_in_the_current_scope: "The name '{0}' does not exist in the current scope.",
        The_name_0_does_not_refer_to_a_value: "The name '{0}' does not refer to a value.",
        super_can_only_be_used_inside_a_class_instance_method: "'super' can only be used inside a class instance method.",
        The_left_hand_side_of_an_assignment_expression_must_be_a_variable_property_or_indexer: "The left-hand side of an assignment expression must be a variable, property or indexer.",
        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: "Value of type '{0}' is not callable. Did you mean to include 'new'?",
        Value_of_type_0_is_not_callable: "Value of type '{0}' is not callable.",
        Value_of_type_0_is_not_newable: "Value of type '{0}' is not newable.",
        Value_of_type_0_is_not_indexable_by_type_1: "Value of type '{0}' is not indexable by type '{1}'.",
        Operator_0_cannot_be_applied_to_types_1_and_2: "Operator '{0}' cannot be applied to types '{1}' and '{2}'.",
        Operator_0_cannot_be_applied_to_types_1_and_2_3: "Operator '{0}' cannot be applied to types '{1}' and '{2}': {3}",
        Cannot_convert_0_to_1: "Cannot convert '{0}' to '{1}'.",
        Cannot_convert_0_to_1_NL_2: "Cannot convert '{0}' to '{1}':{NL}{2}",
        Expected_var_class_interface_or_module: "Expected var, class, interface, or module.",
        Operator_0_cannot_be_applied_to_type_1: "Operator '{0}' cannot be applied to type '{1}'.",
        Getter_0_already_declared: "Getter '{0}' already declared.",
        Setter_0_already_declared: "Setter '{0}' already declared.",
        Exported_class_0_extends_private_class_1: "Exported class '{0}' extends private class '{1}'.",
        Exported_class_0_implements_private_interface_1: "Exported class '{0}' implements private interface '{1}'.",
        Exported_interface_0_extends_private_interface_1: "Exported interface '{0}' extends private interface '{1}'.",
        Exported_class_0_extends_class_from_inaccessible_module_1: "Exported class '{0}' extends class from inaccessible module {1}.",
        Exported_class_0_implements_interface_from_inaccessible_module_1: "Exported class '{0}' implements interface from inaccessible module {1}.",
        Exported_interface_0_extends_interface_from_inaccessible_module_1: "Exported interface '{0}' extends interface from inaccessible module {1}.",
        Public_static_property_0_of_exported_class_has_or_is_using_private_type_1: "Public static property '{0}' of exported class has or is using private type '{1}'.",
        Public_property_0_of_exported_class_has_or_is_using_private_type_1: "Public property '{0}' of exported class has or is using private type '{1}'.",
        Property_0_of_exported_interface_has_or_is_using_private_type_1: "Property '{0}' of exported interface has or is using private type '{1}'.",
        Exported_variable_0_has_or_is_using_private_type_1: "Exported variable '{0}' has or is using private type '{1}'.",
        Public_static_property_0_of_exported_class_is_using_inaccessible_module_1: "Public static property '{0}' of exported class is using inaccessible module {1}.",
        Public_property_0_of_exported_class_is_using_inaccessible_module_1: "Public property '{0}' of exported class is using inaccessible module {1}.",
        Property_0_of_exported_interface_is_using_inaccessible_module_1: "Property '{0}' of exported interface is using inaccessible module {1}.",
        Exported_variable_0_is_using_inaccessible_module_1: "Exported variable '{0}' is using inaccessible module {1}.",
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_type_1: "Parameter '{0}' of constructor from exported class has or is using private type '{1}'.",
        Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_type_1: "Parameter '{0}' of public static property setter from exported class has or is using private type '{1}'.",
        Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_type_1: "Parameter '{0}' of public property setter from exported class has or is using private type '{1}'.",
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_type_1: "Parameter '{0}' of constructor signature from exported interface has or is using private type '{1}'.",
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_type_1: "Parameter '{0}' of call signature from exported interface has or is using private type '{1}'.",
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_type_1: "Parameter '{0}' of public static method from exported class has or is using private type '{1}'.",
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_type_1: "Parameter '{0}' of public method from exported class has or is using private type '{1}'.",
        Parameter_0_of_method_from_exported_interface_has_or_is_using_private_type_1: "Parameter '{0}' of method from exported interface has or is using private type '{1}'.",
        Parameter_0_of_exported_function_has_or_is_using_private_type_1: "Parameter '{0}' of exported function has or is using private type '{1}'.",
        Parameter_0_of_constructor_from_exported_class_is_using_inaccessible_module_1: "Parameter '{0}' of constructor from exported class is using inaccessible module {1}.",
        Parameter_0_of_public_static_property_setter_from_exported_class_is_using_inaccessible_module_1: "Parameter '{0}' of public static property setter from exported class is using inaccessible module {1}.",
        Parameter_0_of_public_property_setter_from_exported_class_is_using_inaccessible_module_1: "Parameter '{0}' of public property setter from exported class is using inaccessible module {1}.",
        Parameter_0_of_constructor_signature_from_exported_interface_is_using_inaccessible_module_1: "Parameter '{0}' of constructor signature from exported interface is using inaccessible module {1}.",
        Parameter_0_of_call_signature_from_exported_interface_is_using_inaccessible_module_1: "Parameter '{0}' of call signature from exported interface is using inaccessible module {1}",
        Parameter_0_of_public_static_method_from_exported_class_is_using_inaccessible_module_1: "Parameter '{0}' of public static method from exported class is using inaccessible module {1}.",
        Parameter_0_of_public_method_from_exported_class_is_using_inaccessible_module_1: "Parameter '{0}' of public method from exported class is using inaccessible module {1}.",
        Parameter_0_of_method_from_exported_interface_is_using_inaccessible_module_1: "Parameter '{0}' of method from exported interface is using inaccessible module {1}.",
        Parameter_0_of_exported_function_is_using_inaccessible_module_1: "Parameter '{0}' of exported function is using inaccessible module {1}.",
        Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_type_0: "Return type of public static property getter from exported class has or is using private type '{0}'.",
        Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_type_0: "Return type of public property getter from exported class has or is using private type '{0}'.",
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_type_0: "Return type of constructor signature from exported interface has or is using private type '{0}'.",
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_type_0: "Return type of call signature from exported interface has or is using private type '{0}'.",
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_type_0: "Return type of index signature from exported interface has or is using private type '{0}'.",
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_type_0: "Return type of public static method from exported class has or is using private type '{0}'.",
        Return_type_of_public_method_from_exported_class_has_or_is_using_private_type_0: "Return type of public method from exported class has or is using private type '{0}'.",
        Return_type_of_method_from_exported_interface_has_or_is_using_private_type_0: "Return type of method from exported interface has or is using private type '{0}'.",
        Return_type_of_exported_function_has_or_is_using_private_type_0: "Return type of exported function has or is using private type '{0}'.",
        Return_type_of_public_static_property_getter_from_exported_class_is_using_inaccessible_module_0: "Return type of public static property getter from exported class is using inaccessible module {0}.",
        Return_type_of_public_property_getter_from_exported_class_is_using_inaccessible_module_0: "Return type of public property getter from exported class is using inaccessible module {0}.",
        Return_type_of_constructor_signature_from_exported_interface_is_using_inaccessible_module_0: "Return type of constructor signature from exported interface is using inaccessible module {0}.",
        Return_type_of_call_signature_from_exported_interface_is_using_inaccessible_module_0: "Return type of call signature from exported interface is using inaccessible module {0}.",
        Return_type_of_index_signature_from_exported_interface_is_using_inaccessible_module_0: "Return type of index signature from exported interface is using inaccessible module {0}.",
        Return_type_of_public_static_method_from_exported_class_is_using_inaccessible_module_0: "Return type of public static method from exported class is using inaccessible module {0}.",
        Return_type_of_public_method_from_exported_class_is_using_inaccessible_module_0: "Return type of public method from exported class is using inaccessible module {0}.",
        Return_type_of_method_from_exported_interface_is_using_inaccessible_module_0: "Return type of method from exported interface is using inaccessible module {0}.",
        Return_type_of_exported_function_is_using_inaccessible_module_0: "Return type of exported function is using inaccessible module {0}.",
        new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead.",
        A_parameter_list_must_follow_a_generic_type_argument_list_expected: "A parameter list must follow a generic type argument list. '(' expected.",
        Multiple_constructor_implementations_are_not_allowed: "Multiple constructor implementations are not allowed.",
        Unable_to_resolve_external_module_0: "Unable to resolve external module '{0}'.",
        Module_cannot_be_aliased_to_a_non_module_type: "Module cannot be aliased to a non-module type.",
        A_class_may_only_extend_another_class: "A class may only extend another class.",
        A_class_may_only_implement_another_class_or_interface: "A class may only implement another class or interface.",
        An_interface_may_only_extend_another_class_or_interface: "An interface may only extend another class or interface.",
        Unable_to_resolve_type: "Unable to resolve type.",
        Unable_to_resolve_type_of_0: "Unable to resolve type of '{0}'.",
        Unable_to_resolve_type_parameter_constraint: "Unable to resolve type parameter constraint.",
        Type_parameter_constraint_cannot_be_a_primitive_type: "Type parameter constraint cannot be a primitive type.",
        Supplied_parameters_do_not_match_any_signature_of_call_target: "Supplied parameters do not match any signature of call target.",
        Supplied_parameters_do_not_match_any_signature_of_call_target_NL_0: "Supplied parameters do not match any signature of call target:{NL}{0}",
        Invalid_new_expression: "Invalid 'new' expression.",
        Call_signatures_used_in_a_new_expression_must_have_a_void_return_type: "Call signatures used in a 'new' expression must have a 'void' return type.",
        Could_not_select_overload_for_new_expression: "Could not select overload for 'new' expression.",
        Type_0_does_not_satisfy_the_constraint_1_for_type_parameter_2: "Type '{0}' does not satisfy the constraint '{1}' for type parameter '{2}'.",
        Could_not_select_overload_for_call_expression: "Could not select overload for 'call' expression.",
        Cannot_invoke_an_expression_whose_type_lacks_a_call_signature: "Cannot invoke an expression whose type lacks a call signature.",
        Calls_to_super_are_only_valid_inside_a_class: "Calls to 'super' are only valid inside a class.",
        Generic_type_0_requires_1_type_argument_s: "Generic type '{0}' requires {1} type argument(s).",
        Type_of_array_literal_cannot_be_determined_Best_common_type_could_not_be_found_for_array_elements: "Type of array literal cannot be determined. Best common type could not be found for array elements.",
        Could_not_find_enclosing_symbol_for_dotted_name_0: "Could not find enclosing symbol for dotted name '{0}'.",
        The_property_0_does_not_exist_on_value_of_type_1: "The property '{0}' does not exist on value of type '{1}'.",
        Could_not_find_symbol_0: "Could not find symbol '{0}'.",
        get_and_set_accessor_must_have_the_same_type: "'get' and 'set' accessor must have the same type.",
        this_cannot_be_referenced_in_current_location: "'this' cannot be referenced in current location.",
        Static_members_cannot_reference_class_type_parameters: "Static members cannot reference class type parameters.",
        Class_0_is_recursively_referenced_as_a_base_type_of_itself: "Class '{0}' is recursively referenced as a base type of itself.",
        Interface_0_is_recursively_referenced_as_a_base_type_of_itself: "Interface '{0}' is recursively referenced as a base type of itself.",
        super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.",
        super_cannot_be_referenced_in_non_derived_classes: "'super' cannot be referenced in non-derived classes.",
        A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: "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: "Constructors for derived classes must contain a 'super' call.",
        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: "Super calls are not permitted outside constructors or in nested functions inside constructors.",
        _0_1_is_inaccessible: "'{0}.{1}' is inaccessible.",
        this_cannot_be_referenced_within_module_bodies: "'this' cannot be referenced within module bodies.",
        Invalid_expression_types_not_known_to_support_the_addition_operator: "Invalid '+' expression - types not known to support the addition operator.",
        The_right_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.",
        The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.",
        The_type_of_a_unary_arithmetic_operation_operand_must_be_of_type_any_number_or_an_enum_type: "The type of a unary arithmetic operation operand must be of type 'any', 'number' or an enum type.",
        Variable_declarations_of_a_for_statement_cannot_use_a_type_annotation: "Variable declarations of a 'for' statement cannot use a type annotation.",
        Variable_declarations_of_a_for_statement_must_be_of_types_string_or_any: "Variable declarations of a 'for' statement must be of types 'string' or 'any'.",
        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.",
        The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.",
        The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: "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_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: "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: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type.",
        Setters_cannot_return_a_value: "Setters cannot return a value.",
        Tried_to_query_type_of_uninitialized_module_0: "Tried to query type of uninitialized module '{0}'.",
        Tried_to_set_variable_type_to_uninitialized_module_type_0: "Tried to set variable type to uninitialized module type '{0}'.",
        Type_0_does_not_have_type_parameters: "Type '{0}' does not have type parameters.",
        Getters_must_return_a_value: "Getters must return a value.",
        Getter_and_setter_accessors_do_not_agree_in_visibility: "Getter and setter accessors do not agree in visibility.",
        Invalid_left_hand_side_of_assignment_expression: "Invalid left-hand side of assignment expression.",
        Function_declared_a_non_void_return_type_but_has_no_return_expression: "Function declared a non-void return type, but has no return expression.",
        Cannot_resolve_return_type_reference: "Cannot resolve return type reference.",
        Constructors_cannot_have_a_return_type_of_void: "Constructors cannot have a return type of 'void'.",
        Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'.",
        All_symbols_within_a_with_block_will_be_resolved_to_any: "All symbols within a with block will be resolved to 'any'.",
        Import_declarations_in_an_internal_module_cannot_reference_an_external_module: "Import declarations in an internal module cannot reference an external module.",
        Class_0_declares_interface_1_but_does_not_implement_it_NL_2: "Class {0} declares interface {1} but does not implement it:{NL}{2}",
        Class_0_declares_class_1_as_an_interface_but_does_not_implement_it_NL_2: "Class {0} declares class {1} as an interface but does not implement it:{NL}{2}",
        The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer: "The operand of an increment or decrement operator must be a variable, property or indexer.",
        this_cannot_be_referenced_in_static_initializers_in_a_class_body: "'this' cannot be referenced in static initializers in a class body.",
        Class_0_cannot_extend_class_1_NL_2: "Class '{0}' cannot extend class '{1}':{NL}{2}",
        Interface_0_cannot_extend_class_1_NL_2: "Interface '{0}' cannot extend class '{1}':{NL}{2}",
        Interface_0_cannot_extend_interface_1_NL_2: "Interface '{0}' cannot extend interface '{1}':{NL}{2}",
        Duplicate_overload_signature_for_0: "Duplicate overload signature for '{0}'.",
        Duplicate_constructor_overload_signature: "Duplicate constructor overload signature.",
        Duplicate_overload_call_signature: "Duplicate overload call signature.",
        Duplicate_overload_construct_signature: "Duplicate overload construct signature.",
        Overload_signature_is_not_compatible_with_function_definition: "Overload signature is not compatible with function definition.",
        Overload_signature_is_not_compatible_with_function_definition_NL_0: "Overload signature is not compatible with function definition:{NL}{0}",
        Overload_signatures_must_all_be_public_or_private: "Overload signatures must all be public or private.",
        Overload_signatures_must_all_be_exported_or_not_exported: "Overload signatures must all be exported or not exported.",
        Overload_signatures_must_all_be_ambient_or_non_ambient: "Overload signatures must all be ambient or non-ambient.",
        Overload_signatures_must_all_be_optional_or_required: "Overload signatures must all be optional or required.",
        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: "Specialized overload signature is not assignable to any non-specialized signature.",
        this_cannot_be_referenced_in_constructor_arguments: "'this' cannot be referenced in constructor arguments.",
        Instance_member_cannot_be_accessed_off_a_class: "Instance member cannot be accessed off a class.",
        Untyped_function_calls_may_not_accept_type_arguments: "Untyped function calls may not accept type arguments.",
        Non_generic_functions_may_not_accept_type_arguments: "Non-generic functions may not accept type arguments.",
        A_generic_type_may_not_reference_itself_with_a_wrapped_form_of_its_own_type_parameters: "A generic type may not reference itself with a wrapped form of its own type parameters.",
        Rest_parameters_must_be_array_types: "Rest parameters must be array types.",
        Overload_signature_implementation_cannot_use_specialized_type: "Overload signature implementation cannot use specialized type.",
        Export_assignments_may_only_be_used_at_the_top_level_of_external_modules: "Export assignments may only be used at the top-level of external modules.",
        Export_assignments_may_only_be_made_with_variables_functions_classes_interfaces_enums_and_internal_modules: "Export assignments may only be made with variables, functions, classes, interfaces, enums and internal modules.",
        Only_public_methods_of_the_base_class_are_accessible_via_the_super_keyword: "Only public methods of the base class are accessible via the 'super' keyword.",
        Numeric_indexer_type_0_must_be_assignable_to_string_indexer_type_1: "Numeric indexer type '{0}' must be assignable to string indexer type '{1}'.",
        Numeric_indexer_type_0_must_be_assignable_to_string_indexer_type_1_NL_2: "Numeric indexer type '{0}' must be assignable to string indexer type '{1}':{NL}{2}",
        All_numerically_named_properties_must_be_assignable_to_numeric_indexer_type_0: "All numerically named properties must be assignable to numeric indexer type '{0}'.",
        All_numerically_named_properties_must_be_assignable_to_numeric_indexer_type_0_NL_1: "All numerically named properties must be assignable to numeric indexer type '{0}':{NL}{1}",
        All_named_properties_must_be_assignable_to_string_indexer_type_0: "All named properties must be assignable to string indexer type '{0}'.",
        All_named_properties_must_be_assignable_to_string_indexer_type_0_NL_1: "All named properties must be assignable to string indexer type '{0}':{NL}{1}",
        Generic_type_references_must_include_all_type_arguments: "Generic type references must include all type arguments.",
        Default_arguments_are_only_allowed_in_implementation: "Default arguments are only allowed in implementation.",
        Overloads_cannot_differ_only_by_return_type: "Overloads cannot differ only by return type.",
        Function_expression_declared_a_non_void_return_type_but_has_no_return_expression: "Function expression declared a non-void return type, but has no return expression.",
        Import_declaration_referencing_identifier_from_internal_module_can_only_be_made_with_variables_functions_classes_interfaces_enums_and_internal_modules: "Import declaration referencing identifier from internal module can only be made with variables, functions, classes, interfaces, enums and internal modules.",
        Could_not_find_symbol_0_in_module_1: "Could not find symbol '{0}' in module '{1}'.",
        Unable_to_resolve_module_reference_0: "Unable to resolve module reference '{0}'.",
        Could_not_find_module_0_in_module_1: "Could not find module '{0}' in module '{1}'.",
        Exported_import_declaration_0_is_assigned_value_with_type_that_has_or_is_using_private_type_1: "Exported import declaration '{0}' is assigned value with type that has or is using private type '{1}'.",
        Exported_import_declaration_0_is_assigned_value_with_type_that_is_using_inaccessible_module_1: "Exported import declaration '{0}' is assigned value with type that is using inaccessible module '{1}'.",
        Exported_import_declaration_0_is_assigned_type_that_has_or_is_using_private_type_1: "Exported import declaration '{0}' is assigned type that has or is using private type '{1}'.",
        Exported_import_declaration_0_is_assigned_type_that_is_using_inaccessible_module_1: "Exported import declaration '{0}' is assigned type that is using inaccessible module '{1}'.",
        Exported_import_declaration_0_is_assigned_container_that_is_or_is_using_inaccessible_module_1: "Exported import declaration '{0}' is assigned container that is or is using inaccessible module '{1}'.",
        Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_1: "Type name '{0}' in extends clause does not reference constructor function for '{1}'.",
        Internal_module_reference_0_in_import_declaration_does_not_reference_module_instance_for_1: "Internal module reference '{0}' in import declaration does not reference module instance for '{1}'.",
        Module_0_cannot_merge_with_previous_declaration_of_1_in_a_different_file_2: "Module '{0}' cannot merge with previous declaration of '{1}' in a different file '{2}'.",
        Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}':{NL}{3}",
        Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it.",
        Ambient_external_module_declaration_cannot_be_reopened: "Ambient external module declaration cannot be reopened.",
        All_declarations_of_merged_declaration_0_must_be_exported_or_not_exported: "All declarations of merged declaration '{0}' must be exported or not exported.",
        super_cannot_be_referenced_in_constructor_arguments: "'super' cannot be referenced in constructor arguments.",
        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: "Return type of constructor signature must be assignable to the instance type of the class.",
        Ambient_external_module_declaration_must_be_defined_in_global_context: "Ambient external module declaration must be defined in global context.",
        Ambient_external_module_declaration_cannot_specify_relative_module_name: "Ambient external module declaration cannot specify relative module name.",
        Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name: "Import declaration in an ambient external module declaration cannot reference external module through relative external module name.",
        Could_not_find_the_best_common_type_of_types_of_all_return_statement_expressions: "Could not find the best common type of types of all return statement expressions.",
        Import_declaration_cannot_refer_to_external_module_reference_when_noResolve_option_is_set: "Import declaration cannot refer to external module reference when --noResolve option is set.",
        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference.",
        continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: "'continue' statement can only be used within an enclosing iteration statement.",
        break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: "'break' statement can only be used within an enclosing iteration or switch statement.",
        Jump_target_not_found: "Jump target not found.",
        Jump_target_cannot_cross_function_boundary: "Jump target cannot cross function boundary.",
        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference.",
        Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference.",
        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: "Expression resolves to '_super' that compiler uses to capture base class reference.",
        TypeParameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_type_1: "TypeParameter '{0}' of constructor signature from exported interface has or is using private type '{1}'.",
        TypeParameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_type_1: "TypeParameter '{0}' of call signature from exported interface has or is using private type '{1}'.",
        TypeParameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_type_1: "TypeParameter '{0}' of public static method from exported class has or is using private type '{1}'.",
        TypeParameter_0_of_public_method_from_exported_class_has_or_is_using_private_type_1: "TypeParameter '{0}' of public method from exported class has or is using private type '{1}'.",
        TypeParameter_0_of_method_from_exported_interface_has_or_is_using_private_type_1: "TypeParameter '{0}' of method from exported interface has or is using private type '{1}'.",
        TypeParameter_0_of_exported_function_has_or_is_using_private_type_1: "TypeParameter '{0}' of exported function has or is using private type '{1}'.",
        TypeParameter_0_of_constructor_signature_from_exported_interface_is_using_inaccessible_module_1: "TypeParameter '{0}' of constructor signature from exported interface is using inaccessible module {1}.",
        TypeParameter_0_of_call_signature_from_exported_interface_is_using_inaccessible_module_1: "TypeParameter '{0}' of call signature from exported interface is using inaccessible module {1}",
        TypeParameter_0_of_public_static_method_from_exported_class_is_using_inaccessible_module_1: "TypeParameter '{0}' of public static method from exported class is using inaccessible module {1}.",
        TypeParameter_0_of_public_method_from_exported_class_is_using_inaccessible_module_1: "TypeParameter '{0}' of public method from exported class is using inaccessible module {1}.",
        TypeParameter_0_of_method_from_exported_interface_is_using_inaccessible_module_1: "TypeParameter '{0}' of method from exported interface is using inaccessible module {1}.",
        TypeParameter_0_of_exported_function_is_using_inaccessible_module_1: "TypeParameter '{0}' of exported function is using inaccessible module {1}.",
        TypeParameter_0_of_exported_class_has_or_is_using_private_type_1: "TypeParameter '{0}' of exported class has or is using private type '{1}'.",
        TypeParameter_0_of_exported_interface_has_or_is_using_private_type_1: "TypeParameter '{0}' of exported interface has or is using private type '{1}'.",
        TypeParameter_0_of_exported_class_is_using_inaccessible_module_1: "TypeParameter '{0}' of exported class is using inaccessible module {1}.",
        TypeParameter_0_of_exported_interface_is_using_inaccessible_module_1: "TypeParameter '{0}' of exported interface is using inaccessible module {1}.",
        Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter: "Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter.",
        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters.",
        Type_of_conditional_0_must_be_identical_to_1_or_2: "Type of conditional '{0}' must be identical to '{1}' or '{2}'.",
        Type_of_conditional_0_must_be_identical_to_1_2_or_3: "Type of conditional '{0}' must be identical to '{1}', '{2}' or '{3}'.",
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of an external module.",
        Constraint_of_a_type_parameter_cannot_reference_any_type_parameter_from_the_same_type_parameter_list: "Constraint of a type parameter cannot reference any type parameter from the same type parameter list.",
        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.",
        Parameter_0_cannot_be_referenced_in_its_initializer: "Parameter '{0}' cannot be referenced in its initializer.",
        Duplicate_string_index_signature: "Duplicate string index signature.",
        Duplicate_number_index_signature: "Duplicate number index signature.",
        All_declarations_of_an_interface_must_have_identical_type_parameters: "All declarations of an interface must have identical type parameters.",
        Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter: "Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter.",
        Type_0_is_missing_property_1_from_type_2: "Type '{0}' is missing property '{1}' from type '{2}'.",
        Types_of_property_0_of_types_1_and_2_are_incompatible: "Types of property '{0}' of types '{1}' and '{2}' are incompatible.",
        Types_of_property_0_of_types_1_and_2_are_incompatible_NL_3: "Types of property '{0}' of types '{1}' and '{2}' are incompatible:{NL}{3}",
        Property_0_defined_as_private_in_type_1_is_defined_as_public_in_type_2: "Property '{0}' defined as private in type '{1}' is defined as public in type '{2}'.",
        Property_0_defined_as_public_in_type_1_is_defined_as_private_in_type_2: "Property '{0}' defined as public in type '{1}' is defined as private in type '{2}'.",
        Types_0_and_1_define_property_2_as_private: "Types '{0}' and '{1}' define property '{2}' as private.",
        Call_signatures_of_types_0_and_1_are_incompatible: "Call signatures of types '{0}' and '{1}' are incompatible.",
        Call_signatures_of_types_0_and_1_are_incompatible_NL_2: "Call signatures of types '{0}' and '{1}' are incompatible:{NL}{2}",
        Type_0_requires_a_call_signature_but_type_1_lacks_one: "Type '{0}' requires a call signature, but type '{1}' lacks one.",
        Construct_signatures_of_types_0_and_1_are_incompatible: "Construct signatures of types '{0}' and '{1}' are incompatible.",
        Construct_signatures_of_types_0_and_1_are_incompatible_NL_2: "Construct signatures of types '{0}' and '{1}' are incompatible:{NL}{2}",
        Type_0_requires_a_construct_signature_but_type_1_lacks_one: "Type '{0}' requires a construct signature, but type '{1}' lacks one.",
        Index_signatures_of_types_0_and_1_are_incompatible: "Index signatures of types '{0}' and '{1}' are incompatible.",
        Index_signatures_of_types_0_and_1_are_incompatible_NL_2: "Index signatures of types '{0}' and '{1}' are incompatible:{NL}{2}",
        Call_signature_expects_0_or_fewer_parameters: "Call signature expects {0} or fewer parameters.",
        Could_not_apply_type_0_to_argument_1_which_is_of_type_2: "Could not apply type '{0}' to argument {1} which is of type '{2}'.",
        Class_0_defines_instance_member_accessor_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.",
        Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function.",
        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 accessor.",
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property.",
        Types_of_static_property_0_of_class_1_and_class_2_are_incompatible: "Types of static property '{0}' of class '{1}' and class '{2}' are incompatible.",
        Types_of_static_property_0_of_class_1_and_class_2_are_incompatible_NL_3: "Types of static property '{0}' of class '{1}' and class '{2}' are incompatible:{NL}{3}",
        Type_reference_cannot_refer_to_container_0: "Type reference cannot refer to container '{0}'.",
        Type_reference_must_refer_to_type: "Type reference must refer to type.",
        In_enums_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_the_first_enum_element: "In enums with multiple declarations only one declaration can omit an initializer for the first enum element.",
        _0_overload_s: " (+ {0} overload(s))",
        Variable_declaration_cannot_have_the_same_name_as_an_import_declaration: "Variable declaration cannot have the same name as an import declaration.",
        Signature_expected_0_type_arguments_got_1_instead: "Signature expected {0} type arguments, got {1} instead.",
        Property_0_defined_as_optional_in_type_1_but_is_required_in_type_2: "Property '{0}' defined as optional in type '{1}', but is required in type '{2}'.",
        Types_0_and_1_originating_in_infinitely_expanding_type_reference_do_not_refer_to_same_named_type: "Types '{0}' and '{1}' originating in infinitely expanding type reference do not refer to same named type.",
        Types_0_and_1_originating_in_infinitely_expanding_type_reference_have_incompatible_type_arguments: "Types '{0}' and '{1}' originating in infinitely expanding type reference have incompatible type arguments.",
        Types_0_and_1_originating_in_infinitely_expanding_type_reference_have_incompatible_type_arguments_NL_2: "Types '{0}' and '{1}' originating in infinitely expanding type reference have incompatible type arguments:{NL}{2}",
        Named_properties_0_of_types_1_and_2_are_not_identical: "Named properties '{0}' of types '{1}' and '{2}' are not identical.",
        Types_of_string_indexer_of_types_0_and_1_are_not_identical: "Types of string indexer of types '{0}' and '{1}' are not identical.",
        Types_of_number_indexer_of_types_0_and_1_are_not_identical: "Types of number indexer of types '{0}' and '{1}' are not identical.",
        Type_of_number_indexer_in_type_0_is_not_assignable_to_string_indexer_type_in_type_1_NL_2: "Type of number indexer in type '{0}' is not assignable to string indexer type in type '{1}'.{NL}{2}",
        Type_of_property_0_in_type_1_is_not_assignable_to_string_indexer_type_in_type_2_NL_3: "Type of property '{0}' in type '{1}' is not assignable to string indexer type in type '{2}'.{NL}{3}",
        Type_of_property_0_in_type_1_is_not_assignable_to_number_indexer_type_in_type_2_NL_3: "Type of property '{0}' in type '{1}' is not assignable to number indexer type in type '{2}'.{NL}{3}",
        Static_property_0_defined_as_private_in_type_1_is_defined_as_public_in_type_2: "Static property '{0}' defined as private in type '{1}' is defined as public in type '{2}'.",
        Static_property_0_defined_as_public_in_type_1_is_defined_as_private_in_type_2: "Static property '{0}' defined as public in type '{1}' is defined as private in type '{2}'.",
        Types_0_and_1_define_static_property_2_as_private: "Types '{0}' and '{1}' define static property '{2}' as private.",
        Current_host_does_not_support_0_option: "Current host does not support '{0}' option.",
        ECMAScript_target_version_0_not_supported_Specify_a_valid_target_version_1_default_or_2: "ECMAScript target version '{0}' not supported.  Specify a valid target version: '{1}' (default), or '{2}'",
        Module_code_generation_0_not_supported: "Module code generation '{0}' not supported.",
        Could_not_find_file_0: "Could not find file: '{0}'.",
        A_file_cannot_have_a_reference_to_itself: "A file cannot have a reference to itself.",
        Cannot_resolve_referenced_file_0: "Cannot resolve referenced file: '{0}'.",
        Cannot_find_the_common_subdirectory_path_for_the_input_files: "Cannot find the common subdirectory path for the input files.",
        Emit_Error_0: "Emit Error: {0}.",
        Cannot_read_file_0_1: "Cannot read file '{0}': {1}",
        Unsupported_file_encoding: "Unsupported file encoding.",
        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'.",
        Unsupported_locale_0: "Unsupported locale: '{0}'.",
        Execution_Failed_NL: "Execution Failed.{NL}",
        Invalid_call_to_up: "Invalid call to 'up'",
        Invalid_call_to_down: "Invalid call to 'down'",
        Base64_value_0_finished_with_a_continuation_bit: "Base64 value '{0}' finished with a continuation bit.",
        Unknown_option_0: "Unknown option '{0}'",
        Expected_0_arguments_to_message_got_1_instead: "Expected {0} arguments to message, got {1} instead.",
        Expected_the_message_0_to_have_1_arguments_but_it_had_2: "Expected the message '{0}' to have {1} arguments, but it had {2}",
        Could_not_delete_file_0: "Could not delete file '{0}'",
        Could_not_create_directory_0: "Could not create directory '{0}'",
        Error_while_executing_file_0: "Error while executing file '{0}': ",
        Cannot_compile_external_modules_unless_the_module_flag_is_provided: "Cannot compile external modules unless the '--module' flag is provided.",
        Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: "Option mapRoot cannot be specified without specifying sourcemap option.",
        Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: "Option sourceRoot cannot be specified without specifying sourcemap option.",
        Options_mapRoot_and_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: "Options mapRoot and sourceRoot cannot be specified without specifying sourcemap option.",
        Option_0_specified_without_1: "Option '{0}' specified without '{1}'",
        codepage_option_not_supported_on_current_platform: "'codepage' option not supported on current platform.",
        Concatenate_and_emit_output_to_single_file: "Concatenate and emit output to single file.",
        Generates_corresponding_0_file: "Generates corresponding {0} file.",
        Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: "Specifies the location where debugger should locate map files instead of generated locations.",
        Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: "Specifies the location where debugger should locate TypeScript files instead of source locations.",
        Watch_input_files: "Watch input files.",
        Redirect_output_structure_to_the_directory: "Redirect output structure to the directory.",
        Do_not_emit_comments_to_output: "Do not emit comments to output.",
        Skip_resolution_and_preprocessing: "Skip resolution and preprocessing.",
        Specify_ECMAScript_target_version_0_default_or_1: "Specify ECMAScript target version: '{0}' (default), or '{1}'",
        Specify_module_code_generation_0_or_1: "Specify module code generation: '{0}' or '{1}'",
        Print_this_message: "Print this message.",
        Print_the_compiler_s_version_0: "Print the compiler's version: {0}",
        Allow_use_of_deprecated_0_keyword_when_referencing_an_external_module: "Allow use of deprecated '{0}' keyword when referencing an external module.",
        Specify_locale_for_errors_and_messages_For_example_0_or_1: "Specify locale for errors and messages. For example '{0}' or '{1}'",
        Syntax_0: "Syntax:   {0}",
        options: "options",
        file1: "file",
        Examples: "Examples:",
        Options: "Options:",
        Insert_command_line_options_and_files_from_a_file: "Insert command line options and files from a file.",
        Version_0: "Version {0}",
        Use_the_0_flag_to_see_options: "Use the '{0}' flag to see options.",
        NL_Recompiling_0: "{NL}Recompiling ({0}):",
        STRING: "STRING",
        KIND: "KIND",
        file2: "FILE",
        VERSION: "VERSION",
        LOCATION: "LOCATION",
        DIRECTORY: "DIRECTORY",
        NUMBER: "NUMBER",
        Specify_the_codepage_to_use_when_opening_source_files: "Specify the codepage to use when opening source files.",
        Additional_locations: "Additional locations:",
        This_version_of_the_Javascript_runtime_does_not_support_the_0_function: "This version of the Javascript runtime does not support the '{0}' function.",
        Unknown_rule: "Unknown rule.",
        Invalid_line_number_0: "Invalid line number ({0})",
        Warn_on_expressions_and_declarations_with_an_implied_any_type: "Warn on expressions and declarations with an implied 'any' type.",
        Variable_0_implicitly_has_an_any_type: "Variable '{0}' implicitly has an 'any' type.",
        Parameter_0_of_1_implicitly_has_an_any_type: "Parameter '{0}' of '{1}' implicitly has an 'any' type.",
        Parameter_0_of_function_type_implicitly_has_an_any_type: "Parameter '{0}' of function type implicitly has an 'any' type.",
        Member_0_of_object_type_implicitly_has_an_any_type: "Member '{0}' of object type implicitly has an 'any' type.",
        new_expression_which_lacks_a_constructor_signature_implicitly_has_an_any_type: "'new' expression, which lacks a constructor signature, implicitly has an 'any' type.",
        _0_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: "'{0}', which lacks return-type annotation, implicitly has an 'any' return type.",
        Function_expression_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: "Function expression, which lacks return-type annotation, implicitly has an 'any' return type.",
        Parameter_0_of_lambda_function_implicitly_has_an_any_type: "Parameter '{0}' of lambda function implicitly has an 'any' type.",
        Constructor_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: "Constructor signature, which lacks return-type annotation, implicitly has an 'any' return type.",
        Lambda_Function_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: "Lambda Function, which lacks return-type annotation, implicitly has an 'any' return type.",
        Array_Literal_implicitly_has_an_any_type_from_widening: "Array Literal implicitly has an 'any' type from widening.",
        _0_which_lacks_get_accessor_and_parameter_type_annotation_on_set_accessor_implicitly_has_an_any_type: "'{0}', which lacks 'get' accessor and parameter type annotation on 'set' accessor, implicitly has an 'any' type.",
        Index_signature_of_object_type_implicitly_has_an_any_type: "Index signature of object type implicitly has an 'any' type.",
        Object_literal_s_property_0_implicitly_has_an_any_type_from_widening: "Object literal's property '{0}' implicitly has an 'any' type from widening."
    };
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var ArrayUtilities = (function () {
        function ArrayUtilities() {
        }
        ArrayUtilities.isArray = function (value) {
            return Object.prototype.toString.apply(value, []) === '[object Array]';
        };

        ArrayUtilities.sequenceEquals = function (array1, array2, equals) {
            if (array1 === array2) {
                return true;
            }

            if (array1 === null || array2 === null) {
                return false;
            }

            if (array1.length !== array2.length) {
                return false;
            }

            for (var i = 0, n = array1.length; i < n; i++) {
                if (!equals(array1[i], array2[i])) {
                    return false;
                }
            }

            return true;
        };

        ArrayUtilities.contains = function (array, value) {
            for (var i = 0; i < array.length; i++) {
                if (array[i] === value) {
                    return true;
                }
            }

            return false;
        };

        ArrayUtilities.groupBy = function (array, func) {
            var result = {};

            for (var i = 0, n = array.length; i < n; i++) {
                var v = array[i];
                var k = func(v);

                var list = result[k] || [];
                list.push(v);
                result[k] = list;
            }

            return result;
        };

        ArrayUtilities.distinct = function (array, equalsFn) {
            var result = [];

            for (var i = 0, n = array.length; i < n; i++) {
                var current = array[i];
                for (var j = 0; j < result.length; j++) {
                    if (equalsFn(result[j], current)) {
                        break;
                    }
                }

                if (j === result.length) {
                    result.push(current);
                }
            }

            return result;
        };

        ArrayUtilities.min = function (array, func) {
            var min = func(array[0]);

            for (var i = 1; i < array.length; i++) {
                var next = func(array[i]);
                if (next < min) {
                    min = next;
                }
            }

            return min;
        };

        ArrayUtilities.max = function (array, func) {
            var max = func(array[0]);

            for (var i = 1; i < array.length; i++) {
                var next = func(array[i]);
                if (next > max) {
                    max = next;
                }
            }

            return max;
        };

        ArrayUtilities.last = function (array) {
            if (array.length === 0) {
                throw TypeScript.Errors.argumentOutOfRange('array');
            }

            return array[array.length - 1];
        };

        ArrayUtilities.lastOrDefault = function (array, predicate) {
            for (var i = array.length - 1; i >= 0; i--) {
                var v = array[i];
                if (predicate(v, i)) {
                    return v;
                }
            }

            return null;
        };

        ArrayUtilities.firstOrDefault = function (array, func) {
            for (var i = 0, n = array.length; i < n; i++) {
                var value = array[i];
                if (func(value, i)) {
                    return value;
                }
            }

            return null;
        };

        ArrayUtilities.first = function (array, func) {
            for (var i = 0, n = array.length; i < n; i++) {
                var value = array[i];
                if (!func || func(value, i)) {
                    return value;
                }
            }

            throw TypeScript.Errors.invalidOperation();
        };

        ArrayUtilities.sum = function (array, func) {
            var result = 0;

            for (var i = 0, n = array.length; i < n; i++) {
                result += func(array[i]);
            }

            return result;
        };

        ArrayUtilities.select = function (values, func) {
            var result = new Array(values.length);

            for (var i = 0; i < values.length; i++) {
                result[i] = func(values[i]);
            }

            return result;
        };

        ArrayUtilities.where = function (values, func) {
            var result = new Array();

            for (var i = 0; i < values.length; i++) {
                if (func(values[i])) {
                    result.push(values[i]);
                }
            }

            return result;
        };

        ArrayUtilities.any = function (array, func) {
            for (var i = 0, n = array.length; i < n; i++) {
                if (func(array[i])) {
                    return true;
                }
            }

            return false;
        };

        ArrayUtilities.all = function (array, func) {
            for (var i = 0, n = array.length; i < n; i++) {
                if (!func(array[i])) {
                    return false;
                }
            }

            return true;
        };

        ArrayUtilities.binarySearch = function (array, value) {
            var low = 0;
            var high = array.length - 1;

            while (low <= high) {
                var middle = low + ((high - low) >> 1);
                var midValue = array[middle];

                if (midValue === value) {
                    return middle;
                } else if (midValue > value) {
                    high = middle - 1;
                } else {
                    low = middle + 1;
                }
            }

            return ~low;
        };

        ArrayUtilities.createArray = function (length, defaultValue) {
            var result = new Array(length);
            for (var i = 0; i < length; i++) {
                result[i] = defaultValue;
            }

            return result;
        };

        ArrayUtilities.grow = function (array, length, defaultValue) {
            var count = length - array.length;
            for (var i = 0; i < count; i++) {
                array.push(defaultValue);
            }
        };

        ArrayUtilities.copy = function (sourceArray, sourceIndex, destinationArray, destinationIndex, length) {
            for (var i = 0; i < length; i++) {
                destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];
            }
        };

        ArrayUtilities.indexOf = function (array, predicate) {
            for (var i = 0, n = array.length; i < n; i++) {
                if (predicate(array[i])) {
                    return i;
                }
            }

            return -1;
        };
        return ArrayUtilities;
    })();
    TypeScript.ArrayUtilities = ArrayUtilities;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (BitVector) {
        var pool = [];
        var Constants;
        (function (Constants) {
            Constants[Constants["MaxBitsPerEncodedNumber"] = 30] = "MaxBitsPerEncodedNumber";
            Constants[Constants["BitsPerEncodedBiStateValue"] = 1] = "BitsPerEncodedBiStateValue";

            Constants[Constants["BitsPerEncodedTriStateValue"] = 2] = "BitsPerEncodedTriStateValue";

            Constants[Constants["BiStateEncodedTrue"] = 1] = "BiStateEncodedTrue";
            Constants[Constants["BiStateClearBitsMask"] = 1] = "BiStateClearBitsMask";

            Constants[Constants["TriStateEncodedFalse"] = 1] = "TriStateEncodedFalse";
            Constants[Constants["TriStateEncodedTrue"] = 2] = "TriStateEncodedTrue";
            Constants[Constants["TriStateClearBitsMask"] = 3] = "TriStateClearBitsMask";
        })(Constants || (Constants = {}));

        var BitVectorImpl = (function () {
            function BitVectorImpl(allowUndefinedValues) {
                this.allowUndefinedValues = allowUndefinedValues;
                this.isReleased = false;
                this.bits = [];
            }
            BitVectorImpl.prototype.computeTriStateArrayIndex = function (index) {
                var encodedValuesPerNumber = 30 /* MaxBitsPerEncodedNumber */ / 2 /* BitsPerEncodedTriStateValue */;

                return (index / encodedValuesPerNumber) >>> 0;
            };

            BitVectorImpl.prototype.computeBiStateArrayIndex = function (index) {
                var encodedValuesPerNumber = 30 /* MaxBitsPerEncodedNumber */ / 1 /* BitsPerEncodedBiStateValue */;

                return (index / encodedValuesPerNumber) >>> 0;
            };

            BitVectorImpl.prototype.computeTriStateEncodedValueIndex = function (index) {
                var encodedValuesPerNumber = 30 /* MaxBitsPerEncodedNumber */ / 2 /* BitsPerEncodedTriStateValue */;

                return (index % encodedValuesPerNumber) * 2 /* BitsPerEncodedTriStateValue */;
            };

            BitVectorImpl.prototype.computeBiStateEncodedValueIndex = function (index) {
                var encodedValuesPerNumber = 30 /* MaxBitsPerEncodedNumber */ / 1 /* BitsPerEncodedBiStateValue */;

                return (index % encodedValuesPerNumber) * 1 /* BitsPerEncodedBiStateValue */;
            };

            BitVectorImpl.prototype.valueAt = function (index) {
                TypeScript.Debug.assert(!this.isReleased, "Should not use a released bitvector");
                if (this.allowUndefinedValues) {
                    var arrayIndex = this.computeTriStateArrayIndex(index);
                    var encoded = this.bits[arrayIndex];
                    if (encoded === undefined) {
                        return undefined;
                    }

                    var bitIndex = this.computeTriStateEncodedValueIndex(index);
                    if (encoded & (2 /* TriStateEncodedTrue */ << bitIndex)) {
                        return true;
                    } else if (encoded & (1 /* TriStateEncodedFalse */ << bitIndex)) {
                        return false;
                    } else {
                        return undefined;
                    }
                } else {
                    var arrayIndex = this.computeBiStateArrayIndex(index);
                    var encoded = this.bits[arrayIndex];
                    if (encoded === undefined) {
                        return false;
                    }

                    var bitIndex = this.computeBiStateEncodedValueIndex(index);
                    if (encoded & (1 /* BiStateEncodedTrue */ << bitIndex)) {
                        return true;
                    } else {
                        return false;
                    }
                }
            };

            BitVectorImpl.prototype.setValueAt = function (index, value) {
                TypeScript.Debug.assert(!this.isReleased, "Should not use a released bitvector");
                if (this.allowUndefinedValues) {
                    TypeScript.Debug.assert(value === true || value === false || value === undefined, "value must only be true, false or undefined.");

                    var arrayIndex = this.computeTriStateArrayIndex(index);
                    var encoded = this.bits[arrayIndex];
                    if (encoded === undefined) {
                        if (value === undefined) {
                            return;
                        }

                        encoded = 0;
                    }

                    var bitIndex = this.computeTriStateEncodedValueIndex(index);

                    var clearMask = ~(3 /* TriStateClearBitsMask */ << bitIndex);
                    encoded = encoded & clearMask;

                    if (value === true) {
                        encoded = encoded | (2 /* TriStateEncodedTrue */ << bitIndex);
                    } else if (value === false) {
                        encoded = encoded | (1 /* TriStateEncodedFalse */ << bitIndex);
                    }

                    this.bits[arrayIndex] = encoded;
                } else {
                    TypeScript.Debug.assert(value === true || value === false, "value must only be true or false.");

                    var arrayIndex = this.computeBiStateArrayIndex(index);
                    var encoded = this.bits[arrayIndex];
                    if (encoded === undefined) {
                        if (value === false) {
                            return;
                        }

                        encoded = 0;
                    }

                    var bitIndex = this.computeBiStateEncodedValueIndex(index);

                    encoded = encoded & ~(1 /* BiStateClearBitsMask */ << bitIndex);

                    if (value) {
                        encoded = encoded | (1 /* BiStateEncodedTrue */ << bitIndex);
                    }

                    this.bits[arrayIndex] = encoded;
                }
            };

            BitVectorImpl.prototype.release = function () {
                TypeScript.Debug.assert(!this.isReleased, "Should not use a released bitvector");
                this.isReleased = true;
                this.bits.length = 0;
                pool.push(this);
            };
            return BitVectorImpl;
        })();

        function getBitVector(allowUndefinedValues) {
            if (pool.length === 0) {
                return new BitVectorImpl(allowUndefinedValues);
            }

            var vector = pool.pop();
            vector.isReleased = false;
            vector.allowUndefinedValues = allowUndefinedValues;

            return vector;
        }
        BitVector.getBitVector = getBitVector;
    })(TypeScript.BitVector || (TypeScript.BitVector = {}));
    var BitVector = TypeScript.BitVector;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (BitMatrix) {
        var pool = [];

        var BitMatrixImpl = (function () {
            function BitMatrixImpl(allowUndefinedValues) {
                this.allowUndefinedValues = allowUndefinedValues;
                this.isReleased = false;
                this.vectors = [];
            }
            BitMatrixImpl.prototype.valueAt = function (x, y) {
                TypeScript.Debug.assert(!this.isReleased, "Should not use a released bitvector");
                var vector = this.vectors[x];
                if (!vector) {
                    return this.allowUndefinedValues ? undefined : false;
                }

                return vector.valueAt(y);
            };

            BitMatrixImpl.prototype.setValueAt = function (x, y, value) {
                TypeScript.Debug.assert(!this.isReleased, "Should not use a released bitvector");
                var vector = this.vectors[x];
                if (!vector) {
                    if (value === undefined) {
                        return;
                    }

                    vector = TypeScript.BitVector.getBitVector(this.allowUndefinedValues);
                    this.vectors[x] = vector;
                }

                vector.setValueAt(y, value);
            };

            BitMatrixImpl.prototype.release = function () {
                TypeScript.Debug.assert(!this.isReleased, "Should not use a released bitvector");
                this.isReleased = true;

                for (var name in this.vectors) {
                    if (this.vectors.hasOwnProperty(name)) {
                        var vector = this.vectors[name];
                        vector.release();
                    }
                }

                this.vectors.length = 0;
                pool.push(this);
            };
            return BitMatrixImpl;
        })();

        function getBitMatrix(allowUndefinedValues) {
            if (pool.length === 0) {
                return new BitMatrixImpl(allowUndefinedValues);
            }

            var matrix = pool.pop();
            matrix.isReleased = false;
            matrix.allowUndefinedValues = allowUndefinedValues;

            return matrix;
        }
        BitMatrix.getBitMatrix = getBitMatrix;
    })(TypeScript.BitMatrix || (TypeScript.BitMatrix = {}));
    var BitMatrix = TypeScript.BitMatrix;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Constants) {
        Constants[Constants["Max31BitInteger"] = 1073741823] = "Max31BitInteger";
        Constants[Constants["Min31BitInteger"] = -1073741824] = "Min31BitInteger";
    })(TypeScript.Constants || (TypeScript.Constants = {}));
    var Constants = TypeScript.Constants;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (AssertionLevel) {
        AssertionLevel[AssertionLevel["None"] = 0] = "None";
        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
    })(TypeScript.AssertionLevel || (TypeScript.AssertionLevel = {}));
    var AssertionLevel = TypeScript.AssertionLevel;

    var Debug = (function () {
        function Debug() {
        }
        Debug.shouldAssert = function (level) {
            return this.currentAssertionLevel >= level;
        };

        Debug.assert = function (expression, message, verboseDebugInfo) {
            if (typeof message === "undefined") { message = ""; }
            if (typeof verboseDebugInfo === "undefined") { verboseDebugInfo = null; }
            if (!expression) {
                var verboseDebugString = "";
                if (verboseDebugInfo) {
                    verboseDebugString = "\r\nVerbose Debug Information:" + verboseDebugInfo();
                }

                throw new Error("Debug Failure. False expression: " + message + verboseDebugString);
            }
        };

        Debug.fail = function (message) {
            Debug.assert(false, message);
        };
        Debug.currentAssertionLevel = 0 /* None */;
        return Debug;
    })();
    TypeScript.Debug = Debug;
})(TypeScript || (TypeScript = {}));
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var TypeScript;
(function (TypeScript) {
    TypeScript.LocalizedDiagnosticMessages = null;

    var Location = (function () {
        function Location(fileName, lineMap, start, length) {
            this._fileName = fileName;
            this._lineMap = lineMap;
            this._start = start;
            this._length = length;
        }
        Location.prototype.fileName = function () {
            return this._fileName;
        };

        Location.prototype.lineMap = function () {
            return this._lineMap;
        };

        Location.prototype.line = function () {
            return this._lineMap ? this._lineMap.getLineNumberFromPosition(this.start()) : 0;
        };

        Location.prototype.character = function () {
            return this._lineMap ? this._lineMap.getLineAndCharacterFromPosition(this.start()).character() : 0;
        };

        Location.prototype.start = function () {
            return this._start;
        };

        Location.prototype.length = function () {
            return this._length;
        };

        Location.equals = function (location1, location2) {
            return location1._fileName === location2._fileName && location1._start === location2._start && location1._length === location2._length;
        };
        return Location;
    })();
    TypeScript.Location = Location;

    var Diagnostic = (function (_super) {
        __extends(Diagnostic, _super);
        function Diagnostic(fileName, lineMap, start, length, diagnosticKey, _arguments, additionalLocations) {
            if (typeof _arguments === "undefined") { _arguments = null; }
            if (typeof additionalLocations === "undefined") { additionalLocations = null; }
            _super.call(this, fileName, lineMap, start, length);
            this._diagnosticKey = diagnosticKey;
            this._arguments = (_arguments && _arguments.length > 0) ? _arguments : null;
            this._additionalLocations = (additionalLocations && additionalLocations.length > 0) ? additionalLocations : null;
        }
        Diagnostic.prototype.toJSON = function (key) {
            var result = {};
            result.start = this.start();
            result.length = this.length();

            result.diagnosticCode = this._diagnosticKey;

            var _arguments = this.arguments();
            if (_arguments && _arguments.length > 0) {
                result.arguments = _arguments;
            }

            return result;
        };

        Diagnostic.prototype.diagnosticKey = function () {
            return this._diagnosticKey;
        };

        Diagnostic.prototype.arguments = function () {
            return this._arguments;
        };

        Diagnostic.prototype.text = function () {
            return TypeScript.getLocalizedText(this._diagnosticKey, this._arguments);
        };

        Diagnostic.prototype.message = function () {
            return TypeScript.getDiagnosticMessage(this._diagnosticKey, this._arguments);
        };

        Diagnostic.prototype.additionalLocations = function () {
            return this._additionalLocations || [];
        };

        Diagnostic.equals = function (diagnostic1, diagnostic2) {
            return Location.equals(diagnostic1, diagnostic2) && diagnostic1._diagnosticKey === diagnostic2._diagnosticKey && TypeScript.ArrayUtilities.sequenceEquals(diagnostic1._arguments, diagnostic2._arguments, function (v1, v2) {
                return v1 === v2;
            });
        };

        Diagnostic.prototype.info = function () {
            return getDiagnosticInfoFromKey(this.diagnosticKey());
        };
        return Diagnostic;
    })(Location);
    TypeScript.Diagnostic = Diagnostic;

    function newLine() {
        return TypeScript.Environment ? TypeScript.Environment.newLine : "\r\n";
    }
    TypeScript.newLine = newLine;

    function getLargestIndex(diagnostic) {
        var largest = -1;
        var regex = /\{(\d+)\}/g;

        var match;
        while (match = regex.exec(diagnostic)) {
            var val = parseInt(match[1]);
            if (!isNaN(val) && val > largest) {
                largest = val;
            }
        }

        return largest;
    }

    function getDiagnosticInfoFromKey(diagnosticKey) {
        var result = TypeScript.diagnosticInformationMap[diagnosticKey];
        TypeScript.Debug.assert(result);
        return result;
    }

    function getLocalizedText(diagnosticKey, args) {
        if (TypeScript.LocalizedDiagnosticMessages) {
        }

        var diagnosticMessageText = TypeScript.LocalizedDiagnosticMessages ? TypeScript.LocalizedDiagnosticMessages[diagnosticKey] : diagnosticKey;
        TypeScript.Debug.assert(diagnosticMessageText !== undefined && diagnosticMessageText !== null);

        var actualCount = args ? args.length : 0;

        var expectedCount = 1 + getLargestIndex(diagnosticKey);

        if (expectedCount !== actualCount) {
            throw new Error(getLocalizedText(TypeScript.DiagnosticCode.Expected_0_arguments_to_message_got_1_instead, [expectedCount, actualCount]));
        }

        var valueCount = 1 + getLargestIndex(diagnosticMessageText);
        if (valueCount !== expectedCount) {
            throw new Error(getLocalizedText(TypeScript.DiagnosticCode.Expected_the_message_0_to_have_1_arguments_but_it_had_2, [diagnosticMessageText, expectedCount, valueCount]));
        }

        diagnosticMessageText = diagnosticMessageText.replace(/{(\d+)}/g, function (match, num) {
            return typeof args[num] !== 'undefined' ? args[num] : match;
        });

        diagnosticMessageText = diagnosticMessageText.replace(/{(NL)}/g, function (match) {
            return TypeScript.newLine();
        });

        return diagnosticMessageText;
    }
    TypeScript.getLocalizedText = getLocalizedText;

    function getDiagnosticMessage(diagnosticKey, args) {
        var diagnostic = getDiagnosticInfoFromKey(diagnosticKey);
        var diagnosticMessageText = getLocalizedText(diagnosticKey, args);

        var message;
        if (diagnostic.category === 1 /* Error */) {
            message = getLocalizedText(TypeScript.DiagnosticCode.error_TS_0_1, [diagnostic.code, diagnosticMessageText]);
        } else if (diagnostic.category === 0 /* Warning */) {
            message = getLocalizedText(TypeScript.DiagnosticCode.warning_TS_0_1, [diagnostic.code, diagnosticMessageText]);
        } else {
            message = diagnosticMessageText;
        }

        return message;
    }
    TypeScript.getDiagnosticMessage = getDiagnosticMessage;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var Errors = (function () {
        function Errors() {
        }
        Errors.argument = function (argument, message) {
            return new Error("Invalid argument: " + argument + ". " + message);
        };

        Errors.argumentOutOfRange = function (argument) {
            return new Error("Argument out of range: " + argument);
        };

        Errors.argumentNull = function (argument) {
            return new Error("Argument null: " + argument);
        };

        Errors.abstract = function () {
            return new Error("Operation not implemented properly by subclass.");
        };

        Errors.notYetImplemented = function () {
            return new Error("Not yet implemented.");
        };

        Errors.invalidOperation = function (message) {
            return new Error("Invalid operation: " + message);
        };
        return Errors;
    })();
    TypeScript.Errors = Errors;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var Hash = (function () {
        function Hash() {
        }
        Hash.computeFnv1aCharArrayHashCode = function (text, start, len) {
            var hashCode = Hash.FNV_BASE;
            var end = start + len;

            for (var i = start; i < end; i++) {
                hashCode = TypeScript.IntegerUtilities.integerMultiplyLow32Bits(hashCode ^ text[i], Hash.FNV_PRIME);
            }

            return hashCode;
        };

        Hash.computeSimple31BitCharArrayHashCode = function (key, start, len) {
            var hash = 0;

            for (var i = 0; i < len; i++) {
                var ch = key[start + i];

                hash = ((((hash << 5) - hash) | 0) + ch) | 0;
            }

            return hash & 0x7FFFFFFF;
        };

        Hash.computeSimple31BitStringHashCode = function (key) {
            var hash = 0;

            var start = 0;
            var len = key.length;

            for (var i = 0; i < len; i++) {
                var ch = key.charCodeAt(start + i);

                hash = ((((hash << 5) - hash) | 0) + ch) | 0;
            }

            return hash & 0x7FFFFFFF;
        };

        Hash.computeMurmur2StringHashCode = function (key, seed) {
            var m = 0x5bd1e995;
            var r = 24;

            var numberOfCharsLeft = key.length;
            var h = Math.abs(seed ^ numberOfCharsLeft);

            var index = 0;
            while (numberOfCharsLeft >= 2) {
                var c1 = key.charCodeAt(index);
                var c2 = key.charCodeAt(index + 1);

                var k = Math.abs(c1 | (c2 << 16));

                k = TypeScript.IntegerUtilities.integerMultiplyLow32Bits(k, m);
                k ^= k >> r;
                k = TypeScript.IntegerUtilities.integerMultiplyLow32Bits(k, m);

                h = TypeScript.IntegerUtilities.integerMultiplyLow32Bits(h, m);
                h ^= k;

                index += 2;
                numberOfCharsLeft -= 2;
            }

            if (numberOfCharsLeft === 1) {
                h ^= key.charCodeAt(index);
                h = TypeScript.IntegerUtilities.integerMultiplyLow32Bits(h, m);
            }

            h ^= h >> 13;
            h = TypeScript.IntegerUtilities.integerMultiplyLow32Bits(h, m);
            h ^= h >> 15;

            return h;
        };

        Hash.getPrime = function (min) {
            for (var i = 0; i < Hash.primes.length; i++) {
                var num = Hash.primes[i];
                if (num >= min) {
                    return num;
                }
            }

            throw TypeScript.Errors.notYetImplemented();
        };

        Hash.expandPrime = function (oldSize) {
            var num = oldSize << 1;
            if (num > 2146435069 && 2146435069 > oldSize) {
                return 2146435069;
            }
            return Hash.getPrime(num);
        };

        Hash.combine = function (value, currentHash) {
            return (((currentHash << 5) + currentHash) + value) & 0x7FFFFFFF;
        };
        Hash.FNV_BASE = 2166136261;
        Hash.FNV_PRIME = 16777619;

        Hash.primes = [
            3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521,
            631, 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419,
            10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431,
            90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689,
            672827, 807403, 968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899,
            4166287, 4999559, 5999471, 7199369];
        return Hash;
    })();
    TypeScript.Hash = Hash;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Collections) {
        Collections.DefaultHashTableCapacity = 1024;

        var HashTableEntry = (function () {
            function HashTableEntry(Key, Value, HashCode, Next) {
                this.Key = Key;
                this.Value = Value;
                this.HashCode = HashCode;
                this.Next = Next;
            }
            return HashTableEntry;
        })();

        var HashTable = (function () {
            function HashTable(capacity, hash) {
                this.hash = hash;
                this.count = 0;
                var size = TypeScript.Hash.getPrime(capacity);
                this.entries = TypeScript.ArrayUtilities.createArray(size, null);
            }
            HashTable.prototype.set = function (key, value) {
                this.addOrSet(key, value, false);
            };

            HashTable.prototype.add = function (key, value) {
                this.addOrSet(key, value, true);
            };

            HashTable.prototype.containsKey = function (key) {
                var hashCode = this.computeHashCode(key);
                var entry = this.findEntry(key, hashCode);
                return entry !== null;
            };

            HashTable.prototype.get = function (key) {
                var hashCode = this.computeHashCode(key);
                var entry = this.findEntry(key, hashCode);

                return entry === null ? null : entry.Value;
            };

            HashTable.prototype.computeHashCode = function (key) {
                var hashCode = this.hash === null ? key.hashCode : this.hash(key);

                hashCode = hashCode & 0x7FFFFFFF;
                TypeScript.Debug.assert(hashCode >= 0);

                return hashCode;
            };

            HashTable.prototype.addOrSet = function (key, value, throwOnExistingEntry) {
                var hashCode = this.computeHashCode(key);

                var entry = this.findEntry(key, hashCode);
                if (entry !== null) {
                    if (throwOnExistingEntry) {
                        throw TypeScript.Errors.argument('key', "Key was already in table.");
                    }

                    entry.Key = key;
                    entry.Value = value;
                    return;
                }

                return this.addEntry(key, value, hashCode);
            };

            HashTable.prototype.findEntry = function (key, hashCode) {
                for (var e = this.entries[hashCode % this.entries.length]; e !== null; e = e.Next) {
                    if (e.HashCode === hashCode && key === e.Key) {
                        return e;
                    }
                }

                return null;
            };

            HashTable.prototype.addEntry = function (key, value, hashCode) {
                var index = hashCode % this.entries.length;

                var e = new HashTableEntry(key, value, hashCode, this.entries[index]);

                this.entries[index] = e;

                if (this.count >= (this.entries.length / 2)) {
                    this.grow();
                }

                this.count++;
                return e.Key;
            };

            HashTable.prototype.grow = function () {
                var newSize = TypeScript.Hash.expandPrime(this.entries.length);

                var oldEntries = this.entries;
                var newEntries = TypeScript.ArrayUtilities.createArray(newSize, null);

                this.entries = newEntries;

                for (var i = 0; i < oldEntries.length; i++) {
                    var e = oldEntries[i];

                    while (e !== null) {
                        var newIndex = e.HashCode % newSize;
                        var tmp = e.Next;
                        e.Next = newEntries[newIndex];
                        newEntries[newIndex] = e;
                        e = tmp;
                    }
                }
            };
            return HashTable;
        })();
        Collections.HashTable = HashTable;

        function createHashTable(capacity, hash) {
            if (typeof capacity === "undefined") { capacity = Collections.DefaultHashTableCapacity; }
            if (typeof hash === "undefined") { hash = null; }
            return new HashTable(capacity, hash);
        }
        Collections.createHashTable = createHashTable;

        var currentHashCode = 1;
        function identityHashCode(value) {
            if (value.__hash === undefined) {
                value.__hash = currentHashCode;
                currentHashCode++;
            }

            return value.__hash;
        }
        Collections.identityHashCode = identityHashCode;
    })(TypeScript.Collections || (TypeScript.Collections = {}));
    var Collections = TypeScript.Collections;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    TypeScript.nodeMakeDirectoryTime = 0;
    TypeScript.nodeCreateBufferTime = 0;
    TypeScript.nodeWriteFileSyncTime = 0;

    (function (ByteOrderMark) {
        ByteOrderMark[ByteOrderMark["None"] = 0] = "None";
        ByteOrderMark[ByteOrderMark["Utf8"] = 1] = "Utf8";
        ByteOrderMark[ByteOrderMark["Utf16BigEndian"] = 2] = "Utf16BigEndian";
        ByteOrderMark[ByteOrderMark["Utf16LittleEndian"] = 3] = "Utf16LittleEndian";
    })(TypeScript.ByteOrderMark || (TypeScript.ByteOrderMark = {}));
    var ByteOrderMark = TypeScript.ByteOrderMark;

    var FileInformation = (function () {
        function FileInformation(contents, byteOrderMark) {
            this.contents = contents;
            this.byteOrderMark = byteOrderMark;
        }
        return FileInformation;
    })();
    TypeScript.FileInformation = FileInformation;

    TypeScript.Environment = (function () {
        function getWindowsScriptHostEnvironment() {
            try  {
                var fso = new ActiveXObject("Scripting.FileSystemObject");
            } catch (e) {
                return null;
            }

            var streamObjectPool = [];

            function getStreamObject() {
                if (streamObjectPool.length > 0) {
                    return streamObjectPool.pop();
                } else {
                    return new ActiveXObject("ADODB.Stream");
                }
            }

            function releaseStreamObject(obj) {
                streamObjectPool.push(obj);
            }

            var args = [];
            for (var i = 0; i < WScript.Arguments.length; i++) {
                args[i] = WScript.Arguments.Item(i);
            }

            return {
                newLine: "\r\n",
                currentDirectory: function () {
                    return WScript.CreateObject("WScript.Shell").CurrentDirectory;
                },
                supportsCodePage: function () {
                    return WScript.ReadFile;
                },
                readFile: function (path, codepage) {
                    try  {
                        if (codepage !== null && this.supportsCodePage()) {
                            try  {
                                var contents = WScript.ReadFile(path, codepage);
                                return new FileInformation(contents, 0 /* None */);
                            } catch (e) {
                            }
                        }

                        var streamObj = getStreamObject();
                        streamObj.Open();
                        streamObj.Type = 2;

                        streamObj.Charset = 'x-ansi';

                        streamObj.LoadFromFile(path);
                        var bomChar = streamObj.ReadText(2);

                        streamObj.Position = 0;

                        var byteOrderMark = 0 /* None */;

                        if (bomChar.charCodeAt(0) === 0xFE && bomChar.charCodeAt(1) === 0xFF) {
                            streamObj.Charset = 'unicode';
                            byteOrderMark = 2 /* Utf16BigEndian */;
                        } else if (bomChar.charCodeAt(0) === 0xFF && bomChar.charCodeAt(1) === 0xFE) {
                            streamObj.Charset = 'unicode';
                            byteOrderMark = 3 /* Utf16LittleEndian */;
                        } else if (bomChar.charCodeAt(0) === 0xEF && bomChar.charCodeAt(1) === 0xBB) {
                            streamObj.Charset = 'utf-8';
                            byteOrderMark = 1 /* Utf8 */;
                        } else {
                            streamObj.Charset = 'utf-8';
                        }

                        var contents = streamObj.ReadText(-1);
                        streamObj.Close();
                        releaseStreamObject(streamObj);
                        return new FileInformation(contents, byteOrderMark);
                    } catch (err) {
                        var message;
                        if (err.number === -2147024809) {
                            message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Unsupported_file_encoding, null);
                        } else {
                            message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Cannot_read_file_0_1, [path, err.message]);
                        }

                        throw new Error(message);
                    }
                },
                writeFile: function (path, contents, writeByteOrderMark) {
                    var textStream = getStreamObject();
                    textStream.Charset = 'utf-8';
                    textStream.Open();
                    textStream.WriteText(contents, 0);

                    if (!writeByteOrderMark) {
                        textStream.Position = 3;
                    } else {
                        textStream.Position = 0;
                    }

                    var fileStream = getStreamObject();
                    fileStream.Type = 1;
                    fileStream.Open();

                    textStream.CopyTo(fileStream);

                    fileStream.Flush();
                    fileStream.SaveToFile(path, 2);
                    fileStream.Close();

                    textStream.Flush();
                    textStream.Close();
                },
                fileExists: function (path) {
                    return fso.FileExists(path);
                },
                deleteFile: function (path) {
                    if (fso.FileExists(path)) {
                        fso.DeleteFile(path, true);
                    }
                },
                directoryExists: function (path) {
                    return fso.FolderExists(path);
                },
                listFiles: function (path, spec, options) {
                    options = options || {};
                    function filesInFolder(folder, root) {
                        var paths = [];
                        var fc;

                        if (options.recursive) {
                            fc = new Enumerator(folder.subfolders);

                            for (; !fc.atEnd(); fc.moveNext()) {
                                paths = paths.concat(filesInFolder(fc.item(), root + "\\" + fc.item().Name));
                            }
                        }

                        fc = new Enumerator(folder.files);

                        for (; !fc.atEnd(); fc.moveNext()) {
                            if (!spec || fc.item().Name.match(spec)) {
                                paths.push(root + "\\" + fc.item().Name);
                            }
                        }

                        return paths;
                    }

                    var folder = fso.GetFolder(path);
                    var paths = [];

                    return filesInFolder(folder, path);
                },
                arguments: args,
                standardOut: WScript.StdOut
            };
        }
        ;

        function getNodeEnvironment() {
            var _fs = require('fs');
            var _path = require('path');
            var _module = require('module');
            var _os = require('os');

            return {
                newLine: _os.EOL,
                currentDirectory: function () {
                    return process.cwd();
                },
                supportsCodePage: function () {
                    return false;
                },
                readFile: function (file, codepage) {
                    if (codepage !== null) {
                        throw new Error(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.codepage_option_not_supported_on_current_platform, null));
                    }

                    var buffer = _fs.readFileSync(file);
                    switch (buffer[0]) {
                        case 0xFE:
                            if (buffer[1] === 0xFF) {
                                var i = 0;
                                while ((i + 1) < buffer.length) {
                                    var temp = buffer[i];
                                    buffer[i] = buffer[i + 1];
                                    buffer[i + 1] = temp;
                                    i += 2;
                                }
                                return new FileInformation(buffer.toString("ucs2", 2), 2 /* Utf16BigEndian */);
                            }
                            break;
                        case 0xFF:
                            if (buffer[1] === 0xFE) {
                                return new FileInformation(buffer.toString("ucs2", 2), 3 /* Utf16LittleEndian */);
                            }
                            break;
                        case 0xEF:
                            if (buffer[1] === 0xBB) {
                                return new FileInformation(buffer.toString("utf8", 3), 1 /* Utf8 */);
                            }
                    }

                    return new FileInformation(buffer.toString("utf8", 0), 0 /* None */);
                },
                writeFile: function (path, contents, writeByteOrderMark) {
                    function mkdirRecursiveSync(path) {
                        var stats = _fs.statSync(path);
                        if (stats.isFile()) {
                            throw "\"" + path + "\" exists but isn't a directory.";
                        } else if (stats.isDirectory()) {
                            return;
                        } else {
                            mkdirRecursiveSync(_path.dirname(path));
                            _fs.mkdirSync(path, 509);
                        }
                    }
                    var start = new Date().getTime();
                    mkdirRecursiveSync(_path.dirname(path));
                    TypeScript.nodeMakeDirectoryTime += new Date().getTime() - start;

                    if (writeByteOrderMark) {
                        contents = '\uFEFF' + contents;
                    }

                    var start = new Date().getTime();

                    var chunkLength = 4 * 1024;
                    var fileDescriptor = _fs.openSync(path, "w");
                    try  {
                        for (var index = 0; index < contents.length; index += chunkLength) {
                            var bufferStart = new Date().getTime();
                            var buffer = new Buffer(contents.substr(index, chunkLength), "utf8");
                            TypeScript.nodeCreateBufferTime += new Date().getTime() - bufferStart;

                            _fs.writeSync(fileDescriptor, buffer, 0, buffer.length, null);
                        }
                    } finally {
                        _fs.closeSync(fileDescriptor);
                    }

                    TypeScript.nodeWriteFileSyncTime += new Date().getTime() - start;
                },
                fileExists: function (path) {
                    return _fs.existsSync(path);
                },
                deleteFile: function (path) {
                    try  {
                        _fs.unlinkSync(path);
                    } catch (e) {
                    }
                },
                directoryExists: function (path) {
                    return _fs.existsSync(path) && _fs.statSync(path).isDirectory();
                },
                listFiles: function dir(path, spec, options) {
                    options = options || {};

                    function filesInFolder(folder) {
                        var paths = [];

                        var files = _fs.readdirSync(folder);
                        for (var i = 0; i < files.length; i++) {
                            var stat = _fs.statSync(folder + "\\" + files[i]);
                            if (options.recursive && stat.isDirectory()) {
                                paths = paths.concat(filesInFolder(folder + "\\" + files[i]));
                            } else if (stat.isFile() && (!spec || files[i].match(spec))) {
                                paths.push(folder + "\\" + files[i]);
                            }
                        }

                        return paths;
                    }

                    return filesInFolder(path);
                },
                arguments: process.argv.slice(2),
                standardOut: {
                    Write: function (str) {
                        process.stdout.write(str);
                    },
                    WriteLine: function (str) {
                        process.stdout.write(str + '\n');
                    },
                    Close: function () {
                    }
                }
            };
        }
        ;

        if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
            return getWindowsScriptHostEnvironment();
        } else if (typeof module !== 'undefined' && module.exports) {
            return getNodeEnvironment();
        } else {
            return null;
        }
    })();
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (IntegerUtilities) {
        function integerDivide(numerator, denominator) {
            return (numerator / denominator) >> 0;
        }
        IntegerUtilities.integerDivide = integerDivide;

        function integerMultiplyLow32Bits(n1, n2) {
            var n1Low16 = n1 & 0x0000ffff;
            var n1High16 = n1 >>> 16;

            var n2Low16 = n2 & 0x0000ffff;
            var n2High16 = n2 >>> 16;

            var resultLow32 = (((n1 & 0xffff0000) * n2) >>> 0) + (((n1 & 0x0000ffff) * n2) >>> 0) >>> 0;
            return resultLow32;
        }
        IntegerUtilities.integerMultiplyLow32Bits = integerMultiplyLow32Bits;

        function integerMultiplyHigh32Bits(n1, n2) {
            var n1Low16 = n1 & 0x0000ffff;
            var n1High16 = n1 >>> 16;

            var n2Low16 = n2 & 0x0000ffff;
            var n2High16 = n2 >>> 16;

            var resultHigh32 = n1High16 * n2High16 + ((((n1Low16 * n2Low16) >>> 17) + n1Low16 * n2High16) >>> 15);
            return resultHigh32;
        }
        IntegerUtilities.integerMultiplyHigh32Bits = integerMultiplyHigh32Bits;

        function isInteger(text) {
            return /^[0-9]+$/.test(text);
        }
        IntegerUtilities.isInteger = isInteger;

        function isHexInteger(text) {
            return /^0(x|X)[0-9a-fA-F]+$/.test(text);
        }
        IntegerUtilities.isHexInteger = isHexInteger;
    })(TypeScript.IntegerUtilities || (TypeScript.IntegerUtilities = {}));
    var IntegerUtilities = TypeScript.IntegerUtilities;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var LineMap = (function () {
        function LineMap(_computeLineStarts, length) {
            this._computeLineStarts = _computeLineStarts;
            this.length = length;
            this._lineStarts = null;
        }
        LineMap.prototype.toJSON = function (key) {
            return { lineStarts: this.lineStarts(), length: this.length };
        };

        LineMap.prototype.equals = function (other) {
            return this.length === other.length && TypeScript.ArrayUtilities.sequenceEquals(this.lineStarts(), other.lineStarts(), function (v1, v2) {
                return v1 === v2;
            });
        };

        LineMap.prototype.lineStarts = function () {
            if (this._lineStarts === null) {
                this._lineStarts = this._computeLineStarts();
            }

            return this._lineStarts;
        };

        LineMap.prototype.lineCount = function () {
            return this.lineStarts().length;
        };

        LineMap.prototype.getPosition = function (line, character) {
            return this.lineStarts()[line] + character;
        };

        LineMap.prototype.getLineNumberFromPosition = function (position) {
            if (position < 0 || position > this.length) {
                throw TypeScript.Errors.argumentOutOfRange("position");
            }

            if (position === this.length) {
                return this.lineCount() - 1;
            }

            var lineNumber = TypeScript.ArrayUtilities.binarySearch(this.lineStarts(), position);
            if (lineNumber < 0) {
                lineNumber = (~lineNumber) - 1;
            }

            return lineNumber;
        };

        LineMap.prototype.getLineStartPosition = function (lineNumber) {
            return this.lineStarts()[lineNumber];
        };

        LineMap.prototype.fillLineAndCharacterFromPosition = function (position, lineAndCharacter) {
            if (position < 0 || position > this.length) {
                throw TypeScript.Errors.argumentOutOfRange("position");
            }

            var lineNumber = this.getLineNumberFromPosition(position);
            lineAndCharacter.line = lineNumber;
            lineAndCharacter.character = position - this.lineStarts()[lineNumber];
        };

        LineMap.prototype.getLineAndCharacterFromPosition = function (position) {
            if (position < 0 || position > this.length) {
                throw TypeScript.Errors.argumentOutOfRange("position");
            }

            var lineNumber = this.getLineNumberFromPosition(position);

            return new TypeScript.LineAndCharacter(lineNumber, position - this.lineStarts()[lineNumber]);
        };
        LineMap.empty = new LineMap(function () {
            return [0];
        }, 0);
        return LineMap;
    })();
    TypeScript.LineMap = LineMap;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var LineAndCharacter = (function () {
        function LineAndCharacter(line, character) {
            this._line = 0;
            this._character = 0;
            if (line < 0) {
                throw TypeScript.Errors.argumentOutOfRange("line");
            }

            if (character < 0) {
                throw TypeScript.Errors.argumentOutOfRange("character");
            }

            this._line = line;
            this._character = character;
        }
        LineAndCharacter.prototype.line = function () {
            return this._line;
        };

        LineAndCharacter.prototype.character = function () {
            return this._character;
        };
        return LineAndCharacter;
    })();
    TypeScript.LineAndCharacter = LineAndCharacter;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var MathPrototype = (function () {
        function MathPrototype() {
        }
        MathPrototype.max = function (a, b) {
            return a >= b ? a : b;
        };

        MathPrototype.min = function (a, b) {
            return a <= b ? a : b;
        };
        return MathPrototype;
    })();
    TypeScript.MathPrototype = MathPrototype;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Collections) {
        Collections.DefaultStringTableCapacity = 256;

        var StringTableEntry = (function () {
            function StringTableEntry(Text, HashCode, Next) {
                this.Text = Text;
                this.HashCode = HashCode;
                this.Next = Next;
            }
            return StringTableEntry;
        })();

        var StringTable = (function () {
            function StringTable(capacity) {
                this.count = 0;
                var size = TypeScript.Hash.getPrime(capacity);
                this.entries = TypeScript.ArrayUtilities.createArray(size, null);
            }
            StringTable.prototype.addCharArray = function (key, start, len) {
                var hashCode = TypeScript.Hash.computeSimple31BitCharArrayHashCode(key, start, len) & 0x7FFFFFFF;

                var entry = this.findCharArrayEntry(key, start, len, hashCode);
                if (entry !== null) {
                    return entry.Text;
                }

                var slice = key.slice(start, start + len);
                return this.addEntry(TypeScript.StringUtilities.fromCharCodeArray(slice), hashCode);
            };

            StringTable.prototype.findCharArrayEntry = function (key, start, len, hashCode) {
                for (var e = this.entries[hashCode % this.entries.length]; e !== null; e = e.Next) {
                    if (e.HashCode === hashCode && StringTable.textCharArrayEquals(e.Text, key, start, len)) {
                        return e;
                    }
                }

                return null;
            };

            StringTable.prototype.addEntry = function (text, hashCode) {
                var index = hashCode % this.entries.length;

                var e = new StringTableEntry(text, hashCode, this.entries[index]);

                this.entries[index] = e;

                if (this.count === this.entries.length) {
                    this.grow();
                }

                this.count++;
                return e.Text;
            };

            StringTable.prototype.grow = function () {
                var newSize = TypeScript.Hash.expandPrime(this.entries.length);

                var oldEntries = this.entries;
                var newEntries = TypeScript.ArrayUtilities.createArray(newSize, null);

                this.entries = newEntries;

                for (var i = 0; i < oldEntries.length; i++) {
                    var e = oldEntries[i];
                    while (e !== null) {
                        var newIndex = e.HashCode % newSize;
                        var tmp = e.Next;
                        e.Next = newEntries[newIndex];
                        newEntries[newIndex] = e;
                        e = tmp;
                    }
                }
            };

            StringTable.textCharArrayEquals = function (text, array, start, length) {
                if (text.length !== length) {
                    return false;
                }

                var s = start;
                for (var i = 0; i < length; i++) {
                    if (text.charCodeAt(i) !== array[s]) {
                        return false;
                    }

                    s++;
                }

                return true;
            };
            return StringTable;
        })();
        Collections.StringTable = StringTable;

        Collections.DefaultStringTable = new StringTable(Collections.DefaultStringTableCapacity);
    })(TypeScript.Collections || (TypeScript.Collections = {}));
    var Collections = TypeScript.Collections;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var StringUtilities = (function () {
        function StringUtilities() {
        }
        StringUtilities.isString = function (value) {
            return Object.prototype.toString.apply(value, []) === '[object String]';
        };

        StringUtilities.fromCharCodeArray = function (array) {
            return String.fromCharCode.apply(null, array);
        };

        StringUtilities.endsWith = function (string, value) {
            return string.substring(string.length - value.length, string.length) === value;
        };

        StringUtilities.startsWith = function (string, value) {
            return string.substr(0, value.length) === value;
        };

        StringUtilities.copyTo = function (source, sourceIndex, destination, destinationIndex, count) {
            for (var i = 0; i < count; i++) {
                destination[destinationIndex + i] = source.charCodeAt(sourceIndex + i);
            }
        };

        StringUtilities.repeat = function (value, count) {
            return Array(count + 1).join(value);
        };

        StringUtilities.stringEquals = function (val1, val2) {
            return val1 === val2;
        };
        return StringUtilities;
    })();
    TypeScript.StringUtilities = StringUtilities;
})(TypeScript || (TypeScript = {}));
var global = Function("return this").call(null);

var TypeScript;
(function (TypeScript) {
    var Clock;
    (function (Clock) {
        Clock.now;
        Clock.resolution;

        if (typeof WScript !== "undefined" && typeof global['WScript'].InitializeProjection !== "undefined") {
            global['WScript'].InitializeProjection();

            Clock.now = function () {
                return TestUtilities.QueryPerformanceCounter();
            };

            Clock.resolution = TestUtilities.QueryPerformanceFrequency();
        } else {
            Clock.now = function () {
                return Date.now();
            };

            Clock.resolution = 1000;
        }
    })(Clock || (Clock = {}));

    var Timer = (function () {
        function Timer() {
            this.time = 0;
        }
        Timer.prototype.start = function () {
            this.time = 0;
            this.startTime = Clock.now();
        };

        Timer.prototype.end = function () {
            this.time = (Clock.now() - this.startTime);
        };
        return Timer;
    })();
    TypeScript.Timer = Timer;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (DiagnosticCategory) {
        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
        DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message";
        DiagnosticCategory[DiagnosticCategory["NoPrefix"] = 3] = "NoPrefix";
    })(TypeScript.DiagnosticCategory || (TypeScript.DiagnosticCategory = {}));
    var DiagnosticCategory = TypeScript.DiagnosticCategory;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    TypeScript.diagnosticInformationMap = {
        "error TS{0}: {1}": {
            "code": 0,
            "category": 3 /* NoPrefix */
        },
        "warning TS{0}: {1}": {
            "code": 1,
            "category": 3 /* NoPrefix */
        },
        "Unrecognized escape sequence.": {
            "code": 1000,
            "category": 1 /* Error */
        },
        "Unexpected character {0}.": {
            "code": 1001,
            "category": 1 /* Error */
        },
        "Missing close quote character.": {
            "code": 1002,
            "category": 1 /* Error */
        },
        "Identifier expected.": {
            "code": 1003,
            "category": 1 /* Error */
        },
        "'{0}' keyword expected.": {
            "code": 1004,
            "category": 1 /* Error */
        },
        "'{0}' expected.": {
            "code": 1005,
            "category": 1 /* Error */
        },
        "Identifier expected; '{0}' is a keyword.": {
            "code": 1006,
            "category": 1 /* Error */
        },
        "Automatic semicolon insertion not allowed.": {
            "code": 1007,
            "category": 1 /* Error */
        },
        "Unexpected token; '{0}' expected.": {
            "code": 1008,
            "category": 1 /* Error */
        },
        "Trailing separator not allowed.": {
            "code": 1009,
            "category": 1 /* Error */
        },
        "'*/' expected.": {
            "code": 1010,
            "category": 1 /* Error */
        },
        "'public' or 'private' modifier must precede 'static'.": {
            "code": 1011,
            "category": 1 /* Error */
        },
        "Unexpected token.": {
            "code": 1012,
            "category": 1 /* Error */
        },
        "Catch clause parameter cannot have a type annotation.": {
            "code": 1013,
            "category": 1 /* Error */
        },
        "Rest parameter must be last in list.": {
            "code": 1014,
            "category": 1 /* Error */
        },
        "Parameter cannot have question mark and initializer.": {
            "code": 1015,
            "category": 1 /* Error */
        },
        "Required parameter cannot follow optional parameter.": {
            "code": 1016,
            "category": 1 /* Error */
        },
        "Index signatures cannot have rest parameters.": {
            "code": 1017,
            "category": 1 /* Error */
        },
        "Index signature parameter cannot have accessibility modifiers.": {
            "code": 1018,
            "category": 1 /* Error */
        },
        "Index signature parameter cannot have a question mark.": {
            "code": 1019,
            "category": 1 /* Error */
        },
        "Index signature parameter cannot have an initializer.": {
            "code": 1020,
            "category": 1 /* Error */
        },
        "Index signature must have a type annotation.": {
            "code": 1021,
            "category": 1 /* Error */
        },
        "Index signature parameter must have a type annotation.": {
            "code": 1022,
            "category": 1 /* Error */
        },
        "Index signature parameter type must be 'string' or 'number'.": {
            "code": 1023,
            "category": 1 /* Error */
        },
        "'extends' clause already seen.": {
            "code": 1024,
            "category": 1 /* Error */
        },
        "'extends' clause must precede 'implements' clause.": {
            "code": 1025,
            "category": 1 /* Error */
        },
        "Classes can only extend a single class.": {
            "code": 1026,
            "category": 1 /* Error */
        },
        "'implements' clause already seen.": {
            "code": 1027,
            "category": 1 /* Error */
        },
        "Accessibility modifier already seen.": {
            "code": 1028,
            "category": 1 /* Error */
        },
        "'{0}' modifier must precede '{1}' modifier.": {
            "code": 1029,
            "category": 1 /* Error */
        },
        "'{0}' modifier already seen.": {
            "code": 1030,
            "category": 1 /* Error */
        },
        "'{0}' modifier cannot appear on a class element.": {
            "code": 1031,
            "category": 1 /* Error */
        },
        "Interface declaration cannot have 'implements' clause.": {
            "code": 1032,
            "category": 1 /* Error */
        },
        "'super' invocation cannot have type arguments.": {
            "code": 1034,
            "category": 1 /* Error */
        },
        "Only ambient modules can use quoted names.": {
            "code": 1035,
            "category": 1 /* Error */
        },
        "Statements are not allowed in ambient contexts.": {
            "code": 1036,
            "category": 1 /* Error */
        },
        "Implementations are not allowed in ambient contexts.": {
            "code": 1037,
            "category": 1 /* Error */
        },
        "'declare' modifier not allowed for code already in an ambient context.": {
            "code": 1038,
            "category": 1 /* Error */
        },
        "Initializers are not allowed in ambient contexts.": {
            "code": 1039,
            "category": 1 /* Error */
        },
        "Parameter property declarations can only be used in a non-ambient constructor declaration.": {
            "code": 1040,
            "category": 1 /* Error */
        },
        "Function implementation expected.": {
            "code": 1041,
            "category": 1 /* Error */
        },
        "Constructor implementation expected.": {
            "code": 1042,
            "category": 1 /* Error */
        },
        "Function overload name must be '{0}'.": {
            "code": 1043,
            "category": 1 /* Error */
        },
        "'{0}' modifier cannot appear on a module element.": {
            "code": 1044,
            "category": 1 /* Error */
        },
        "'declare' modifier cannot appear on an interface declaration.": {
            "code": 1045,
            "category": 1 /* Error */
        },
        "'declare' modifier required for top level element.": {
            "code": 1046,
            "category": 1 /* Error */
        },
        "Rest parameter cannot be optional.": {
            "code": 1047,
            "category": 1 /* Error */
        },
        "Rest parameter cannot have an initializer.": {
            "code": 1048,
            "category": 1 /* Error */
        },
        "'set' accessor must have one and only one parameter.": {
            "code": 1049,
            "category": 1 /* Error */
        },
        "'set' accessor parameter cannot be optional.": {
            "code": 1051,
            "category": 1 /* Error */
        },
        "'set' accessor parameter cannot have an initializer.": {
            "code": 1052,
            "category": 1 /* Error */
        },
        "'set' accessor cannot have rest parameter.": {
            "code": 1053,
            "category": 1 /* Error */
        },
        "'get' accessor cannot have parameters.": {
            "code": 1054,
            "category": 1 /* Error */
        },
        "Modifiers cannot appear here.": {
            "code": 1055,
            "category": 1 /* Error */
        },
        "Accessors are only available when targeting ECMAScript 5 and higher.": {
            "code": 1056,
            "category": 1 /* Error */
        },
        "Class name cannot be '{0}'.": {
            "code": 1057,
            "category": 1 /* Error */
        },
        "Interface name cannot be '{0}'.": {
            "code": 1058,
            "category": 1 /* Error */
        },
        "Enum name cannot be '{0}'.": {
            "code": 1059,
            "category": 1 /* Error */
        },
        "Module name cannot be '{0}'.": {
            "code": 1060,
            "category": 1 /* Error */
        },
        "Enum member must have initializer.": {
            "code": 1061,
            "category": 1 /* Error */
        },
        "Export assignment cannot be used in internal modules.": {
            "code": 1063,
            "category": 1 /* Error */
        },
        "Export assignment not allowed in module with exported element.": {
            "code": 1064,
            "category": 1 /* Error */
        },
        "Module cannot have multiple export assignments.": {
            "code": 1065,
            "category": 1 /* Error */
        },
        "Ambient enum elements can only have integer literal initializers.": {
            "code": 1066,
            "category": 1 /* Error */
        },
        "module, class, interface, enum, import or statement": {
            "code": 1067,
            "category": 3 /* NoPrefix */
        },
        "constructor, function, accessor or variable": {
            "code": 1068,
            "category": 3 /* NoPrefix */
        },
        "statement": {
            "code": 1069,
            "category": 3 /* NoPrefix */
        },
        "case or default clause": {
            "code": 1070,
            "category": 3 /* NoPrefix */
        },
        "identifier": {
            "code": 1071,
            "category": 3 /* NoPrefix */
        },
        "call, construct, index, property or function signature": {
            "code": 1072,
            "category": 3 /* NoPrefix */
        },
        "expression": {
            "code": 1073,
            "category": 3 /* NoPrefix */
        },
        "type name": {
            "code": 1074,
            "category": 3 /* NoPrefix */
        },
        "property or accessor": {
            "code": 1075,
            "category": 3 /* NoPrefix */
        },
        "parameter": {
            "code": 1076,
            "category": 3 /* NoPrefix */
        },
        "type": {
            "code": 1077,
            "category": 3 /* NoPrefix */
        },
        "type parameter": {
            "code": 1078,
            "category": 3 /* NoPrefix */
        },
        "'declare' modifier not allowed on import declaration.": {
            "code": 1079,
            "category": 1 /* Error */
        },
        "Function overload must be static.": {
            "code": 1080,
            "category": 1 /* Error */
        },
        "Function overload must not be static.": {
            "code": 1081,
            "category": 1 /* Error */
        },
        "Parameter property declarations cannot be used in a constructor overload.": {
            "code": 1083,
            "category": 1 /* Error */
        },
        "Invalid 'reference' directive syntax.": {
            "code": 1084,
            "category": 1 /* Error */
        },
        "Octal literals are not available when targeting ECMAScript 5 and higher.": {
            "code": 1085,
            "category": 1 /* Error */
        },
        "Accessors are not allowed in ambient contexts.": {
            "code": 1086,
            "category": 1 /* Error */
        },
        "'{0}' modifier cannot appear on a constructor declaration.": {
            "code": 1089,
            "category": 1 /* Error */
        },
        "'{0}' modifier cannot appear on a parameter.": {
            "code": 1090,
            "category": 1 /* Error */
        },
        "Only a single variable declaration is allowed in a 'for...in' statement.": {
            "code": 1091,
            "category": 1 /* Error */
        },
        "Type parameters cannot appear on a constructor declaration.": {
            "code": 1091,
            "category": 1 /* Error */
        },
        "Type annotation cannot appear on a constructor declaration.": {
            "code": 1092,
            "category": 1 /* Error */
        },
        "Duplicate identifier '{0}'.": {
            "code": 2000,
            "category": 1 /* Error */
        },
        "The name '{0}' does not exist in the current scope.": {
            "code": 2001,
            "category": 1 /* Error */
        },
        "The name '{0}' does not refer to a value.": {
            "code": 2002,
            "category": 1 /* Error */
        },
        "'super' can only be used inside a class instance method.": {
            "code": 2003,
            "category": 1 /* Error */
        },
        "The left-hand side of an assignment expression must be a variable, property or indexer.": {
            "code": 2004,
            "category": 1 /* Error */
        },
        "Value of type '{0}' is not callable. Did you mean to include 'new'?": {
            "code": 2161,
            "category": 1 /* Error */
        },
        "Value of type '{0}' is not callable.": {
            "code": 2006,
            "category": 1 /* Error */
        },
        "Value of type '{0}' is not newable.": {
            "code": 2007,
            "category": 1 /* Error */
        },
        "Value of type '{0}' is not indexable by type '{1}'.": {
            "code": 2008,
            "category": 1 /* Error */
        },
        "Operator '{0}' cannot be applied to types '{1}' and '{2}'.": {
            "code": 2009,
            "category": 1 /* Error */
        },
        "Operator '{0}' cannot be applied to types '{1}' and '{2}': {3}": {
            "code": 2010,
            "category": 1 /* Error */
        },
        "Cannot convert '{0}' to '{1}'.": {
            "code": 2011,
            "category": 1 /* Error */
        },
        "Cannot convert '{0}' to '{1}':{NL}{2}": {
            "code": 2012,
            "category": 1 /* Error */
        },
        "Expected var, class, interface, or module.": {
            "code": 2013,
            "category": 1 /* Error */
        },
        "Operator '{0}' cannot be applied to type '{1}'.": {
            "code": 2014,
            "category": 1 /* Error */
        },
        "Getter '{0}' already declared.": {
            "code": 2015,
            "category": 1 /* Error */
        },
        "Setter '{0}' already declared.": {
            "code": 2016,
            "category": 1 /* Error */
        },
        "Exported class '{0}' extends private class '{1}'.": {
            "code": 2018,
            "category": 1 /* Error */
        },
        "Exported class '{0}' implements private interface '{1}'.": {
            "code": 2019,
            "category": 1 /* Error */
        },
        "Exported interface '{0}' extends private interface '{1}'.": {
            "code": 2020,
            "category": 1 /* Error */
        },
        "Exported class '{0}' extends class from inaccessible module {1}.": {
            "code": 2021,
            "category": 1 /* Error */
        },
        "Exported class '{0}' implements interface from inaccessible module {1}.": {
            "code": 2022,
            "category": 1 /* Error */
        },
        "Exported interface '{0}' extends interface from inaccessible module {1}.": {
            "code": 2023,
            "category": 1 /* Error */
        },
        "Public static property '{0}' of exported class has or is using private type '{1}'.": {
            "code": 2024,
            "category": 1 /* Error */
        },
        "Public property '{0}' of exported class has or is using private type '{1}'.": {
            "code": 2025,
            "category": 1 /* Error */
        },
        "Property '{0}' of exported interface has or is using private type '{1}'.": {
            "code": 2026,
            "category": 1 /* Error */
        },
        "Exported variable '{0}' has or is using private type '{1}'.": {
            "code": 2027,
            "category": 1 /* Error */
        },
        "Public static property '{0}' of exported class is using inaccessible module {1}.": {
            "code": 2028,
            "category": 1 /* Error */
        },
        "Public property '{0}' of exported class is using inaccessible module {1}.": {
            "code": 2029,
            "category": 1 /* Error */
        },
        "Property '{0}' of exported interface is using inaccessible module {1}.": {
            "code": 2030,
            "category": 1 /* Error */
        },
        "Exported variable '{0}' is using inaccessible module {1}.": {
            "code": 2031,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of constructor from exported class has or is using private type '{1}'.": {
            "code": 2032,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public static property setter from exported class has or is using private type '{1}'.": {
            "code": 2033,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public property setter from exported class has or is using private type '{1}'.": {
            "code": 2034,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of constructor signature from exported interface has or is using private type '{1}'.": {
            "code": 2035,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of call signature from exported interface has or is using private type '{1}'.": {
            "code": 2036,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public static method from exported class has or is using private type '{1}'.": {
            "code": 2037,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public method from exported class has or is using private type '{1}'.": {
            "code": 2038,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of method from exported interface has or is using private type '{1}'.": {
            "code": 2039,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of exported function has or is using private type '{1}'.": {
            "code": 2040,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of constructor from exported class is using inaccessible module {1}.": {
            "code": 2041,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public static property setter from exported class is using inaccessible module {1}.": {
            "code": 2042,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public property setter from exported class is using inaccessible module {1}.": {
            "code": 2043,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of constructor signature from exported interface is using inaccessible module {1}.": {
            "code": 2044,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of call signature from exported interface is using inaccessible module {1}": {
            "code": 2045,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public static method from exported class is using inaccessible module {1}.": {
            "code": 2046,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of public method from exported class is using inaccessible module {1}.": {
            "code": 2047,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of method from exported interface is using inaccessible module {1}.": {
            "code": 2048,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of exported function is using inaccessible module {1}.": {
            "code": 2049,
            "category": 1 /* Error */
        },
        "Return type of public static property getter from exported class has or is using private type '{0}'.": {
            "code": 2050,
            "category": 1 /* Error */
        },
        "Return type of public property getter from exported class has or is using private type '{0}'.": {
            "code": 2051,
            "category": 1 /* Error */
        },
        "Return type of constructor signature from exported interface has or is using private type '{0}'.": {
            "code": 2052,
            "category": 1 /* Error */
        },
        "Return type of call signature from exported interface has or is using private type '{0}'.": {
            "code": 2053,
            "category": 1 /* Error */
        },
        "Return type of index signature from exported interface has or is using private type '{0}'.": {
            "code": 2054,
            "category": 1 /* Error */
        },
        "Return type of public static method from exported class has or is using private type '{0}'.": {
            "code": 2055,
            "category": 1 /* Error */
        },
        "Return type of public method from exported class has or is using private type '{0}'.": {
            "code": 2056,
            "category": 1 /* Error */
        },
        "Return type of method from exported interface has or is using private type '{0}'.": {
            "code": 2057,
            "category": 1 /* Error */
        },
        "Return type of exported function has or is using private type '{0}'.": {
            "code": 2058,
            "category": 1 /* Error */
        },
        "Return type of public static property getter from exported class is using inaccessible module {0}.": {
            "code": 2059,
            "category": 1 /* Error */
        },
        "Return type of public property getter from exported class is using inaccessible module {0}.": {
            "code": 2060,
            "category": 1 /* Error */
        },
        "Return type of constructor signature from exported interface is using inaccessible module {0}.": {
            "code": 2061,
            "category": 1 /* Error */
        },
        "Return type of call signature from exported interface is using inaccessible module {0}.": {
            "code": 2062,
            "category": 1 /* Error */
        },
        "Return type of index signature from exported interface is using inaccessible module {0}.": {
            "code": 2063,
            "category": 1 /* Error */
        },
        "Return type of public static method from exported class is using inaccessible module {0}.": {
            "code": 2064,
            "category": 1 /* Error */
        },
        "Return type of public method from exported class is using inaccessible module {0}.": {
            "code": 2065,
            "category": 1 /* Error */
        },
        "Return type of method from exported interface is using inaccessible module {0}.": {
            "code": 2066,
            "category": 1 /* Error */
        },
        "Return type of exported function is using inaccessible module {0}.": {
            "code": 2067,
            "category": 1 /* Error */
        },
        "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead.": {
            "code": 2068,
            "category": 1 /* Error */
        },
        "A parameter list must follow a generic type argument list. '(' expected.": {
            "code": 2069,
            "category": 1 /* Error */
        },
        "Multiple constructor implementations are not allowed.": {
            "code": 2070,
            "category": 1 /* Error */
        },
        "Unable to resolve external module '{0}'.": {
            "code": 2071,
            "category": 1 /* Error */
        },
        "Module cannot be aliased to a non-module type.": {
            "code": 2072,
            "category": 1 /* Error */
        },
        "A class may only extend another class.": {
            "code": 2073,
            "category": 1 /* Error */
        },
        "A class may only implement another class or interface.": {
            "code": 2074,
            "category": 1 /* Error */
        },
        "An interface may only extend another class or interface.": {
            "code": 2075,
            "category": 1 /* Error */
        },
        "Unable to resolve type.": {
            "code": 2077,
            "category": 1 /* Error */
        },
        "Unable to resolve type of '{0}'.": {
            "code": 2078,
            "category": 1 /* Error */
        },
        "Unable to resolve type parameter constraint.": {
            "code": 2079,
            "category": 1 /* Error */
        },
        "Type parameter constraint cannot be a primitive type.": {
            "code": 2080,
            "category": 1 /* Error */
        },
        "Supplied parameters do not match any signature of call target.": {
            "code": 2081,
            "category": 1 /* Error */
        },
        "Supplied parameters do not match any signature of call target:{NL}{0}": {
            "code": 2082,
            "category": 1 /* Error */
        },
        "Invalid 'new' expression.": {
            "code": 2083,
            "category": 1 /* Error */
        },
        "Call signatures used in a 'new' expression must have a 'void' return type.": {
            "code": 2084,
            "category": 1 /* Error */
        },
        "Could not select overload for 'new' expression.": {
            "code": 2085,
            "category": 1 /* Error */
        },
        "Type '{0}' does not satisfy the constraint '{1}' for type parameter '{2}'.": {
            "code": 2086,
            "category": 1 /* Error */
        },
        "Could not select overload for 'call' expression.": {
            "code": 2087,
            "category": 1 /* Error */
        },
        "Cannot invoke an expression whose type lacks a call signature.": {
            "code": 2088,
            "category": 1 /* Error */
        },
        "Calls to 'super' are only valid inside a class.": {
            "code": 2089,
            "category": 1 /* Error */
        },
        "Generic type '{0}' requires {1} type argument(s).": {
            "code": 2090,
            "category": 1 /* Error */
        },
        "Type of array literal cannot be determined. Best common type could not be found for array elements.": {
            "code": 2092,
            "category": 1 /* Error */
        },
        "Could not find enclosing symbol for dotted name '{0}'.": {
            "code": 2093,
            "category": 1 /* Error */
        },
        "The property '{0}' does not exist on value of type '{1}'.": {
            "code": 2094,
            "category": 1 /* Error */
        },
        "Could not find symbol '{0}'.": {
            "code": 2095,
            "category": 1 /* Error */
        },
        "'get' and 'set' accessor must have the same type.": {
            "code": 2096,
            "category": 1 /* Error */
        },
        "'this' cannot be referenced in current location.": {
            "code": 2097,
            "category": 1 /* Error */
        },
        "Static members cannot reference class type parameters.": {
            "code": 2099,
            "category": 1 /* Error */
        },
        "Class '{0}' is recursively referenced as a base type of itself.": {
            "code": 2100,
            "category": 1 /* Error */
        },
        "Interface '{0}' is recursively referenced as a base type of itself.": {
            "code": 2101,
            "category": 1 /* Error */
        },
        "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.": {
            "code": 2102,
            "category": 1 /* Error */
        },
        "'super' cannot be referenced in non-derived classes.": {
            "code": 2103,
            "category": 1 /* Error */
        },
        "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.": {
            "code": 2104,
            "category": 1 /* Error */
        },
        "Constructors for derived classes must contain a 'super' call.": {
            "code": 2105,
            "category": 1 /* Error */
        },
        "Super calls are not permitted outside constructors or in nested functions inside constructors.": {
            "code": 2106,
            "category": 1 /* Error */
        },
        "'{0}.{1}' is inaccessible.": {
            "code": 2107,
            "category": 1 /* Error */
        },
        "'this' cannot be referenced within module bodies.": {
            "code": 2108,
            "category": 1 /* Error */
        },
        "Invalid '+' expression - types not known to support the addition operator.": {
            "code": 2111,
            "category": 1 /* Error */
        },
        "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
            "code": 2112,
            "category": 1 /* Error */
        },
        "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
            "code": 2113,
            "category": 1 /* Error */
        },
        "The type of a unary arithmetic operation operand must be of type 'any', 'number' or an enum type.": {
            "code": 2114,
            "category": 1 /* Error */
        },
        "Variable declarations of a 'for' statement cannot use a type annotation.": {
            "code": 2115,
            "category": 1 /* Error */
        },
        "Variable declarations of a 'for' statement must be of types 'string' or 'any'.": {
            "code": 2116,
            "category": 1 /* Error */
        },
        "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.": {
            "code": 2117,
            "category": 1 /* Error */
        },
        "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.": {
            "code": 2118,
            "category": 1 /* Error */
        },
        "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.": {
            "code": 2119,
            "category": 1 /* Error */
        },
        "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.": {
            "code": 2120,
            "category": 1 /* Error */
        },
        "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type.": {
            "code": 2121,
            "category": 1 /* Error */
        },
        "Setters cannot return a value.": {
            "code": 2122,
            "category": 1 /* Error */
        },
        "Tried to query type of uninitialized module '{0}'.": {
            "code": 2123,
            "category": 1 /* Error */
        },
        "Tried to set variable type to uninitialized module type '{0}'.": {
            "code": 2124,
            "category": 1 /* Error */
        },
        "Type '{0}' does not have type parameters.": {
            "code": 2125,
            "category": 1 /* Error */
        },
        "Getters must return a value.": {
            "code": 2126,
            "category": 1 /* Error */
        },
        "Getter and setter accessors do not agree in visibility.": {
            "code": 2127,
            "category": 1 /* Error */
        },
        "Invalid left-hand side of assignment expression.": {
            "code": 2130,
            "category": 1 /* Error */
        },
        "Function declared a non-void return type, but has no return expression.": {
            "code": 2131,
            "category": 1 /* Error */
        },
        "Cannot resolve return type reference.": {
            "code": 2132,
            "category": 1 /* Error */
        },
        "Constructors cannot have a return type of 'void'.": {
            "code": 2133,
            "category": 1 /* Error */
        },
        "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'.": {
            "code": 2134,
            "category": 1 /* Error */
        },
        "All symbols within a with block will be resolved to 'any'.": {
            "code": 2135,
            "category": 1 /* Error */
        },
        "Import declarations in an internal module cannot reference an external module.": {
            "code": 2136,
            "category": 1 /* Error */
        },
        "Class {0} declares interface {1} but does not implement it:{NL}{2}": {
            "code": 2137,
            "category": 1 /* Error */
        },
        "Class {0} declares class {1} as an interface but does not implement it:{NL}{2}": {
            "code": 2138,
            "category": 1 /* Error */
        },
        "The operand of an increment or decrement operator must be a variable, property or indexer.": {
            "code": 2139,
            "category": 1 /* Error */
        },
        "'this' cannot be referenced in static initializers in a class body.": {
            "code": 2140,
            "category": 1 /* Error */
        },
        "Class '{0}' cannot extend class '{1}':{NL}{2}": {
            "code": 2141,
            "category": 1 /* Error */
        },
        "Interface '{0}' cannot extend class '{1}':{NL}{2}": {
            "code": 2142,
            "category": 1 /* Error */
        },
        "Interface '{0}' cannot extend interface '{1}':{NL}{2}": {
            "code": 2143,
            "category": 1 /* Error */
        },
        "Duplicate overload signature for '{0}'.": {
            "code": 2144,
            "category": 1 /* Error */
        },
        "Duplicate constructor overload signature.": {
            "code": 2145,
            "category": 1 /* Error */
        },
        "Duplicate overload call signature.": {
            "code": 2146,
            "category": 1 /* Error */
        },
        "Duplicate overload construct signature.": {
            "code": 2147,
            "category": 1 /* Error */
        },
        "Overload signature is not compatible with function definition.": {
            "code": 2148,
            "category": 1 /* Error */
        },
        "Overload signature is not compatible with function definition:{NL}{0}": {
            "code": 2149,
            "category": 1 /* Error */
        },
        "Overload signatures must all be public or private.": {
            "code": 2150,
            "category": 1 /* Error */
        },
        "Overload signatures must all be exported or not exported.": {
            "code": 2151,
            "category": 1 /* Error */
        },
        "Overload signatures must all be ambient or non-ambient.": {
            "code": 2152,
            "category": 1 /* Error */
        },
        "Overload signatures must all be optional or required.": {
            "code": 2153,
            "category": 1 /* Error */
        },
        "Specialized overload signature is not assignable to any non-specialized signature.": {
            "code": 2154,
            "category": 1 /* Error */
        },
        "'this' cannot be referenced in constructor arguments.": {
            "code": 2155,
            "category": 1 /* Error */
        },
        "Instance member cannot be accessed off a class.": {
            "code": 2157,
            "category": 1 /* Error */
        },
        "Untyped function calls may not accept type arguments.": {
            "code": 2158,
            "category": 1 /* Error */
        },
        "Non-generic functions may not accept type arguments.": {
            "code": 2159,
            "category": 1 /* Error */
        },
        "A generic type may not reference itself with a wrapped form of its own type parameters.": {
            "code": 2160,
            "category": 1 /* Error */
        },
        "Rest parameters must be array types.": {
            "code": 2162,
            "category": 1 /* Error */
        },
        "Overload signature implementation cannot use specialized type.": {
            "code": 2163,
            "category": 1 /* Error */
        },
        "Export assignments may only be used at the top-level of external modules.": {
            "code": 2164,
            "category": 1 /* Error */
        },
        "Export assignments may only be made with variables, functions, classes, interfaces, enums and internal modules.": {
            "code": 2165,
            "category": 1 /* Error */
        },
        "Only public methods of the base class are accessible via the 'super' keyword.": {
            "code": 2166,
            "category": 1 /* Error */
        },
        "Numeric indexer type '{0}' must be assignable to string indexer type '{1}'.": {
            "code": 2167,
            "category": 1 /* Error */
        },
        "Numeric indexer type '{0}' must be assignable to string indexer type '{1}':{NL}{2}": {
            "code": 2168,
            "category": 1 /* Error */
        },
        "All numerically named properties must be assignable to numeric indexer type '{0}'.": {
            "code": 2169,
            "category": 1 /* Error */
        },
        "All numerically named properties must be assignable to numeric indexer type '{0}':{NL}{1}": {
            "code": 2170,
            "category": 1 /* Error */
        },
        "All named properties must be assignable to string indexer type '{0}'.": {
            "code": 2171,
            "category": 1 /* Error */
        },
        "All named properties must be assignable to string indexer type '{0}':{NL}{1}": {
            "code": 2172,
            "category": 1 /* Error */
        },
        "Generic type references must include all type arguments.": {
            "code": 2173,
            "category": 1 /* Error */
        },
        "Default arguments are only allowed in implementation.": {
            "code": 2174,
            "category": 1 /* Error */
        },
        "Overloads cannot differ only by return type.": {
            "code": 2175,
            "category": 1 /* Error */
        },
        "Function expression declared a non-void return type, but has no return expression.": {
            "code": 2176,
            "category": 1 /* Error */
        },
        "Import declaration referencing identifier from internal module can only be made with variables, functions, classes, interfaces, enums and internal modules.": {
            "code": 2177,
            "category": 1 /* Error */
        },
        "Could not find symbol '{0}' in module '{1}'.": {
            "code": 2178,
            "category": 1 /* Error */
        },
        "Unable to resolve module reference '{0}'.": {
            "code": 2179,
            "category": 1 /* Error */
        },
        "Could not find module '{0}' in module '{1}'.": {
            "code": 2180,
            "category": 1 /* Error */
        },
        "Exported import declaration '{0}' is assigned value with type that has or is using private type '{1}'.": {
            "code": 2181,
            "category": 1 /* Error */
        },
        "Exported import declaration '{0}' is assigned value with type that is using inaccessible module '{1}'.": {
            "code": 2182,
            "category": 1 /* Error */
        },
        "Exported import declaration '{0}' is assigned type that has or is using private type '{1}'.": {
            "code": 2183,
            "category": 1 /* Error */
        },
        "Exported import declaration '{0}' is assigned type that is using inaccessible module '{1}'.": {
            "code": 2184,
            "category": 1 /* Error */
        },
        "Exported import declaration '{0}' is assigned container that is or is using inaccessible module '{1}'.": {
            "code": 2185,
            "category": 1 /* Error */
        },
        "Type name '{0}' in extends clause does not reference constructor function for '{1}'.": {
            "code": 2186,
            "category": 1 /* Error */
        },
        "Internal module reference '{0}' in import declaration does not reference module instance for '{1}'.": {
            "code": 2187,
            "category": 1 /* Error */
        },
        "Module '{0}' cannot merge with previous declaration of '{1}' in a different file '{2}'.": {
            "code": 2188,
            "category": 1 /* Error */
        },
        "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}':{NL}{3}": {
            "code": 2189,
            "category": 1 /* Error */
        },
        "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it.": {
            "code": 2190,
            "category": 1 /* Error */
        },
        "Ambient external module declaration cannot be reopened.": {
            "code": 2191,
            "category": 1 /* Error */
        },
        "All declarations of merged declaration '{0}' must be exported or not exported.": {
            "code": 2192,
            "category": 1 /* Error */
        },
        "'super' cannot be referenced in constructor arguments.": {
            "code": 2193,
            "category": 1 /* Error */
        },
        "Return type of constructor signature must be assignable to the instance type of the class.": {
            "code": 2194,
            "category": 1 /* Error */
        },
        "Ambient external module declaration must be defined in global context.": {
            "code": 2195,
            "category": 1 /* Error */
        },
        "Ambient external module declaration cannot specify relative module name.": {
            "code": 2196,
            "category": 1 /* Error */
        },
        "Import declaration in an ambient external module declaration cannot reference external module through relative external module name.": {
            "code": 2197,
            "category": 1 /* Error */
        },
        "Could not find the best common type of types of all return statement expressions.": {
            "code": 2198,
            "category": 1 /* Error */
        },
        "Import declaration cannot refer to external module reference when --noResolve option is set.": {
            "code": 2199,
            "category": 1 /* Error */
        },
        "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference.": {
            "code": 2200,
            "category": 1 /* Error */
        },
        "'continue' statement can only be used within an enclosing iteration statement.": {
            "code": 2201,
            "category": 1 /* Error */
        },
        "'break' statement can only be used within an enclosing iteration or switch statement.": {
            "code": 2202,
            "category": 1 /* Error */
        },
        "Jump target not found.": {
            "code": 2203,
            "category": 1 /* Error */
        },
        "Jump target cannot cross function boundary.": {
            "code": 2204,
            "category": 1 /* Error */
        },
        "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference.": {
            "code": 2205,
            "category": 1 /* Error */
        },
        "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference.": {
            "code": 2206,
            "category": 1 /* Error */
        },
        "Expression resolves to '_super' that compiler uses to capture base class reference.": {
            "code": 2207,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of constructor signature from exported interface has or is using private type '{1}'.": {
            "code": 2208,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of call signature from exported interface has or is using private type '{1}'.": {
            "code": 2209,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of public static method from exported class has or is using private type '{1}'.": {
            "code": 2210,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of public method from exported class has or is using private type '{1}'.": {
            "code": 2211,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of method from exported interface has or is using private type '{1}'.": {
            "code": 2212,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of exported function has or is using private type '{1}'.": {
            "code": 2213,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of constructor signature from exported interface is using inaccessible module {1}.": {
            "code": 2214,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of call signature from exported interface is using inaccessible module {1}": {
            "code": 2215,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of public static method from exported class is using inaccessible module {1}.": {
            "code": 2216,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of public method from exported class is using inaccessible module {1}.": {
            "code": 2217,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of method from exported interface is using inaccessible module {1}.": {
            "code": 2218,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of exported function is using inaccessible module {1}.": {
            "code": 2219,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of exported class has or is using private type '{1}'.": {
            "code": 2220,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of exported interface has or is using private type '{1}'.": {
            "code": 2221,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of exported class is using inaccessible module {1}.": {
            "code": 2222,
            "category": 1 /* Error */
        },
        "TypeParameter '{0}' of exported interface is using inaccessible module {1}.": {
            "code": 2223,
            "category": 1 /* Error */
        },
        "Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter.": {
            "code": 2224,
            "category": 1 /* Error */
        },
        "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters.": {
            "code": 2225,
            "category": 1 /* Error */
        },
        "Type of conditional '{0}' must be identical to '{1}' or '{2}'.": {
            "code": 2226,
            "category": 1 /* Error */
        },
        "Type of conditional '{0}' must be identical to '{1}', '{2}' or '{3}'.": {
            "code": 2227,
            "category": 1 /* Error */
        },
        "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of an external module.": {
            "code": 2228,
            "category": 1 /* Error */
        },
        "Constraint of a type parameter cannot reference any type parameter from the same type parameter list.": {
            "code": 2229,
            "category": 1 /* Error */
        },
        "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": {
            "code": 2230,
            "category": 1 /* Error */
        },
        "Parameter '{0}' cannot be referenced in its initializer.": {
            "code": 2231,
            "category": 1 /* Error */
        },
        "Duplicate string index signature.": {
            "code": 2232,
            "category": 1 /* Error */
        },
        "Duplicate number index signature.": {
            "code": 2233,
            "category": 1 /* Error */
        },
        "All declarations of an interface must have identical type parameters.": {
            "code": 2234,
            "category": 1 /* Error */
        },
        "Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter.": {
            "code": 2235,
            "category": 1 /* Error */
        },
        "Type '{0}' is missing property '{1}' from type '{2}'.": {
            "code": 4000,
            "category": 3 /* NoPrefix */
        },
        "Types of property '{0}' of types '{1}' and '{2}' are incompatible.": {
            "code": 4001,
            "category": 3 /* NoPrefix */
        },
        "Types of property '{0}' of types '{1}' and '{2}' are incompatible:{NL}{3}": {
            "code": 4002,
            "category": 3 /* NoPrefix */
        },
        "Property '{0}' defined as private in type '{1}' is defined as public in type '{2}'.": {
            "code": 4003,
            "category": 3 /* NoPrefix */
        },
        "Property '{0}' defined as public in type '{1}' is defined as private in type '{2}'.": {
            "code": 4004,
            "category": 3 /* NoPrefix */
        },
        "Types '{0}' and '{1}' define property '{2}' as private.": {
            "code": 4005,
            "category": 3 /* NoPrefix */
        },
        "Call signatures of types '{0}' and '{1}' are incompatible.": {
            "code": 4006,
            "category": 3 /* NoPrefix */
        },
        "Call signatures of types '{0}' and '{1}' are incompatible:{NL}{2}": {
            "code": 4007,
            "category": 3 /* NoPrefix */
        },
        "Type '{0}' requires a call signature, but type '{1}' lacks one.": {
            "code": 4008,
            "category": 3 /* NoPrefix */
        },
        "Construct signatures of types '{0}' and '{1}' are incompatible.": {
            "code": 4009,
            "category": 3 /* NoPrefix */
        },
        "Construct signatures of types '{0}' and '{1}' are incompatible:{NL}{2}": {
            "code": 4010,
            "category": 3 /* NoPrefix */
        },
        "Type '{0}' requires a construct signature, but type '{1}' lacks one.": {
            "code": 4011,
            "category": 3 /* NoPrefix */
        },
        "Index signatures of types '{0}' and '{1}' are incompatible.": {
            "code": 4012,
            "category": 3 /* NoPrefix */
        },
        "Index signatures of types '{0}' and '{1}' are incompatible:{NL}{2}": {
            "code": 4013,
            "category": 3 /* NoPrefix */
        },
        "Call signature expects {0} or fewer parameters.": {
            "code": 4014,
            "category": 3 /* NoPrefix */
        },
        "Could not apply type '{0}' to argument {1} which is of type '{2}'.": {
            "code": 4015,
            "category": 3 /* NoPrefix */
        },
        "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function.": {
            "code": 4016,
            "category": 3 /* NoPrefix */
        },
        "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function.": {
            "code": 4017,
            "category": 3 /* NoPrefix */
        },
        "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor.": {
            "code": 4018,
            "category": 3 /* NoPrefix */
        },
        "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property.": {
            "code": 4019,
            "category": 3 /* NoPrefix */
        },
        "Types of static property '{0}' of class '{1}' and class '{2}' are incompatible.": {
            "code": 4020,
            "category": 3 /* NoPrefix */
        },
        "Types of static property '{0}' of class '{1}' and class '{2}' are incompatible:{NL}{3}": {
            "code": 4021,
            "category": 3 /* NoPrefix */
        },
        "Type reference cannot refer to container '{0}'.": {
            "code": 4022,
            "category": 1 /* Error */
        },
        "Type reference must refer to type.": {
            "code": 4023,
            "category": 1 /* Error */
        },
        "In enums with multiple declarations only one declaration can omit an initializer for the first enum element.": {
            "code": 4024,
            "category": 1 /* Error */
        },
        " (+ {0} overload(s))": {
            "code": 4025,
            "category": 2 /* Message */
        },
        "Variable declaration cannot have the same name as an import declaration.": {
            "code": 4026,
            "category": 1 /* Error */
        },
        "Signature expected {0} type arguments, got {1} instead.": {
            "code": 4027,
            "category": 1 /* Error */
        },
        "Property '{0}' defined as optional in type '{1}', but is required in type '{2}'.": {
            "code": 4028,
            "category": 3 /* NoPrefix */
        },
        "Types '{0}' and '{1}' originating in infinitely expanding type reference do not refer to same named type.": {
            "code": 4029,
            "category": 3 /* NoPrefix */
        },
        "Types '{0}' and '{1}' originating in infinitely expanding type reference have incompatible type arguments.": {
            "code": 4030,
            "category": 3 /* NoPrefix */
        },
        "Types '{0}' and '{1}' originating in infinitely expanding type reference have incompatible type arguments:{NL}{2}": {
            "code": 4031,
            "category": 3 /* NoPrefix */
        },
        "Named properties '{0}' of types '{1}' and '{2}' are not identical.": {
            "code": 4032,
            "category": 3 /* NoPrefix */
        },
        "Types of string indexer of types '{0}' and '{1}' are not identical.": {
            "code": 4033,
            "category": 3 /* NoPrefix */
        },
        "Types of number indexer of types '{0}' and '{1}' are not identical.": {
            "code": 4034,
            "category": 3 /* NoPrefix */
        },
        "Type of number indexer in type '{0}' is not assignable to string indexer type in type '{1}'.{NL}{2}": {
            "code": 4035,
            "category": 3 /* NoPrefix */
        },
        "Type of property '{0}' in type '{1}' is not assignable to string indexer type in type '{2}'.{NL}{3}": {
            "code": 4036,
            "category": 3 /* NoPrefix */
        },
        "Type of property '{0}' in type '{1}' is not assignable to number indexer type in type '{2}'.{NL}{3}": {
            "code": 4037,
            "category": 3 /* NoPrefix */
        },
        "Static property '{0}' defined as private in type '{1}' is defined as public in type '{2}'.": {
            "code": 4038,
            "category": 3 /* NoPrefix */
        },
        "Static property '{0}' defined as public in type '{1}' is defined as private in type '{2}'.": {
            "code": 4039,
            "category": 3 /* NoPrefix */
        },
        "Types '{0}' and '{1}' define static property '{2}' as private.": {
            "code": 4040,
            "category": 3 /* NoPrefix */
        },
        "Current host does not support '{0}' option.": {
            "code": 5001,
            "category": 1 /* Error */
        },
        "ECMAScript target version '{0}' not supported.  Specify a valid target version: '{1}' (default), or '{2}'": {
            "code": 5002,
            "category": 1 /* Error */
        },
        "Module code generation '{0}' not supported.": {
            "code": 5003,
            "category": 1 /* Error */
        },
        "Could not find file: '{0}'.": {
            "code": 5004,
            "category": 1 /* Error */
        },
        "A file cannot have a reference to itself.": {
            "code": 5006,
            "category": 1 /* Error */
        },
        "Cannot resolve referenced file: '{0}'.": {
            "code": 5007,
            "category": 1 /* Error */
        },
        "Cannot find the common subdirectory path for the input files.": {
            "code": 5009,
            "category": 1 /* Error */
        },
        "Emit Error: {0}.": {
            "code": 5011,
            "category": 1 /* Error */
        },
        "Cannot read file '{0}': {1}": {
            "code": 5012,
            "category": 1 /* Error */
        },
        "Unsupported file encoding.": {
            "code": 5013,
            "category": 3 /* NoPrefix */
        },
        "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'.": {
            "code": 5014,
            "category": 1 /* Error */
        },
        "Unsupported locale: '{0}'.": {
            "code": 5015,
            "category": 1 /* Error */
        },
        "Execution Failed.{NL}": {
            "code": 5016,
            "category": 1 /* Error */
        },
        "Invalid call to 'up'": {
            "code": 5019,
            "category": 1 /* Error */
        },
        "Invalid call to 'down'": {
            "code": 5020,
            "category": 1 /* Error */
        },
        "Base64 value '{0}' finished with a continuation bit.": {
            "code": 5021,
            "category": 1 /* Error */
        },
        "Unknown option '{0}'": {
            "code": 5023,
            "category": 1 /* Error */
        },
        "Expected {0} arguments to message, got {1} instead.": {
            "code": 5024,
            "category": 1 /* Error */
        },
        "Expected the message '{0}' to have {1} arguments, but it had {2}": {
            "code": 5025,
            "category": 1 /* Error */
        },
        "Could not delete file '{0}'": {
            "code": 5034,
            "category": 1 /* Error */
        },
        "Could not create directory '{0}'": {
            "code": 5035,
            "category": 1 /* Error */
        },
        "Error while executing file '{0}': ": {
            "code": 5036,
            "category": 1 /* Error */
        },
        "Cannot compile external modules unless the '--module' flag is provided.": {
            "code": 5037,
            "category": 1 /* Error */
        },
        "Option mapRoot cannot be specified without specifying sourcemap option.": {
            "code": 5038,
            "category": 1 /* Error */
        },
        "Option sourceRoot cannot be specified without specifying sourcemap option.": {
            "code": 5039,
            "category": 1 /* Error */
        },
        "Options mapRoot and sourceRoot cannot be specified without specifying sourcemap option.": {
            "code": 5040,
            "category": 1 /* Error */
        },
        "Option '{0}' specified without '{1}'": {
            "code": 5041,
            "category": 1 /* Error */
        },
        "'codepage' option not supported on current platform.": {
            "code": 5042,
            "category": 1 /* Error */
        },
        "Concatenate and emit output to single file.": {
            "code": 6001,
            "category": 2 /* Message */
        },
        "Generates corresponding {0} file.": {
            "code": 6002,
            "category": 2 /* Message */
        },
        "Specifies the location where debugger should locate map files instead of generated locations.": {
            "code": 6003,
            "category": 2 /* Message */
        },
        "Specifies the location where debugger should locate TypeScript files instead of source locations.": {
            "code": 6004,
            "category": 2 /* Message */
        },
        "Watch input files.": {
            "code": 6005,
            "category": 2 /* Message */
        },
        "Redirect output structure to the directory.": {
            "code": 6006,
            "category": 2 /* Message */
        },
        "Do not emit comments to output.": {
            "code": 6009,
            "category": 2 /* Message */
        },
        "Skip resolution and preprocessing.": {
            "code": 6010,
            "category": 2 /* Message */
        },
        "Specify ECMAScript target version: '{0}' (default), or '{1}'": {
            "code": 6015,
            "category": 2 /* Message */
        },
        "Specify module code generation: '{0}' or '{1}'": {
            "code": 6016,
            "category": 2 /* Message */
        },
        "Print this message.": {
            "code": 6017,
            "category": 2 /* Message */
        },
        "Print the compiler's version: {0}": {
            "code": 6019,
            "category": 2 /* Message */
        },
        "Allow use of deprecated '{0}' keyword when referencing an external module.": {
            "code": 6021,
            "category": 2 /* Message */
        },
        "Specify locale for errors and messages. For example '{0}' or '{1}'": {
            "code": 6022,
            "category": 2 /* Message */
        },
        "Syntax:   {0}": {
            "code": 6023,
            "category": 2 /* Message */
        },
        "options": {
            "code": 6024,
            "category": 2 /* Message */
        },
        "file1": {
            "code": 6025,
            "category": 2 /* Message */
        },
        "Examples:": {
            "code": 6026,
            "category": 2 /* Message */
        },
        "Options:": {
            "code": 6027,
            "category": 2 /* Message */
        },
        "Insert command line options and files from a file.": {
            "code": 6030,
            "category": 2 /* Message */
        },
        "Version {0}": {
            "code": 6029,
            "category": 2 /* Message */
        },
        "Use the '{0}' flag to see options.": {
            "code": 6031,
            "category": 2 /* Message */
        },
        "{NL}Recompiling ({0}):": {
            "code": 6032,
            "category": 2 /* Message */
        },
        "STRING": {
            "code": 6033,
            "category": 2 /* Message */
        },
        "KIND": {
            "code": 6034,
            "category": 2 /* Message */
        },
        "file2": {
            "code": 6035,
            "category": 2 /* Message */
        },
        "VERSION": {
            "code": 6036,
            "category": 2 /* Message */
        },
        "LOCATION": {
            "code": 6037,
            "category": 2 /* Message */
        },
        "DIRECTORY": {
            "code": 6038,
            "category": 2 /* Message */
        },
        "NUMBER": {
            "code": 6039,
            "category": 2 /* Message */
        },
        "Specify the codepage to use when opening source files.": {
            "code": 6040,
            "category": 2 /* Message */
        },
        "Additional locations:": {
            "code": 6041,
            "category": 2 /* Message */
        },
        "This version of the Javascript runtime does not support the '{0}' function.": {
            "code": 7000,
            "category": 1 /* Error */
        },
        "Unknown rule.": {
            "code": 7002,
            "category": 1 /* Error */
        },
        "Invalid line number ({0})": {
            "code": 7003,
            "category": 1 /* Error */
        },
        "Warn on expressions and declarations with an implied 'any' type.": {
            "code": 7004,
            "category": 2 /* Message */
        },
        "Variable '{0}' implicitly has an 'any' type.": {
            "code": 7005,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of '{1}' implicitly has an 'any' type.": {
            "code": 7006,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of function type implicitly has an 'any' type.": {
            "code": 7007,
            "category": 1 /* Error */
        },
        "Member '{0}' of object type implicitly has an 'any' type.": {
            "code": 7008,
            "category": 1 /* Error */
        },
        "'new' expression, which lacks a constructor signature, implicitly has an 'any' type.": {
            "code": 7009,
            "category": 1 /* Error */
        },
        "'{0}', which lacks return-type annotation, implicitly has an 'any' return type.": {
            "code": 7010,
            "category": 1 /* Error */
        },
        "Function expression, which lacks return-type annotation, implicitly has an 'any' return type.": {
            "code": 7011,
            "category": 1 /* Error */
        },
        "Parameter '{0}' of lambda function implicitly has an 'any' type.": {
            "code": 7012,
            "category": 1 /* Error */
        },
        "Constructor signature, which lacks return-type annotation, implicitly has an 'any' return type.": {
            "code": 7013,
            "category": 1 /* Error */
        },
        "Lambda Function, which lacks return-type annotation, implicitly has an 'any' return type.": {
            "code": 7014,
            "category": 1 /* Error */
        },
        "Array Literal implicitly has an 'any' type from widening.": {
            "code": 7015,
            "category": 1 /* Error */
        },
        "'{0}', which lacks 'get' accessor and parameter type annotation on 'set' accessor, implicitly has an 'any' type.": {
            "code": 7016,
            "category": 1 /* Error */
        },
        "Index signature of object type implicitly has an 'any' type.": {
            "code": 7017,
            "category": 1 /* Error */
        },
        "Object literal's property '{0}' implicitly has an 'any' type from widening.": {
            "code": 7018,
            "category": 1 /* Error */
        }
    };
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (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"] = 0x2028] = "lineSeparator";
        CharacterCodes[CharacterCodes["paragraphSeparator"] = 0x2029] = "paragraphSeparator";

        CharacterCodes[CharacterCodes["nextLine"] = 0x0085] = "nextLine";

        CharacterCodes[CharacterCodes["space"] = 0x0020] = "space";
        CharacterCodes[CharacterCodes["nonBreakingSpace"] = 0x00A0] = "nonBreakingSpace";
        CharacterCodes[CharacterCodes["enQuad"] = 0x2000] = "enQuad";
        CharacterCodes[CharacterCodes["emQuad"] = 0x2001] = "emQuad";
        CharacterCodes[CharacterCodes["enSpace"] = 0x2002] = "enSpace";
        CharacterCodes[CharacterCodes["emSpace"] = 0x2003] = "emSpace";
        CharacterCodes[CharacterCodes["threePerEmSpace"] = 0x2004] = "threePerEmSpace";
        CharacterCodes[CharacterCodes["fourPerEmSpace"] = 0x2005] = "fourPerEmSpace";
        CharacterCodes[CharacterCodes["sixPerEmSpace"] = 0x2006] = "sixPerEmSpace";
        CharacterCodes[CharacterCodes["figureSpace"] = 0x2007] = "figureSpace";
        CharacterCodes[CharacterCodes["punctuationSpace"] = 0x2008] = "punctuationSpace";
        CharacterCodes[CharacterCodes["thinSpace"] = 0x2009] = "thinSpace";
        CharacterCodes[CharacterCodes["hairSpace"] = 0x200A] = "hairSpace";
        CharacterCodes[CharacterCodes["zeroWidthSpace"] = 0x200B] = "zeroWidthSpace";
        CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 0x202F] = "narrowNoBreakSpace";
        CharacterCodes[CharacterCodes["ideographicSpace"] = 0x3000] = "ideographicSpace";

        CharacterCodes[CharacterCodes["_"] = 95] = "_";
        CharacterCodes[CharacterCodes["$"] = 36] = "$";

        CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
        CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
        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["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["E"] = 69] = "E";
        CharacterCodes[CharacterCodes["F"] = 70] = "F";
        CharacterCodes[CharacterCodes["X"] = 88] = "X";
        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["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["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"] = 0xFEFF] = "byteOrderMark";
        CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
        CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
    })(TypeScript.CharacterCodes || (TypeScript.CharacterCodes = {}));
    var CharacterCodes = TypeScript.CharacterCodes;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    

    (function (ScriptSnapshot) {
        var StringScriptSnapshot = (function () {
            function StringScriptSnapshot(text) {
                this.text = text;
                this._lineStartPositions = null;
            }
            StringScriptSnapshot.prototype.getText = function (start, end) {
                return this.text.substring(start, end);
            };

            StringScriptSnapshot.prototype.getLength = function () {
                return this.text.length;
            };

            StringScriptSnapshot.prototype.getLineStartPositions = function () {
                if (!this._lineStartPositions) {
                    this._lineStartPositions = TypeScript.TextUtilities.parseLineStarts(this.text);
                }

                return this._lineStartPositions;
            };

            StringScriptSnapshot.prototype.getTextChangeRangeSinceVersion = function (scriptVersion) {
                throw TypeScript.Errors.notYetImplemented();
            };
            return StringScriptSnapshot;
        })();

        function fromString(text) {
            return new StringScriptSnapshot(text);
        }
        ScriptSnapshot.fromString = fromString;
    })(TypeScript.ScriptSnapshot || (TypeScript.ScriptSnapshot = {}));
    var ScriptSnapshot = TypeScript.ScriptSnapshot;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (LineMap1) {
        function fromSimpleText(text) {
            return new TypeScript.LineMap(function () {
                return TypeScript.TextUtilities.parseLineStarts({ charCodeAt: function (index) {
                        return text.charCodeAt(index);
                    }, length: text.length() });
            }, text.length());
        }
        LineMap1.fromSimpleText = fromSimpleText;

        function fromScriptSnapshot(scriptSnapshot) {
            return new TypeScript.LineMap(function () {
                return scriptSnapshot.getLineStartPositions();
            }, scriptSnapshot.getLength());
        }
        LineMap1.fromScriptSnapshot = fromScriptSnapshot;

        function fromString(text) {
            return new TypeScript.LineMap(function () {
                return TypeScript.TextUtilities.parseLineStarts(text);
            }, text.length);
        }
        LineMap1.fromString = fromString;
    })(TypeScript.LineMap1 || (TypeScript.LineMap1 = {}));
    var LineMap1 = TypeScript.LineMap1;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (TextFactory) {
        function getStartAndLengthOfLineBreakEndingAt(text, index, info) {
            var c = text.charCodeAt(index);
            if (c === 10 /* lineFeed */) {
                if (index > 0 && text.charCodeAt(index - 1) === 13 /* carriageReturn */) {
                    info.startPosition = index - 1;
                    info.length = 2;
                } else {
                    info.startPosition = index;
                    info.length = 1;
                }
            } else if (TypeScript.TextUtilities.isAnyLineBreakCharacter(c)) {
                info.startPosition = index;
                info.length = 1;
            } else {
                info.startPosition = index + 1;
                info.length = 0;
            }
        }

        var LinebreakInfo = (function () {
            function LinebreakInfo(startPosition, length) {
                this.startPosition = startPosition;
                this.length = length;
            }
            return LinebreakInfo;
        })();

        var TextLine = (function () {
            function TextLine(text, body, lineBreakLength, lineNumber) {
                this._text = null;
                this._textSpan = null;
                if (text === null) {
                    throw TypeScript.Errors.argumentNull('text');
                }
                TypeScript.Debug.assert(lineBreakLength >= 0);
                TypeScript.Debug.assert(lineNumber >= 0);
                this._text = text;
                this._textSpan = body;
                this._lineBreakLength = lineBreakLength;
                this._lineNumber = lineNumber;
            }
            TextLine.prototype.start = function () {
                return this._textSpan.start();
            };

            TextLine.prototype.end = function () {
                return this._textSpan.end();
            };

            TextLine.prototype.endIncludingLineBreak = function () {
                return this.end() + this._lineBreakLength;
            };

            TextLine.prototype.extent = function () {
                return this._textSpan;
            };

            TextLine.prototype.extentIncludingLineBreak = function () {
                return TypeScript.TextSpan.fromBounds(this.start(), this.endIncludingLineBreak());
            };

            TextLine.prototype.toString = function () {
                return this._text.toString(this._textSpan);
            };

            TextLine.prototype.lineNumber = function () {
                return this._lineNumber;
            };
            return TextLine;
        })();

        var TextBase = (function () {
            function TextBase() {
                this.linebreakInfo = new LinebreakInfo(0, 0);
                this.lastLineFoundForPosition = null;
            }
            TextBase.prototype.length = function () {
                throw TypeScript.Errors.abstract();
            };

            TextBase.prototype.charCodeAt = function (position) {
                throw TypeScript.Errors.abstract();
            };

            TextBase.prototype.checkSubSpan = function (span) {
                if (span.start() < 0 || span.start() > this.length() || span.end() > this.length()) {
                    throw TypeScript.Errors.argumentOutOfRange("span");
                }
            };

            TextBase.prototype.toString = function (span) {
                if (typeof span === "undefined") { span = null; }
                throw TypeScript.Errors.abstract();
            };

            TextBase.prototype.subText = function (span) {
                this.checkSubSpan(span);

                return new SubText(this, span);
            };

            TextBase.prototype.substr = function (start, length, intern) {
                throw TypeScript.Errors.abstract();
            };

            TextBase.prototype.copyTo = function (sourceIndex, destination, destinationIndex, count) {
                throw TypeScript.Errors.abstract();
            };

            TextBase.prototype.lineCount = function () {
                return this._lineStarts().length;
            };

            TextBase.prototype.lines = function () {
                var lines = [];

                var length = this.lineCount();
                for (var i = 0; i < length; ++i) {
                    lines[i] = this.getLineFromLineNumber(i);
                }

                return lines;
            };

            TextBase.prototype.lineMap = function () {
                var _this = this;
                return new TypeScript.LineMap(function () {
                    return _this._lineStarts();
                }, this.length());
            };

            TextBase.prototype._lineStarts = function () {
                throw TypeScript.Errors.abstract();
            };

            TextBase.prototype.getLineFromLineNumber = function (lineNumber) {
                var lineStarts = this._lineStarts();

                if (lineNumber < 0 || lineNumber >= lineStarts.length) {
                    throw TypeScript.Errors.argumentOutOfRange("lineNumber");
                }

                var first = lineStarts[lineNumber];
                if (lineNumber === lineStarts.length - 1) {
                    return new TextLine(this, new TypeScript.TextSpan(first, this.length() - first), 0, lineNumber);
                } else {
                    getStartAndLengthOfLineBreakEndingAt(this, lineStarts[lineNumber + 1] - 1, this.linebreakInfo);
                    return new TextLine(this, new TypeScript.TextSpan(first, this.linebreakInfo.startPosition - first), this.linebreakInfo.length, lineNumber);
                }
            };

            TextBase.prototype.getLineFromPosition = function (position) {
                var lastFound = this.lastLineFoundForPosition;
                if (lastFound !== null && lastFound.start() <= position && lastFound.endIncludingLineBreak() > position) {
                    return lastFound;
                }

                var lineNumber = this.getLineNumberFromPosition(position);

                var result = this.getLineFromLineNumber(lineNumber);
                this.lastLineFoundForPosition = result;
                return result;
            };

            TextBase.prototype.getLineNumberFromPosition = function (position) {
                if (position < 0 || position > this.length()) {
                    throw TypeScript.Errors.argumentOutOfRange("position");
                }

                if (position === this.length()) {
                    return this.lineCount() - 1;
                }

                var lineNumber = TypeScript.ArrayUtilities.binarySearch(this._lineStarts(), position);
                if (lineNumber < 0) {
                    lineNumber = (~lineNumber) - 1;
                }

                return lineNumber;
            };

            TextBase.prototype.getLinePosition = function (position) {
                if (position < 0 || position > this.length()) {
                    throw TypeScript.Errors.argumentOutOfRange("position");
                }

                var lineNumber = this.getLineNumberFromPosition(position);

                return new TypeScript.LineAndCharacter(lineNumber, position - this._lineStarts()[lineNumber]);
            };
            return TextBase;
        })();

        var SubText = (function (_super) {
            __extends(SubText, _super);
            function SubText(text, span) {
                _super.call(this);
                this._lazyLineStarts = null;

                if (text === null) {
                    throw TypeScript.Errors.argumentNull("text");
                }

                if (span.start() < 0 || span.start() >= text.length() || span.end() < 0 || span.end() > text.length()) {
                    throw TypeScript.Errors.argument("span");
                }

                this.text = text;
                this.span = span;
            }
            SubText.prototype.length = function () {
                return this.span.length();
            };

            SubText.prototype.charCodeAt = function (position) {
                if (position < 0 || position > this.length()) {
                    throw TypeScript.Errors.argumentOutOfRange("position");
                }

                return this.text.charCodeAt(this.span.start() + position);
            };

            SubText.prototype.subText = function (span) {
                this.checkSubSpan(span);

                return new SubText(this.text, this.getCompositeSpan(span.start(), span.length()));
            };

            SubText.prototype.copyTo = function (sourceIndex, destination, destinationIndex, count) {
                var span = this.getCompositeSpan(sourceIndex, count);
                this.text.copyTo(span.start(), destination, destinationIndex, span.length());
            };

            SubText.prototype.substr = function (start, length, intern) {
                var startInOriginalText = this.span.start() + start;
                return this.text.substr(startInOriginalText, length, intern);
            };

            SubText.prototype.getCompositeSpan = function (start, length) {
                var compositeStart = TypeScript.MathPrototype.min(this.text.length(), this.span.start() + start);
                var compositeEnd = TypeScript.MathPrototype.min(this.text.length(), compositeStart + length);
                return new TypeScript.TextSpan(compositeStart, compositeEnd - compositeStart);
            };

            SubText.prototype._lineStarts = function () {
                var _this = this;
                if (!this._lazyLineStarts) {
                    this._lazyLineStarts = TypeScript.TextUtilities.parseLineStarts({ charCodeAt: function (index) {
                            return _this.charCodeAt(index);
                        }, length: this.length() });
                }

                return this._lazyLineStarts;
            };
            return SubText;
        })(TextBase);

        var StringText = (function (_super) {
            __extends(StringText, _super);
            function StringText(data) {
                _super.call(this);
                this.source = null;
                this._lazyLineStarts = null;

                if (data === null) {
                    throw TypeScript.Errors.argumentNull("data");
                }

                this.source = data;
            }
            StringText.prototype.length = function () {
                return this.source.length;
            };

            StringText.prototype.charCodeAt = function (position) {
                if (position < 0 || position >= this.source.length) {
                    throw TypeScript.Errors.argumentOutOfRange("position");
                }

                return this.source.charCodeAt(position);
            };

            StringText.prototype.substr = function (start, length, intern) {
                return this.source.substr(start, length);
            };

            StringText.prototype.toString = function (span) {
                if (typeof span === "undefined") { span = null; }
                if (span === null) {
                    span = new TypeScript.TextSpan(0, this.length());
                }

                this.checkSubSpan(span);

                if (span.start() === 0 && span.length() === this.length()) {
                    return this.source;
                }

                return this.source.substr(span.start(), span.length());
            };

            StringText.prototype.copyTo = function (sourceIndex, destination, destinationIndex, count) {
                TypeScript.StringUtilities.copyTo(this.source, sourceIndex, destination, destinationIndex, count);
            };

            StringText.prototype._lineStarts = function () {
                if (this._lazyLineStarts === null) {
                    this._lazyLineStarts = TypeScript.TextUtilities.parseLineStarts(this.source);
                }

                return this._lazyLineStarts;
            };
            return StringText;
        })(TextBase);

        function createText(value) {
            return new StringText(value);
        }
        TextFactory.createText = createText;
    })(TypeScript.TextFactory || (TypeScript.TextFactory = {}));
    var TextFactory = TypeScript.TextFactory;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (SimpleText) {
        var SimpleSubText = (function () {
            function SimpleSubText(text, span) {
                this.text = null;
                this.span = null;
                if (text === null) {
                    throw TypeScript.Errors.argumentNull("text");
                }

                if (span.start() < 0 || span.start() >= text.length() || span.end() < 0 || span.end() > text.length()) {
                    throw TypeScript.Errors.argument("span");
                }

                this.text = text;
                this.span = span;
            }
            SimpleSubText.prototype.checkSubSpan = function (span) {
                if (span.start() < 0 || span.start() > this.length() || span.end() > this.length()) {
                    throw TypeScript.Errors.argumentOutOfRange("span");
                }
            };

            SimpleSubText.prototype.checkSubPosition = function (position) {
                if (position < 0 || position >= this.length()) {
                    throw TypeScript.Errors.argumentOutOfRange("position");
                }
            };

            SimpleSubText.prototype.length = function () {
                return this.span.length();
            };

            SimpleSubText.prototype.subText = function (span) {
                this.checkSubSpan(span);

                return new SimpleSubText(this.text, this.getCompositeSpan(span.start(), span.length()));
            };

            SimpleSubText.prototype.copyTo = function (sourceIndex, destination, destinationIndex, count) {
                var span = this.getCompositeSpan(sourceIndex, count);
                this.text.copyTo(span.start(), destination, destinationIndex, span.length());
            };

            SimpleSubText.prototype.substr = function (start, length, intern) {
                var span = this.getCompositeSpan(start, length);
                return this.text.substr(span.start(), span.length(), intern);
            };

            SimpleSubText.prototype.getCompositeSpan = function (start, length) {
                var compositeStart = TypeScript.MathPrototype.min(this.text.length(), this.span.start() + start);
                var compositeEnd = TypeScript.MathPrototype.min(this.text.length(), compositeStart + length);
                return new TypeScript.TextSpan(compositeStart, compositeEnd - compositeStart);
            };

            SimpleSubText.prototype.charCodeAt = function (index) {
                this.checkSubPosition(index);
                return this.text.charCodeAt(this.span.start() + index);
            };

            SimpleSubText.prototype.lineMap = function () {
                return TypeScript.LineMap1.fromSimpleText(this);
            };
            return SimpleSubText;
        })();

        var SimpleStringText = (function () {
            function SimpleStringText(value) {
                this.value = value;
                this._lineMap = null;
            }
            SimpleStringText.prototype.length = function () {
                return this.value.length;
            };

            SimpleStringText.prototype.copyTo = function (sourceIndex, destination, destinationIndex, count) {
                TypeScript.StringUtilities.copyTo(this.value, sourceIndex, destination, destinationIndex, count);
            };

            SimpleStringText.prototype.substr = function (start, length, intern) {
                if (intern) {
                    var array = length <= SimpleStringText.charArray.length ? SimpleStringText.charArray : TypeScript.ArrayUtilities.createArray(length, 0);
                    this.copyTo(start, array, 0, length);
                    return TypeScript.Collections.DefaultStringTable.addCharArray(array, 0, length);
                }

                return this.value.substr(start, length);
            };

            SimpleStringText.prototype.subText = function (span) {
                return new SimpleSubText(this, span);
            };

            SimpleStringText.prototype.charCodeAt = function (index) {
                return this.value.charCodeAt(index);
            };

            SimpleStringText.prototype.lineMap = function () {
                if (!this._lineMap) {
                    this._lineMap = TypeScript.LineMap1.fromString(this.value);
                }

                return this._lineMap;
            };
            SimpleStringText.charArray = TypeScript.ArrayUtilities.createArray(1024, 0);
            return SimpleStringText;
        })();

        var SimpleScriptSnapshotText = (function () {
            function SimpleScriptSnapshotText(scriptSnapshot) {
                this.scriptSnapshot = scriptSnapshot;
            }
            SimpleScriptSnapshotText.prototype.charCodeAt = function (index) {
                return this.scriptSnapshot.getText(index, index + 1).charCodeAt(0);
            };

            SimpleScriptSnapshotText.prototype.length = function () {
                return this.scriptSnapshot.getLength();
            };

            SimpleScriptSnapshotText.prototype.copyTo = function (sourceIndex, destination, destinationIndex, count) {
                var text = this.scriptSnapshot.getText(sourceIndex, sourceIndex + count);
                TypeScript.StringUtilities.copyTo(text, 0, destination, destinationIndex, count);
            };

            SimpleScriptSnapshotText.prototype.substr = function (start, length, intern) {
                return this.scriptSnapshot.getText(start, start + length);
            };

            SimpleScriptSnapshotText.prototype.subText = function (span) {
                return new SimpleSubText(this, span);
            };

            SimpleScriptSnapshotText.prototype.lineMap = function () {
                var _this = this;
                return new TypeScript.LineMap(function () {
                    return _this.scriptSnapshot.getLineStartPositions();
                }, this.length());
            };
            return SimpleScriptSnapshotText;
        })();

        function fromString(value) {
            return new SimpleStringText(value);
        }
        SimpleText.fromString = fromString;

        function fromScriptSnapshot(scriptSnapshot) {
            return new SimpleScriptSnapshotText(scriptSnapshot);
        }
        SimpleText.fromScriptSnapshot = fromScriptSnapshot;
    })(TypeScript.SimpleText || (TypeScript.SimpleText = {}));
    var SimpleText = TypeScript.SimpleText;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (TextUtilities) {
        function parseLineStarts(text) {
            var length = text.length;

            if (0 === length) {
                var result = new Array();
                result.push(0);
                return result;
            }

            var position = 0;
            var index = 0;
            var arrayBuilder = new Array();
            var lineNumber = 0;

            while (index < length) {
                var c = text.charCodeAt(index);
                var lineBreakLength;

                if (c > 13 /* carriageReturn */ && c <= 127) {
                    index++;
                    continue;
                } else if (c === 13 /* carriageReturn */ && index + 1 < length && text.charCodeAt(index + 1) === 10 /* lineFeed */) {
                    lineBreakLength = 2;
                } else if (c === 10 /* lineFeed */) {
                    lineBreakLength = 1;
                } else {
                    lineBreakLength = TextUtilities.getLengthOfLineBreak(text, index);
                }

                if (0 === lineBreakLength) {
                    index++;
                } else {
                    arrayBuilder.push(position);
                    index += lineBreakLength;
                    position = index;
                    lineNumber++;
                }
            }

            arrayBuilder.push(position);

            return arrayBuilder;
        }
        TextUtilities.parseLineStarts = parseLineStarts;

        function getLengthOfLineBreakSlow(text, index, c) {
            if (c === 13 /* carriageReturn */) {
                var next = index + 1;
                return (next < text.length) && 10 /* lineFeed */ === text.charCodeAt(next) ? 2 : 1;
            } else if (isAnyLineBreakCharacter(c)) {
                return 1;
            } else {
                return 0;
            }
        }
        TextUtilities.getLengthOfLineBreakSlow = getLengthOfLineBreakSlow;

        function getLengthOfLineBreak(text, index) {
            var c = text.charCodeAt(index);

            if (c > 13 /* carriageReturn */ && c <= 127) {
                return 0;
            }

            return getLengthOfLineBreakSlow(text, index, c);
        }
        TextUtilities.getLengthOfLineBreak = getLengthOfLineBreak;

        function isAnyLineBreakCharacter(c) {
            return c === 10 /* lineFeed */ || c === 13 /* carriageReturn */ || c === 133 /* nextLine */ || c === 8232 /* lineSeparator */ || c === 8233 /* paragraphSeparator */;
        }
        TextUtilities.isAnyLineBreakCharacter = isAnyLineBreakCharacter;
    })(TypeScript.TextUtilities || (TypeScript.TextUtilities = {}));
    var TextUtilities = TypeScript.TextUtilities;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var TextSpan = (function () {
        function TextSpan(start, length) {
            if (start < 0) {
                TypeScript.Errors.argument("start");
            }

            if (length < 0) {
                TypeScript.Errors.argument("length");
            }

            this._start = start;
            this._length = length;
        }
        TextSpan.prototype.start = function () {
            return this._start;
        };

        TextSpan.prototype.length = function () {
            return this._length;
        };

        TextSpan.prototype.end = function () {
            return this._start + this._length;
        };

        TextSpan.prototype.isEmpty = function () {
            return this._length === 0;
        };

        TextSpan.prototype.containsPosition = function (position) {
            return position >= this._start && position < this.end();
        };

        TextSpan.prototype.containsTextSpan = function (span) {
            return span._start >= this._start && span.end() <= this.end();
        };

        TextSpan.prototype.overlapsWith = function (span) {
            var overlapStart = TypeScript.MathPrototype.max(this._start, span._start);
            var overlapEnd = TypeScript.MathPrototype.min(this.end(), span.end());

            return overlapStart < overlapEnd;
        };

        TextSpan.prototype.overlap = function (span) {
            var overlapStart = TypeScript.MathPrototype.max(this._start, span._start);
            var overlapEnd = TypeScript.MathPrototype.min(this.end(), span.end());

            if (overlapStart < overlapEnd) {
                return TextSpan.fromBounds(overlapStart, overlapEnd);
            }

            return null;
        };

        TextSpan.prototype.intersectsWithTextSpan = function (span) {
            return span._start <= this.end() && span.end() >= this._start;
        };

        TextSpan.prototype.intersectsWith = function (start, length) {
            var end = start + length;
            return start <= this.end() && end >= this._start;
        };

        TextSpan.prototype.intersectsWithPosition = function (position) {
            return position <= this.end() && position >= this._start;
        };

        TextSpan.prototype.intersection = function (span) {
            var intersectStart = TypeScript.MathPrototype.max(this._start, span._start);
            var intersectEnd = TypeScript.MathPrototype.min(this.end(), span.end());

            if (intersectStart <= intersectEnd) {
                return TextSpan.fromBounds(intersectStart, intersectEnd);
            }

            return null;
        };

        TextSpan.fromBounds = function (start, end) {
            TypeScript.Debug.assert(start >= 0);
            TypeScript.Debug.assert(end - start >= 0);
            return new TextSpan(start, end - start);
        };
        return TextSpan;
    })();
    TypeScript.TextSpan = TextSpan;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var TextChangeRange = (function () {
        function TextChangeRange(span, newLength) {
            if (newLength < 0) {
                throw TypeScript.Errors.argumentOutOfRange("newLength");
            }

            this._span = span;
            this._newLength = newLength;
        }
        TextChangeRange.prototype.span = function () {
            return this._span;
        };

        TextChangeRange.prototype.newLength = function () {
            return this._newLength;
        };

        TextChangeRange.prototype.newSpan = function () {
            return new TypeScript.TextSpan(this.span().start(), this.newLength());
        };

        TextChangeRange.prototype.isUnchanged = function () {
            return this.span().isEmpty() && this.newLength() === 0;
        };

        TextChangeRange.collapseChangesFromSingleVersion = function (changes) {
            var diff = 0;
            var start = 1073741823 /* Max31BitInteger */;
            var end = 0;

            for (var i = 0; i < changes.length; i++) {
                var change = changes[i];
                diff += change.newLength() - change.span().length();

                if (change.span().start() < start) {
                    start = change.span().start();
                }

                if (change.span().end() > end) {
                    end = change.span().end();
                }
            }

            if (start > end) {
                return null;
            }

            var combined = TypeScript.TextSpan.fromBounds(start, end);
            var newLen = combined.length() + diff;

            return new TextChangeRange(combined, newLen);
        };

        TextChangeRange.collapseChangesAcrossMultipleVersions = function (changes) {
            if (changes.length === 0) {
                return TextChangeRange.unchanged;
            }

            if (changes.length === 1) {
                return changes[0];
            }

            var change0 = changes[0];

            var oldStartN = change0.span().start();
            var oldEndN = change0.span().end();
            var newEndN = oldStartN + change0.newLength();

            for (var i = 1; i < changes.length; i++) {
                var nextChange = changes[i];

                var oldStart1 = oldStartN;
                var oldEnd1 = oldEndN;
                var newEnd1 = newEndN;

                var oldStart2 = nextChange.span().start();
                var oldEnd2 = nextChange.span().end();
                var newEnd2 = oldStart2 + nextChange.newLength();

                oldStartN = TypeScript.MathPrototype.min(oldStart1, oldStart2);
                oldEndN = TypeScript.MathPrototype.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
                newEndN = TypeScript.MathPrototype.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
            }

            return new TextChangeRange(TypeScript.TextSpan.fromBounds(oldStartN, oldEndN), newEndN - oldStartN);
        };
        TextChangeRange.unchanged = new TextChangeRange(new TypeScript.TextSpan(0, 0), 0);
        return TextChangeRange;
    })();
    TypeScript.TextChangeRange = TextChangeRange;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var CharacterInfo = (function () {
        function CharacterInfo() {
        }
        CharacterInfo.isDecimalDigit = function (c) {
            return c >= 48 /* _0 */ && c <= 57 /* _9 */;
        };
        CharacterInfo.isOctalDigit = function (c) {
            return c >= 48 /* _0 */ && c <= 55 /* _7 */;
        };

        CharacterInfo.isHexDigit = function (c) {
            return CharacterInfo.isDecimalDigit(c) || (c >= 65 /* A */ && c <= 70 /* F */) || (c >= 97 /* a */ && c <= 102 /* f */);
        };

        CharacterInfo.hexValue = function (c) {
            return CharacterInfo.isDecimalDigit(c) ? (c - 48 /* _0 */) : (c >= 65 /* A */ && c <= 70 /* F */) ? c - 65 /* A */ + 10 : c - 97 /* a */ + 10;
        };

        CharacterInfo.isWhitespace = function (ch) {
            switch (ch) {
                case 32 /* space */:
                case 160 /* nonBreakingSpace */:
                case 8192 /* enQuad */:
                case 8193 /* emQuad */:
                case 8194 /* enSpace */:
                case 8195 /* emSpace */:
                case 8196 /* threePerEmSpace */:
                case 8197 /* fourPerEmSpace */:
                case 8198 /* sixPerEmSpace */:
                case 8199 /* figureSpace */:
                case 8200 /* punctuationSpace */:
                case 8201 /* thinSpace */:
                case 8202 /* hairSpace */:
                case 8203 /* zeroWidthSpace */:
                case 8239 /* narrowNoBreakSpace */:
                case 12288 /* ideographicSpace */:

                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 65279 /* byteOrderMark */:
                    return true;
            }

            return false;
        };

        CharacterInfo.isLineTerminator = function (ch) {
            switch (ch) {
                case 13 /* carriageReturn */:
                case 10 /* lineFeed */:
                case 8233 /* paragraphSeparator */:
                case 8232 /* lineSeparator */:
                    return true;
            }

            return false;
        };
        return CharacterInfo;
    })();
    TypeScript.CharacterInfo = CharacterInfo;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (SyntaxConstants) {
        SyntaxConstants[SyntaxConstants["TriviaNewLineMask"] = 0x00000001] = "TriviaNewLineMask";
        SyntaxConstants[SyntaxConstants["TriviaCommentMask"] = 0x00000002] = "TriviaCommentMask";
        SyntaxConstants[SyntaxConstants["TriviaFullWidthShift"] = 2] = "TriviaFullWidthShift";

        SyntaxConstants[SyntaxConstants["NodeDataComputed"] = 0x00000001] = "NodeDataComputed";
        SyntaxConstants[SyntaxConstants["NodeIncrementallyUnusableMask"] = 0x00000002] = "NodeIncrementallyUnusableMask";
        SyntaxConstants[SyntaxConstants["NodeParsedInStrictModeMask"] = 0x00000004] = "NodeParsedInStrictModeMask";
        SyntaxConstants[SyntaxConstants["NodeFullWidthShift"] = 3] = "NodeFullWidthShift";

        SyntaxConstants[SyntaxConstants["IsVariableWidthKeyword"] = 1 << 31] = "IsVariableWidthKeyword";
    })(TypeScript.SyntaxConstants || (TypeScript.SyntaxConstants = {}));
    var SyntaxConstants = TypeScript.SyntaxConstants;
})(TypeScript || (TypeScript = {}));
var FormattingOptions = (function () {
    function FormattingOptions(useTabs, spacesPerTab, indentSpaces, newLineCharacter) {
        this.useTabs = useTabs;
        this.spacesPerTab = spacesPerTab;
        this.indentSpaces = indentSpaces;
        this.newLineCharacter = newLineCharacter;
    }
    FormattingOptions.defaultOptions = new FormattingOptions(false, 4, 4, "\r\n");
    return FormattingOptions;
})();
var TypeScript;
(function (TypeScript) {
    (function (Indentation) {
        function columnForEndOfToken(token, syntaxInformationMap, options) {
            return columnForStartOfToken(token, syntaxInformationMap, options) + token.width();
        }
        Indentation.columnForEndOfToken = columnForEndOfToken;

        function columnForStartOfToken(token, syntaxInformationMap, options) {
            var firstTokenInLine = syntaxInformationMap.firstTokenInLineContainingToken(token);
            var leadingTextInReverse = [];

            var current = token;
            while (current !== firstTokenInLine) {
                current = syntaxInformationMap.previousToken(current);

                if (current === firstTokenInLine) {
                    leadingTextInReverse.push(current.trailingTrivia().fullText());
                    leadingTextInReverse.push(current.text());
                } else {
                    leadingTextInReverse.push(current.fullText());
                }
            }

            collectLeadingTriviaTextToStartOfLine(firstTokenInLine, leadingTextInReverse);

            return columnForLeadingTextInReverse(leadingTextInReverse, options);
        }
        Indentation.columnForStartOfToken = columnForStartOfToken;

        function columnForStartOfFirstTokenInLineContainingToken(token, syntaxInformationMap, options) {
            var firstTokenInLine = syntaxInformationMap.firstTokenInLineContainingToken(token);
            var leadingTextInReverse = [];

            collectLeadingTriviaTextToStartOfLine(firstTokenInLine, leadingTextInReverse);

            return columnForLeadingTextInReverse(leadingTextInReverse, options);
        }
        Indentation.columnForStartOfFirstTokenInLineContainingToken = columnForStartOfFirstTokenInLineContainingToken;

        function collectLeadingTriviaTextToStartOfLine(firstTokenInLine, leadingTextInReverse) {
            var leadingTrivia = firstTokenInLine.leadingTrivia();

            for (var i = leadingTrivia.count() - 1; i >= 0; i--) {
                var trivia = leadingTrivia.syntaxTriviaAt(i);
                if (trivia.kind() === 5 /* NewLineTrivia */) {
                    break;
                }

                if (trivia.kind() === 6 /* MultiLineCommentTrivia */) {
                    var lineSegments = TypeScript.Syntax.splitMultiLineCommentTriviaIntoMultipleLines(trivia);
                    leadingTextInReverse.push(TypeScript.ArrayUtilities.last(lineSegments));

                    if (lineSegments.length > 0) {
                        break;
                    }
                }

                leadingTextInReverse.push(trivia.fullText());
            }
        }

        function columnForLeadingTextInReverse(leadingTextInReverse, options) {
            var column = 0;

            for (var i = leadingTextInReverse.length - 1; i >= 0; i--) {
                var text = leadingTextInReverse[i];
                column = columnForPositionInStringWorker(text, text.length, column, options);
            }

            return column;
        }

        function columnForPositionInString(input, position, options) {
            return columnForPositionInStringWorker(input, position, 0, options);
        }
        Indentation.columnForPositionInString = columnForPositionInString;

        function columnForPositionInStringWorker(input, position, startColumn, options) {
            var column = startColumn;
            var spacesPerTab = options.spacesPerTab;

            for (var j = 0; j < position; j++) {
                var ch = input.charCodeAt(j);

                if (ch === 9 /* tab */) {
                    column += spacesPerTab - column % spacesPerTab;
                } else {
                    column++;
                }
            }

            return column;
        }

        function indentationString(column, options) {
            var numberOfTabs = 0;
            var numberOfSpaces = TypeScript.MathPrototype.max(0, column);

            if (options.useTabs) {
                numberOfTabs = Math.floor(column / options.spacesPerTab);
                numberOfSpaces -= numberOfTabs * options.spacesPerTab;
            }

            return TypeScript.StringUtilities.repeat('\t', numberOfTabs) + TypeScript.StringUtilities.repeat(' ', numberOfSpaces);
        }
        Indentation.indentationString = indentationString;

        function indentationTrivia(column, options) {
            return TypeScript.Syntax.whitespace(this.indentationString(column, options));
        }
        Indentation.indentationTrivia = indentationTrivia;

        function firstNonWhitespacePosition(value) {
            for (var i = 0; i < value.length; i++) {
                var ch = value.charCodeAt(i);
                if (!TypeScript.CharacterInfo.isWhitespace(ch)) {
                    return i;
                }
            }

            return value.length;
        }
        Indentation.firstNonWhitespacePosition = firstNonWhitespacePosition;
    })(TypeScript.Indentation || (TypeScript.Indentation = {}));
    var Indentation = TypeScript.Indentation;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (LanguageVersion) {
        LanguageVersion[LanguageVersion["EcmaScript3"] = 0] = "EcmaScript3";
        LanguageVersion[LanguageVersion["EcmaScript5"] = 1] = "EcmaScript5";
    })(TypeScript.LanguageVersion || (TypeScript.LanguageVersion = {}));
    var LanguageVersion = TypeScript.LanguageVersion;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var ParseOptions = (function () {
        function ParseOptions(languageVersion, allowAutomaticSemicolonInsertion) {
            this._languageVersion = languageVersion;
            this._allowAutomaticSemicolonInsertion = allowAutomaticSemicolonInsertion;
        }
        ParseOptions.prototype.toJSON = function (key) {
            return { allowAutomaticSemicolonInsertion: this._allowAutomaticSemicolonInsertion };
        };

        ParseOptions.prototype.languageVersion = function () {
            return this._languageVersion;
        };

        ParseOptions.prototype.allowAutomaticSemicolonInsertion = function () {
            return this._allowAutomaticSemicolonInsertion;
        };
        return ParseOptions;
    })();
    TypeScript.ParseOptions = ParseOptions;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var PositionedElement = (function () {
        function PositionedElement(parent, element, fullStart) {
            this._parent = parent;
            this._element = element;
            this._fullStart = fullStart;
        }
        PositionedElement.create = function (parent, element, fullStart) {
            if (element === null) {
                return null;
            }

            if (element.isNode()) {
                return new PositionedNode(parent, element, fullStart);
            } else if (element.isToken()) {
                return new PositionedToken(parent, element, fullStart);
            } else if (element.isList()) {
                return new PositionedList(parent, element, fullStart);
            } else if (element.isSeparatedList()) {
                return new PositionedSeparatedList(parent, element, fullStart);
            } else {
                throw TypeScript.Errors.invalidOperation();
            }
        };

        PositionedElement.prototype.parent = function () {
            return this._parent;
        };

        PositionedElement.prototype.parentElement = function () {
            return this._parent && this._parent._element;
        };

        PositionedElement.prototype.element = function () {
            return this._element;
        };

        PositionedElement.prototype.kind = function () {
            return this.element().kind();
        };

        PositionedElement.prototype.childIndex = function (child) {
            return TypeScript.Syntax.childIndex(this.element(), child);
        };

        PositionedElement.prototype.childCount = function () {
            return this.element().childCount();
        };

        PositionedElement.prototype.childAt = function (index) {
            var offset = TypeScript.Syntax.childOffsetAt(this.element(), index);
            return PositionedElement.create(this, this.element().childAt(index), this.fullStart() + offset);
        };

        PositionedElement.prototype.childStart = function (child) {
            var offset = TypeScript.Syntax.childOffset(this.element(), child);
            return this.fullStart() + offset + child.leadingTriviaWidth();
        };

        PositionedElement.prototype.childEnd = function (child) {
            var offset = TypeScript.Syntax.childOffset(this.element(), child);
            return this.fullStart() + offset + child.leadingTriviaWidth() + child.width();
        };

        PositionedElement.prototype.childStartAt = function (index) {
            var offset = TypeScript.Syntax.childOffsetAt(this.element(), index);
            var child = this.element().childAt(index);
            return this.fullStart() + offset + child.leadingTriviaWidth();
        };

        PositionedElement.prototype.childEndAt = function (index) {
            var offset = TypeScript.Syntax.childOffsetAt(this.element(), index);
            var child = this.element().childAt(index);
            return this.fullStart() + offset + child.leadingTriviaWidth() + child.width();
        };

        PositionedElement.prototype.getPositionedChild = function (child) {
            var offset = TypeScript.Syntax.childOffset(this.element(), child);
            return PositionedElement.create(this, child, this.fullStart() + offset);
        };

        PositionedElement.prototype.fullStart = function () {
            return this._fullStart;
        };

        PositionedElement.prototype.fullEnd = function () {
            return this.fullStart() + this.element().fullWidth();
        };

        PositionedElement.prototype.fullWidth = function () {
            return this.element().fullWidth();
        };

        PositionedElement.prototype.start = function () {
            return this.fullStart() + this.element().leadingTriviaWidth();
        };

        PositionedElement.prototype.end = function () {
            return this.fullStart() + this.element().leadingTriviaWidth() + this.element().width();
        };

        PositionedElement.prototype.root = function () {
            var current = this;
            while (current.parent() !== null) {
                current = current.parent();
            }

            return current;
        };

        PositionedElement.prototype.containingNode = function () {
            var current = this.parent();

            while (current !== null && !current.element().isNode()) {
                current = current.parent();
            }

            return current;
        };
        return PositionedElement;
    })();
    TypeScript.PositionedElement = PositionedElement;

    var PositionedNodeOrToken = (function (_super) {
        __extends(PositionedNodeOrToken, _super);
        function PositionedNodeOrToken(parent, nodeOrToken, fullStart) {
            _super.call(this, parent, nodeOrToken, fullStart);
        }
        PositionedNodeOrToken.prototype.nodeOrToken = function () {
            return this.element();
        };
        return PositionedNodeOrToken;
    })(PositionedElement);
    TypeScript.PositionedNodeOrToken = PositionedNodeOrToken;

    var PositionedNode = (function (_super) {
        __extends(PositionedNode, _super);
        function PositionedNode(parent, node, fullStart) {
            _super.call(this, parent, node, fullStart);
        }
        PositionedNode.prototype.node = function () {
            return this.element();
        };
        return PositionedNode;
    })(PositionedNodeOrToken);
    TypeScript.PositionedNode = PositionedNode;

    var PositionedToken = (function (_super) {
        __extends(PositionedToken, _super);
        function PositionedToken(parent, token, fullStart) {
            _super.call(this, parent, token, fullStart);
        }
        PositionedToken.prototype.token = function () {
            return this.element();
        };

        PositionedToken.prototype.previousToken = function (includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            var triviaList = this.token().leadingTrivia();
            if (includeSkippedTokens && triviaList && triviaList.hasSkippedToken()) {
                var currentTriviaEndPosition = this.start();
                for (var i = triviaList.count() - 1; i >= 0; i--) {
                    var trivia = triviaList.syntaxTriviaAt(i);
                    if (trivia.isSkippedToken()) {
                        return new PositionedSkippedToken(this, trivia.skippedToken(), currentTriviaEndPosition - trivia.fullWidth());
                    }

                    currentTriviaEndPosition -= trivia.fullWidth();
                }
            }

            var start = this.fullStart();
            if (start === 0) {
                return null;
            }

            return this.root().node().findToken(start - 1, includeSkippedTokens);
        };

        PositionedToken.prototype.nextToken = function (includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            if (this.token().tokenKind === 10 /* EndOfFileToken */) {
                return null;
            }

            var triviaList = this.token().trailingTrivia();
            if (includeSkippedTokens && triviaList && triviaList.hasSkippedToken()) {
                var fullStart = this.end();
                for (var i = 0, n = triviaList.count(); i < n; i++) {
                    var trivia = triviaList.syntaxTriviaAt(i);
                    if (trivia.isSkippedToken()) {
                        return new PositionedSkippedToken(this, trivia.skippedToken(), fullStart);
                    }

                    fullStart += trivia.fullWidth();
                }
            }

            return this.root().node().findToken(this.fullEnd(), includeSkippedTokens);
        };
        return PositionedToken;
    })(PositionedNodeOrToken);
    TypeScript.PositionedToken = PositionedToken;

    var PositionedList = (function (_super) {
        __extends(PositionedList, _super);
        function PositionedList(parent, list, fullStart) {
            _super.call(this, parent, list, fullStart);
        }
        PositionedList.prototype.list = function () {
            return this.element();
        };
        return PositionedList;
    })(PositionedElement);
    TypeScript.PositionedList = PositionedList;

    var PositionedSeparatedList = (function (_super) {
        __extends(PositionedSeparatedList, _super);
        function PositionedSeparatedList(parent, list, fullStart) {
            _super.call(this, parent, list, fullStart);
        }
        PositionedSeparatedList.prototype.list = function () {
            return this.element();
        };
        return PositionedSeparatedList;
    })(PositionedElement);
    TypeScript.PositionedSeparatedList = PositionedSeparatedList;

    var PositionedSkippedToken = (function (_super) {
        __extends(PositionedSkippedToken, _super);
        function PositionedSkippedToken(parentToken, token, fullStart) {
            _super.call(this, parentToken.parent(), token, fullStart);
            this._parentToken = parentToken;
        }
        PositionedSkippedToken.prototype.parentToken = function () {
            return this._parentToken;
        };

        PositionedSkippedToken.prototype.previousToken = function (includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            var start = this.fullStart();

            if (includeSkippedTokens) {
                var previousToken;

                if (start >= this.parentToken().end()) {
                    previousToken = TypeScript.Syntax.findSkippedTokenInTrailingTriviaList(this.parentToken(), start - 1);

                    if (previousToken) {
                        return previousToken;
                    }

                    return this.parentToken();
                } else {
                    previousToken = TypeScript.Syntax.findSkippedTokenInLeadingTriviaList(this.parentToken(), start - 1);

                    if (previousToken) {
                        return previousToken;
                    }
                }
            }

            var start = this.parentToken().fullStart();
            if (start === 0) {
                return null;
            }

            return this.root().node().findToken(start - 1, includeSkippedTokens);
        };

        PositionedSkippedToken.prototype.nextToken = function (includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            if (this.token().tokenKind === 10 /* EndOfFileToken */) {
                return null;
            }

            if (includeSkippedTokens) {
                var end = this.end();
                var nextToken;

                if (end <= this.parentToken().start()) {
                    nextToken = TypeScript.Syntax.findSkippedTokenInLeadingTriviaList(this.parentToken(), end);

                    if (nextToken) {
                        return nextToken;
                    }

                    return this.parentToken();
                } else {
                    nextToken = TypeScript.Syntax.findSkippedTokenInTrailingTriviaList(this.parentToken(), end);

                    if (nextToken) {
                        return nextToken;
                    }
                }
            }

            return this.root().node().findToken(this.parentToken().fullEnd(), includeSkippedTokens);
        };
        return PositionedSkippedToken;
    })(PositionedToken);
    TypeScript.PositionedSkippedToken = PositionedSkippedToken;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (SyntaxKind) {
        SyntaxKind[SyntaxKind["None"] = 0] = "None";
        SyntaxKind[SyntaxKind["List"] = 1] = "List";
        SyntaxKind[SyntaxKind["SeparatedList"] = 2] = "SeparatedList";
        SyntaxKind[SyntaxKind["TriviaList"] = 3] = "TriviaList";

        SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 4] = "WhitespaceTrivia";
        SyntaxKind[SyntaxKind["NewLineTrivia"] = 5] = "NewLineTrivia";
        SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 6] = "MultiLineCommentTrivia";
        SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 7] = "SingleLineCommentTrivia";
        SyntaxKind[SyntaxKind["SkippedTokenTrivia"] = 8] = "SkippedTokenTrivia";

        SyntaxKind[SyntaxKind["ErrorToken"] = 9] = "ErrorToken";
        SyntaxKind[SyntaxKind["EndOfFileToken"] = 10] = "EndOfFileToken";

        SyntaxKind[SyntaxKind["IdentifierName"] = 11] = "IdentifierName";

        SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 12] = "RegularExpressionLiteral";
        SyntaxKind[SyntaxKind["NumericLiteral"] = 13] = "NumericLiteral";
        SyntaxKind[SyntaxKind["StringLiteral"] = 14] = "StringLiteral";

        SyntaxKind[SyntaxKind["BreakKeyword"] = 15] = "BreakKeyword";
        SyntaxKind[SyntaxKind["CaseKeyword"] = 16] = "CaseKeyword";
        SyntaxKind[SyntaxKind["CatchKeyword"] = 17] = "CatchKeyword";
        SyntaxKind[SyntaxKind["ContinueKeyword"] = 18] = "ContinueKeyword";
        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 19] = "DebuggerKeyword";
        SyntaxKind[SyntaxKind["DefaultKeyword"] = 20] = "DefaultKeyword";
        SyntaxKind[SyntaxKind["DeleteKeyword"] = 21] = "DeleteKeyword";
        SyntaxKind[SyntaxKind["DoKeyword"] = 22] = "DoKeyword";
        SyntaxKind[SyntaxKind["ElseKeyword"] = 23] = "ElseKeyword";
        SyntaxKind[SyntaxKind["FalseKeyword"] = 24] = "FalseKeyword";
        SyntaxKind[SyntaxKind["FinallyKeyword"] = 25] = "FinallyKeyword";
        SyntaxKind[SyntaxKind["ForKeyword"] = 26] = "ForKeyword";
        SyntaxKind[SyntaxKind["FunctionKeyword"] = 27] = "FunctionKeyword";
        SyntaxKind[SyntaxKind["IfKeyword"] = 28] = "IfKeyword";
        SyntaxKind[SyntaxKind["InKeyword"] = 29] = "InKeyword";
        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 30] = "InstanceOfKeyword";
        SyntaxKind[SyntaxKind["NewKeyword"] = 31] = "NewKeyword";
        SyntaxKind[SyntaxKind["NullKeyword"] = 32] = "NullKeyword";
        SyntaxKind[SyntaxKind["ReturnKeyword"] = 33] = "ReturnKeyword";
        SyntaxKind[SyntaxKind["SwitchKeyword"] = 34] = "SwitchKeyword";
        SyntaxKind[SyntaxKind["ThisKeyword"] = 35] = "ThisKeyword";
        SyntaxKind[SyntaxKind["ThrowKeyword"] = 36] = "ThrowKeyword";
        SyntaxKind[SyntaxKind["TrueKeyword"] = 37] = "TrueKeyword";
        SyntaxKind[SyntaxKind["TryKeyword"] = 38] = "TryKeyword";
        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 39] = "TypeOfKeyword";
        SyntaxKind[SyntaxKind["VarKeyword"] = 40] = "VarKeyword";
        SyntaxKind[SyntaxKind["VoidKeyword"] = 41] = "VoidKeyword";
        SyntaxKind[SyntaxKind["WhileKeyword"] = 42] = "WhileKeyword";
        SyntaxKind[SyntaxKind["WithKeyword"] = 43] = "WithKeyword";

        SyntaxKind[SyntaxKind["ClassKeyword"] = 44] = "ClassKeyword";
        SyntaxKind[SyntaxKind["ConstKeyword"] = 45] = "ConstKeyword";
        SyntaxKind[SyntaxKind["EnumKeyword"] = 46] = "EnumKeyword";
        SyntaxKind[SyntaxKind["ExportKeyword"] = 47] = "ExportKeyword";
        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 48] = "ExtendsKeyword";
        SyntaxKind[SyntaxKind["ImportKeyword"] = 49] = "ImportKeyword";
        SyntaxKind[SyntaxKind["SuperKeyword"] = 50] = "SuperKeyword";

        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 51] = "ImplementsKeyword";
        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 52] = "InterfaceKeyword";
        SyntaxKind[SyntaxKind["LetKeyword"] = 53] = "LetKeyword";
        SyntaxKind[SyntaxKind["PackageKeyword"] = 54] = "PackageKeyword";
        SyntaxKind[SyntaxKind["PrivateKeyword"] = 55] = "PrivateKeyword";
        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 56] = "ProtectedKeyword";
        SyntaxKind[SyntaxKind["PublicKeyword"] = 57] = "PublicKeyword";
        SyntaxKind[SyntaxKind["StaticKeyword"] = 58] = "StaticKeyword";
        SyntaxKind[SyntaxKind["YieldKeyword"] = 59] = "YieldKeyword";

        SyntaxKind[SyntaxKind["AnyKeyword"] = 60] = "AnyKeyword";
        SyntaxKind[SyntaxKind["BooleanKeyword"] = 61] = "BooleanKeyword";
        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 62] = "ConstructorKeyword";
        SyntaxKind[SyntaxKind["DeclareKeyword"] = 63] = "DeclareKeyword";
        SyntaxKind[SyntaxKind["GetKeyword"] = 64] = "GetKeyword";
        SyntaxKind[SyntaxKind["ModuleKeyword"] = 65] = "ModuleKeyword";
        SyntaxKind[SyntaxKind["RequireKeyword"] = 66] = "RequireKeyword";
        SyntaxKind[SyntaxKind["NumberKeyword"] = 67] = "NumberKeyword";
        SyntaxKind[SyntaxKind["SetKeyword"] = 68] = "SetKeyword";
        SyntaxKind[SyntaxKind["StringKeyword"] = 69] = "StringKeyword";

        SyntaxKind[SyntaxKind["OpenBraceToken"] = 70] = "OpenBraceToken";
        SyntaxKind[SyntaxKind["CloseBraceToken"] = 71] = "CloseBraceToken";
        SyntaxKind[SyntaxKind["OpenParenToken"] = 72] = "OpenParenToken";
        SyntaxKind[SyntaxKind["CloseParenToken"] = 73] = "CloseParenToken";
        SyntaxKind[SyntaxKind["OpenBracketToken"] = 74] = "OpenBracketToken";
        SyntaxKind[SyntaxKind["CloseBracketToken"] = 75] = "CloseBracketToken";
        SyntaxKind[SyntaxKind["DotToken"] = 76] = "DotToken";
        SyntaxKind[SyntaxKind["DotDotDotToken"] = 77] = "DotDotDotToken";
        SyntaxKind[SyntaxKind["SemicolonToken"] = 78] = "SemicolonToken";
        SyntaxKind[SyntaxKind["CommaToken"] = 79] = "CommaToken";
        SyntaxKind[SyntaxKind["LessThanToken"] = 80] = "LessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanToken"] = 81] = "GreaterThanToken";
        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 82] = "LessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 83] = "GreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 84] = "EqualsEqualsToken";
        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 85] = "EqualsGreaterThanToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 86] = "ExclamationEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 87] = "EqualsEqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 88] = "ExclamationEqualsEqualsToken";
        SyntaxKind[SyntaxKind["PlusToken"] = 89] = "PlusToken";
        SyntaxKind[SyntaxKind["MinusToken"] = 90] = "MinusToken";
        SyntaxKind[SyntaxKind["AsteriskToken"] = 91] = "AsteriskToken";
        SyntaxKind[SyntaxKind["PercentToken"] = 92] = "PercentToken";
        SyntaxKind[SyntaxKind["PlusPlusToken"] = 93] = "PlusPlusToken";
        SyntaxKind[SyntaxKind["MinusMinusToken"] = 94] = "MinusMinusToken";
        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 95] = "LessThanLessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 96] = "GreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 97] = "GreaterThanGreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["AmpersandToken"] = 98] = "AmpersandToken";
        SyntaxKind[SyntaxKind["BarToken"] = 99] = "BarToken";
        SyntaxKind[SyntaxKind["CaretToken"] = 100] = "CaretToken";
        SyntaxKind[SyntaxKind["ExclamationToken"] = 101] = "ExclamationToken";
        SyntaxKind[SyntaxKind["TildeToken"] = 102] = "TildeToken";
        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 103] = "AmpersandAmpersandToken";
        SyntaxKind[SyntaxKind["BarBarToken"] = 104] = "BarBarToken";
        SyntaxKind[SyntaxKind["QuestionToken"] = 105] = "QuestionToken";
        SyntaxKind[SyntaxKind["ColonToken"] = 106] = "ColonToken";
        SyntaxKind[SyntaxKind["EqualsToken"] = 107] = "EqualsToken";
        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 108] = "PlusEqualsToken";
        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 109] = "MinusEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 110] = "AsteriskEqualsToken";
        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 111] = "PercentEqualsToken";
        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 112] = "LessThanLessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 113] = "GreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 114] = "GreaterThanGreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 115] = "AmpersandEqualsToken";
        SyntaxKind[SyntaxKind["BarEqualsToken"] = 116] = "BarEqualsToken";
        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 117] = "CaretEqualsToken";
        SyntaxKind[SyntaxKind["SlashToken"] = 118] = "SlashToken";
        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 119] = "SlashEqualsToken";

        SyntaxKind[SyntaxKind["SourceUnit"] = 120] = "SourceUnit";

        SyntaxKind[SyntaxKind["QualifiedName"] = 121] = "QualifiedName";

        SyntaxKind[SyntaxKind["ObjectType"] = 122] = "ObjectType";
        SyntaxKind[SyntaxKind["FunctionType"] = 123] = "FunctionType";
        SyntaxKind[SyntaxKind["ArrayType"] = 124] = "ArrayType";
        SyntaxKind[SyntaxKind["ConstructorType"] = 125] = "ConstructorType";
        SyntaxKind[SyntaxKind["GenericType"] = 126] = "GenericType";
        SyntaxKind[SyntaxKind["TypeQuery"] = 127] = "TypeQuery";

        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 128] = "InterfaceDeclaration";
        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 129] = "FunctionDeclaration";
        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 130] = "ModuleDeclaration";
        SyntaxKind[SyntaxKind["ClassDeclaration"] = 131] = "ClassDeclaration";
        SyntaxKind[SyntaxKind["EnumDeclaration"] = 132] = "EnumDeclaration";
        SyntaxKind[SyntaxKind["ImportDeclaration"] = 133] = "ImportDeclaration";
        SyntaxKind[SyntaxKind["ExportAssignment"] = 134] = "ExportAssignment";

        SyntaxKind[SyntaxKind["MemberFunctionDeclaration"] = 135] = "MemberFunctionDeclaration";
        SyntaxKind[SyntaxKind["MemberVariableDeclaration"] = 136] = "MemberVariableDeclaration";
        SyntaxKind[SyntaxKind["ConstructorDeclaration"] = 137] = "ConstructorDeclaration";
        SyntaxKind[SyntaxKind["IndexMemberDeclaration"] = 138] = "IndexMemberDeclaration";

        SyntaxKind[SyntaxKind["GetAccessor"] = 139] = "GetAccessor";
        SyntaxKind[SyntaxKind["SetAccessor"] = 140] = "SetAccessor";

        SyntaxKind[SyntaxKind["PropertySignature"] = 141] = "PropertySignature";
        SyntaxKind[SyntaxKind["CallSignature"] = 142] = "CallSignature";
        SyntaxKind[SyntaxKind["ConstructSignature"] = 143] = "ConstructSignature";
        SyntaxKind[SyntaxKind["IndexSignature"] = 144] = "IndexSignature";
        SyntaxKind[SyntaxKind["MethodSignature"] = 145] = "MethodSignature";

        SyntaxKind[SyntaxKind["Block"] = 146] = "Block";
        SyntaxKind[SyntaxKind["IfStatement"] = 147] = "IfStatement";
        SyntaxKind[SyntaxKind["VariableStatement"] = 148] = "VariableStatement";
        SyntaxKind[SyntaxKind["ExpressionStatement"] = 149] = "ExpressionStatement";
        SyntaxKind[SyntaxKind["ReturnStatement"] = 150] = "ReturnStatement";
        SyntaxKind[SyntaxKind["SwitchStatement"] = 151] = "SwitchStatement";
        SyntaxKind[SyntaxKind["BreakStatement"] = 152] = "BreakStatement";
        SyntaxKind[SyntaxKind["ContinueStatement"] = 153] = "ContinueStatement";
        SyntaxKind[SyntaxKind["ForStatement"] = 154] = "ForStatement";
        SyntaxKind[SyntaxKind["ForInStatement"] = 155] = "ForInStatement";
        SyntaxKind[SyntaxKind["EmptyStatement"] = 156] = "EmptyStatement";
        SyntaxKind[SyntaxKind["ThrowStatement"] = 157] = "ThrowStatement";
        SyntaxKind[SyntaxKind["WhileStatement"] = 158] = "WhileStatement";
        SyntaxKind[SyntaxKind["TryStatement"] = 159] = "TryStatement";
        SyntaxKind[SyntaxKind["LabeledStatement"] = 160] = "LabeledStatement";
        SyntaxKind[SyntaxKind["DoStatement"] = 161] = "DoStatement";
        SyntaxKind[SyntaxKind["DebuggerStatement"] = 162] = "DebuggerStatement";
        SyntaxKind[SyntaxKind["WithStatement"] = 163] = "WithStatement";

        SyntaxKind[SyntaxKind["PlusExpression"] = 164] = "PlusExpression";
        SyntaxKind[SyntaxKind["NegateExpression"] = 165] = "NegateExpression";
        SyntaxKind[SyntaxKind["BitwiseNotExpression"] = 166] = "BitwiseNotExpression";
        SyntaxKind[SyntaxKind["LogicalNotExpression"] = 167] = "LogicalNotExpression";
        SyntaxKind[SyntaxKind["PreIncrementExpression"] = 168] = "PreIncrementExpression";
        SyntaxKind[SyntaxKind["PreDecrementExpression"] = 169] = "PreDecrementExpression";
        SyntaxKind[SyntaxKind["DeleteExpression"] = 170] = "DeleteExpression";
        SyntaxKind[SyntaxKind["TypeOfExpression"] = 171] = "TypeOfExpression";
        SyntaxKind[SyntaxKind["VoidExpression"] = 172] = "VoidExpression";
        SyntaxKind[SyntaxKind["CommaExpression"] = 173] = "CommaExpression";
        SyntaxKind[SyntaxKind["AssignmentExpression"] = 174] = "AssignmentExpression";
        SyntaxKind[SyntaxKind["AddAssignmentExpression"] = 175] = "AddAssignmentExpression";
        SyntaxKind[SyntaxKind["SubtractAssignmentExpression"] = 176] = "SubtractAssignmentExpression";
        SyntaxKind[SyntaxKind["MultiplyAssignmentExpression"] = 177] = "MultiplyAssignmentExpression";
        SyntaxKind[SyntaxKind["DivideAssignmentExpression"] = 178] = "DivideAssignmentExpression";
        SyntaxKind[SyntaxKind["ModuloAssignmentExpression"] = 179] = "ModuloAssignmentExpression";
        SyntaxKind[SyntaxKind["AndAssignmentExpression"] = 180] = "AndAssignmentExpression";
        SyntaxKind[SyntaxKind["ExclusiveOrAssignmentExpression"] = 181] = "ExclusiveOrAssignmentExpression";
        SyntaxKind[SyntaxKind["OrAssignmentExpression"] = 182] = "OrAssignmentExpression";
        SyntaxKind[SyntaxKind["LeftShiftAssignmentExpression"] = 183] = "LeftShiftAssignmentExpression";
        SyntaxKind[SyntaxKind["SignedRightShiftAssignmentExpression"] = 184] = "SignedRightShiftAssignmentExpression";
        SyntaxKind[SyntaxKind["UnsignedRightShiftAssignmentExpression"] = 185] = "UnsignedRightShiftAssignmentExpression";
        SyntaxKind[SyntaxKind["ConditionalExpression"] = 186] = "ConditionalExpression";
        SyntaxKind[SyntaxKind["LogicalOrExpression"] = 187] = "LogicalOrExpression";
        SyntaxKind[SyntaxKind["LogicalAndExpression"] = 188] = "LogicalAndExpression";
        SyntaxKind[SyntaxKind["BitwiseOrExpression"] = 189] = "BitwiseOrExpression";
        SyntaxKind[SyntaxKind["BitwiseExclusiveOrExpression"] = 190] = "BitwiseExclusiveOrExpression";
        SyntaxKind[SyntaxKind["BitwiseAndExpression"] = 191] = "BitwiseAndExpression";
        SyntaxKind[SyntaxKind["EqualsWithTypeConversionExpression"] = 192] = "EqualsWithTypeConversionExpression";
        SyntaxKind[SyntaxKind["NotEqualsWithTypeConversionExpression"] = 193] = "NotEqualsWithTypeConversionExpression";
        SyntaxKind[SyntaxKind["EqualsExpression"] = 194] = "EqualsExpression";
        SyntaxKind[SyntaxKind["NotEqualsExpression"] = 195] = "NotEqualsExpression";
        SyntaxKind[SyntaxKind["LessThanExpression"] = 196] = "LessThanExpression";
        SyntaxKind[SyntaxKind["GreaterThanExpression"] = 197] = "GreaterThanExpression";
        SyntaxKind[SyntaxKind["LessThanOrEqualExpression"] = 198] = "LessThanOrEqualExpression";
        SyntaxKind[SyntaxKind["GreaterThanOrEqualExpression"] = 199] = "GreaterThanOrEqualExpression";
        SyntaxKind[SyntaxKind["InstanceOfExpression"] = 200] = "InstanceOfExpression";
        SyntaxKind[SyntaxKind["InExpression"] = 201] = "InExpression";
        SyntaxKind[SyntaxKind["LeftShiftExpression"] = 202] = "LeftShiftExpression";
        SyntaxKind[SyntaxKind["SignedRightShiftExpression"] = 203] = "SignedRightShiftExpression";
        SyntaxKind[SyntaxKind["UnsignedRightShiftExpression"] = 204] = "UnsignedRightShiftExpression";
        SyntaxKind[SyntaxKind["MultiplyExpression"] = 205] = "MultiplyExpression";
        SyntaxKind[SyntaxKind["DivideExpression"] = 206] = "DivideExpression";
        SyntaxKind[SyntaxKind["ModuloExpression"] = 207] = "ModuloExpression";
        SyntaxKind[SyntaxKind["AddExpression"] = 208] = "AddExpression";
        SyntaxKind[SyntaxKind["SubtractExpression"] = 209] = "SubtractExpression";
        SyntaxKind[SyntaxKind["PostIncrementExpression"] = 210] = "PostIncrementExpression";
        SyntaxKind[SyntaxKind["PostDecrementExpression"] = 211] = "PostDecrementExpression";
        SyntaxKind[SyntaxKind["MemberAccessExpression"] = 212] = "MemberAccessExpression";
        SyntaxKind[SyntaxKind["InvocationExpression"] = 213] = "InvocationExpression";
        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 214] = "ArrayLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 215] = "ObjectLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectCreationExpression"] = 216] = "ObjectCreationExpression";
        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 217] = "ParenthesizedExpression";
        SyntaxKind[SyntaxKind["ParenthesizedArrowFunctionExpression"] = 218] = "ParenthesizedArrowFunctionExpression";
        SyntaxKind[SyntaxKind["SimpleArrowFunctionExpression"] = 219] = "SimpleArrowFunctionExpression";
        SyntaxKind[SyntaxKind["CastExpression"] = 220] = "CastExpression";
        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 221] = "ElementAccessExpression";
        SyntaxKind[SyntaxKind["FunctionExpression"] = 222] = "FunctionExpression";
        SyntaxKind[SyntaxKind["OmittedExpression"] = 223] = "OmittedExpression";

        SyntaxKind[SyntaxKind["VariableDeclaration"] = 224] = "VariableDeclaration";
        SyntaxKind[SyntaxKind["VariableDeclarator"] = 225] = "VariableDeclarator";

        SyntaxKind[SyntaxKind["ArgumentList"] = 226] = "ArgumentList";
        SyntaxKind[SyntaxKind["ParameterList"] = 227] = "ParameterList";
        SyntaxKind[SyntaxKind["TypeArgumentList"] = 228] = "TypeArgumentList";
        SyntaxKind[SyntaxKind["TypeParameterList"] = 229] = "TypeParameterList";

        SyntaxKind[SyntaxKind["ExtendsHeritageClause"] = 230] = "ExtendsHeritageClause";
        SyntaxKind[SyntaxKind["ImplementsHeritageClause"] = 231] = "ImplementsHeritageClause";
        SyntaxKind[SyntaxKind["EqualsValueClause"] = 232] = "EqualsValueClause";
        SyntaxKind[SyntaxKind["CaseSwitchClause"] = 233] = "CaseSwitchClause";
        SyntaxKind[SyntaxKind["DefaultSwitchClause"] = 234] = "DefaultSwitchClause";
        SyntaxKind[SyntaxKind["ElseClause"] = 235] = "ElseClause";
        SyntaxKind[SyntaxKind["CatchClause"] = 236] = "CatchClause";
        SyntaxKind[SyntaxKind["FinallyClause"] = 237] = "FinallyClause";

        SyntaxKind[SyntaxKind["TypeParameter"] = 238] = "TypeParameter";
        SyntaxKind[SyntaxKind["Constraint"] = 239] = "Constraint";

        SyntaxKind[SyntaxKind["SimplePropertyAssignment"] = 240] = "SimplePropertyAssignment";

        SyntaxKind[SyntaxKind["FunctionPropertyAssignment"] = 241] = "FunctionPropertyAssignment";

        SyntaxKind[SyntaxKind["Parameter"] = 242] = "Parameter";
        SyntaxKind[SyntaxKind["EnumElement"] = 243] = "EnumElement";
        SyntaxKind[SyntaxKind["TypeAnnotation"] = 244] = "TypeAnnotation";
        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 245] = "ExternalModuleReference";
        SyntaxKind[SyntaxKind["ModuleNameModuleReference"] = 246] = "ModuleNameModuleReference";
        SyntaxKind[SyntaxKind["Last"] = SyntaxKind.ModuleNameModuleReference] = "Last";

        SyntaxKind[SyntaxKind["FirstStandardKeyword"] = SyntaxKind.BreakKeyword] = "FirstStandardKeyword";
        SyntaxKind[SyntaxKind["LastStandardKeyword"] = SyntaxKind.WithKeyword] = "LastStandardKeyword";

        SyntaxKind[SyntaxKind["FirstFutureReservedKeyword"] = SyntaxKind.ClassKeyword] = "FirstFutureReservedKeyword";
        SyntaxKind[SyntaxKind["LastFutureReservedKeyword"] = SyntaxKind.SuperKeyword] = "LastFutureReservedKeyword";

        SyntaxKind[SyntaxKind["FirstFutureReservedStrictKeyword"] = SyntaxKind.ImplementsKeyword] = "FirstFutureReservedStrictKeyword";
        SyntaxKind[SyntaxKind["LastFutureReservedStrictKeyword"] = SyntaxKind.YieldKeyword] = "LastFutureReservedStrictKeyword";

        SyntaxKind[SyntaxKind["FirstTypeScriptKeyword"] = SyntaxKind.AnyKeyword] = "FirstTypeScriptKeyword";
        SyntaxKind[SyntaxKind["LastTypeScriptKeyword"] = SyntaxKind.StringKeyword] = "LastTypeScriptKeyword";

        SyntaxKind[SyntaxKind["FirstKeyword"] = SyntaxKind.FirstStandardKeyword] = "FirstKeyword";
        SyntaxKind[SyntaxKind["LastKeyword"] = SyntaxKind.LastTypeScriptKeyword] = "LastKeyword";

        SyntaxKind[SyntaxKind["FirstToken"] = SyntaxKind.ErrorToken] = "FirstToken";
        SyntaxKind[SyntaxKind["LastToken"] = SyntaxKind.SlashEqualsToken] = "LastToken";

        SyntaxKind[SyntaxKind["FirstPunctuation"] = SyntaxKind.OpenBraceToken] = "FirstPunctuation";
        SyntaxKind[SyntaxKind["LastPunctuation"] = SyntaxKind.SlashEqualsToken] = "LastPunctuation";

        SyntaxKind[SyntaxKind["FirstFixedWidth"] = SyntaxKind.FirstKeyword] = "FirstFixedWidth";
        SyntaxKind[SyntaxKind["LastFixedWidth"] = SyntaxKind.LastPunctuation] = "LastFixedWidth";

        SyntaxKind[SyntaxKind["FirstTrivia"] = SyntaxKind.WhitespaceTrivia] = "FirstTrivia";
        SyntaxKind[SyntaxKind["LastTrivia"] = SyntaxKind.SkippedTokenTrivia] = "LastTrivia";
    })(TypeScript.SyntaxKind || (TypeScript.SyntaxKind = {}));
    var SyntaxKind = TypeScript.SyntaxKind;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (SyntaxFacts) {
        var textToKeywordKind = {
            "any": 60 /* AnyKeyword */,
            "boolean": 61 /* BooleanKeyword */,
            "break": 15 /* BreakKeyword */,
            "case": 16 /* CaseKeyword */,
            "catch": 17 /* CatchKeyword */,
            "class": 44 /* ClassKeyword */,
            "continue": 18 /* ContinueKeyword */,
            "const": 45 /* ConstKeyword */,
            "constructor": 62 /* ConstructorKeyword */,
            "debugger": 19 /* DebuggerKeyword */,
            "declare": 63 /* DeclareKeyword */,
            "default": 20 /* DefaultKeyword */,
            "delete": 21 /* DeleteKeyword */,
            "do": 22 /* DoKeyword */,
            "else": 23 /* ElseKeyword */,
            "enum": 46 /* EnumKeyword */,
            "export": 47 /* ExportKeyword */,
            "extends": 48 /* ExtendsKeyword */,
            "false": 24 /* FalseKeyword */,
            "finally": 25 /* FinallyKeyword */,
            "for": 26 /* ForKeyword */,
            "function": 27 /* FunctionKeyword */,
            "get": 64 /* GetKeyword */,
            "if": 28 /* IfKeyword */,
            "implements": 51 /* ImplementsKeyword */,
            "import": 49 /* ImportKeyword */,
            "in": 29 /* InKeyword */,
            "instanceof": 30 /* InstanceOfKeyword */,
            "interface": 52 /* InterfaceKeyword */,
            "let": 53 /* LetKeyword */,
            "module": 65 /* ModuleKeyword */,
            "new": 31 /* NewKeyword */,
            "null": 32 /* NullKeyword */,
            "number": 67 /* NumberKeyword */,
            "package": 54 /* PackageKeyword */,
            "private": 55 /* PrivateKeyword */,
            "protected": 56 /* ProtectedKeyword */,
            "public": 57 /* PublicKeyword */,
            "require": 66 /* RequireKeyword */,
            "return": 33 /* ReturnKeyword */,
            "set": 68 /* SetKeyword */,
            "static": 58 /* StaticKeyword */,
            "string": 69 /* StringKeyword */,
            "super": 50 /* SuperKeyword */,
            "switch": 34 /* SwitchKeyword */,
            "this": 35 /* ThisKeyword */,
            "throw": 36 /* ThrowKeyword */,
            "true": 37 /* TrueKeyword */,
            "try": 38 /* TryKeyword */,
            "typeof": 39 /* TypeOfKeyword */,
            "var": 40 /* VarKeyword */,
            "void": 41 /* VoidKeyword */,
            "while": 42 /* WhileKeyword */,
            "with": 43 /* WithKeyword */,
            "yield": 59 /* YieldKeyword */,
            "{": 70 /* OpenBraceToken */,
            "}": 71 /* CloseBraceToken */,
            "(": 72 /* OpenParenToken */,
            ")": 73 /* CloseParenToken */,
            "[": 74 /* OpenBracketToken */,
            "]": 75 /* CloseBracketToken */,
            ".": 76 /* DotToken */,
            "...": 77 /* DotDotDotToken */,
            ";": 78 /* SemicolonToken */,
            ",": 79 /* CommaToken */,
            "<": 80 /* LessThanToken */,
            ">": 81 /* GreaterThanToken */,
            "<=": 82 /* LessThanEqualsToken */,
            ">=": 83 /* GreaterThanEqualsToken */,
            "==": 84 /* EqualsEqualsToken */,
            "=>": 85 /* EqualsGreaterThanToken */,
            "!=": 86 /* ExclamationEqualsToken */,
            "===": 87 /* EqualsEqualsEqualsToken */,
            "!==": 88 /* ExclamationEqualsEqualsToken */,
            "+": 89 /* PlusToken */,
            "-": 90 /* MinusToken */,
            "*": 91 /* AsteriskToken */,
            "%": 92 /* PercentToken */,
            "++": 93 /* PlusPlusToken */,
            "--": 94 /* MinusMinusToken */,
            "<<": 95 /* LessThanLessThanToken */,
            ">>": 96 /* GreaterThanGreaterThanToken */,
            ">>>": 97 /* GreaterThanGreaterThanGreaterThanToken */,
            "&": 98 /* AmpersandToken */,
            "|": 99 /* BarToken */,
            "^": 100 /* CaretToken */,
            "!": 101 /* ExclamationToken */,
            "~": 102 /* TildeToken */,
            "&&": 103 /* AmpersandAmpersandToken */,
            "||": 104 /* BarBarToken */,
            "?": 105 /* QuestionToken */,
            ":": 106 /* ColonToken */,
            "=": 107 /* EqualsToken */,
            "+=": 108 /* PlusEqualsToken */,
            "-=": 109 /* MinusEqualsToken */,
            "*=": 110 /* AsteriskEqualsToken */,
            "%=": 111 /* PercentEqualsToken */,
            "<<=": 112 /* LessThanLessThanEqualsToken */,
            ">>=": 113 /* GreaterThanGreaterThanEqualsToken */,
            ">>>=": 114 /* GreaterThanGreaterThanGreaterThanEqualsToken */,
            "&=": 115 /* AmpersandEqualsToken */,
            "|=": 116 /* BarEqualsToken */,
            "^=": 117 /* CaretEqualsToken */,
            "/": 118 /* SlashToken */,
            "/=": 119 /* SlashEqualsToken */
        };

        var kindToText = new Array();

        for (var name in textToKeywordKind) {
            if (textToKeywordKind.hasOwnProperty(name)) {
                kindToText[textToKeywordKind[name]] = name;
            }
        }

        kindToText[62 /* ConstructorKeyword */] = "constructor";

        function getTokenKind(text) {
            if (textToKeywordKind.hasOwnProperty(text)) {
                return textToKeywordKind[text];
            }

            return 0 /* None */;
        }
        SyntaxFacts.getTokenKind = getTokenKind;

        function getText(kind) {
            var result = kindToText[kind];
            return result !== undefined ? result : null;
        }
        SyntaxFacts.getText = getText;

        function isTokenKind(kind) {
            return kind >= 9 /* FirstToken */ && kind <= 119 /* LastToken */;
        }
        SyntaxFacts.isTokenKind = isTokenKind;

        function isAnyKeyword(kind) {
            return kind >= 15 /* FirstKeyword */ && kind <= 69 /* LastKeyword */;
        }
        SyntaxFacts.isAnyKeyword = isAnyKeyword;

        function isStandardKeyword(kind) {
            return kind >= 15 /* FirstStandardKeyword */ && kind <= 43 /* LastStandardKeyword */;
        }
        SyntaxFacts.isStandardKeyword = isStandardKeyword;

        function isFutureReservedKeyword(kind) {
            return kind >= 44 /* FirstFutureReservedKeyword */ && kind <= 50 /* LastFutureReservedKeyword */;
        }
        SyntaxFacts.isFutureReservedKeyword = isFutureReservedKeyword;

        function isFutureReservedStrictKeyword(kind) {
            return kind >= 51 /* FirstFutureReservedStrictKeyword */ && kind <= 59 /* LastFutureReservedStrictKeyword */;
        }
        SyntaxFacts.isFutureReservedStrictKeyword = isFutureReservedStrictKeyword;

        function isAnyPunctuation(kind) {
            return kind >= 70 /* FirstPunctuation */ && kind <= 119 /* LastPunctuation */;
        }
        SyntaxFacts.isAnyPunctuation = isAnyPunctuation;

        function isPrefixUnaryExpressionOperatorToken(tokenKind) {
            return getPrefixUnaryExpressionFromOperatorToken(tokenKind) !== 0 /* None */;
        }
        SyntaxFacts.isPrefixUnaryExpressionOperatorToken = isPrefixUnaryExpressionOperatorToken;

        function isBinaryExpressionOperatorToken(tokenKind) {
            return getBinaryExpressionFromOperatorToken(tokenKind) !== 0 /* None */;
        }
        SyntaxFacts.isBinaryExpressionOperatorToken = isBinaryExpressionOperatorToken;

        function getPrefixUnaryExpressionFromOperatorToken(tokenKind) {
            switch (tokenKind) {
                case 89 /* PlusToken */:
                    return 164 /* PlusExpression */;
                case 90 /* MinusToken */:
                    return 165 /* NegateExpression */;
                case 102 /* TildeToken */:
                    return 166 /* BitwiseNotExpression */;
                case 101 /* ExclamationToken */:
                    return 167 /* LogicalNotExpression */;
                case 93 /* PlusPlusToken */:
                    return 168 /* PreIncrementExpression */;
                case 94 /* MinusMinusToken */:
                    return 169 /* PreDecrementExpression */;

                default:
                    return 0 /* None */;
            }
        }
        SyntaxFacts.getPrefixUnaryExpressionFromOperatorToken = getPrefixUnaryExpressionFromOperatorToken;

        function getPostfixUnaryExpressionFromOperatorToken(tokenKind) {
            switch (tokenKind) {
                case 93 /* PlusPlusToken */:
                    return 210 /* PostIncrementExpression */;
                case 94 /* MinusMinusToken */:
                    return 211 /* PostDecrementExpression */;
                default:
                    return 0 /* None */;
            }
        }
        SyntaxFacts.getPostfixUnaryExpressionFromOperatorToken = getPostfixUnaryExpressionFromOperatorToken;

        function getBinaryExpressionFromOperatorToken(tokenKind) {
            switch (tokenKind) {
                case 91 /* AsteriskToken */:
                    return 205 /* MultiplyExpression */;

                case 118 /* SlashToken */:
                    return 206 /* DivideExpression */;

                case 92 /* PercentToken */:
                    return 207 /* ModuloExpression */;

                case 89 /* PlusToken */:
                    return 208 /* AddExpression */;

                case 90 /* MinusToken */:
                    return 209 /* SubtractExpression */;

                case 95 /* LessThanLessThanToken */:
                    return 202 /* LeftShiftExpression */;

                case 96 /* GreaterThanGreaterThanToken */:
                    return 203 /* SignedRightShiftExpression */;

                case 97 /* GreaterThanGreaterThanGreaterThanToken */:
                    return 204 /* UnsignedRightShiftExpression */;

                case 80 /* LessThanToken */:
                    return 196 /* LessThanExpression */;

                case 81 /* GreaterThanToken */:
                    return 197 /* GreaterThanExpression */;

                case 82 /* LessThanEqualsToken */:
                    return 198 /* LessThanOrEqualExpression */;

                case 83 /* GreaterThanEqualsToken */:
                    return 199 /* GreaterThanOrEqualExpression */;

                case 30 /* InstanceOfKeyword */:
                    return 200 /* InstanceOfExpression */;

                case 29 /* InKeyword */:
                    return 201 /* InExpression */;

                case 84 /* EqualsEqualsToken */:
                    return 192 /* EqualsWithTypeConversionExpression */;

                case 86 /* ExclamationEqualsToken */:
                    return 193 /* NotEqualsWithTypeConversionExpression */;

                case 87 /* EqualsEqualsEqualsToken */:
                    return 194 /* EqualsExpression */;

                case 88 /* ExclamationEqualsEqualsToken */:
                    return 195 /* NotEqualsExpression */;

                case 98 /* AmpersandToken */:
                    return 191 /* BitwiseAndExpression */;

                case 100 /* CaretToken */:
                    return 190 /* BitwiseExclusiveOrExpression */;

                case 99 /* BarToken */:
                    return 189 /* BitwiseOrExpression */;

                case 103 /* AmpersandAmpersandToken */:
                    return 188 /* LogicalAndExpression */;

                case 104 /* BarBarToken */:
                    return 187 /* LogicalOrExpression */;

                case 116 /* BarEqualsToken */:
                    return 182 /* OrAssignmentExpression */;

                case 115 /* AmpersandEqualsToken */:
                    return 180 /* AndAssignmentExpression */;

                case 117 /* CaretEqualsToken */:
                    return 181 /* ExclusiveOrAssignmentExpression */;

                case 112 /* LessThanLessThanEqualsToken */:
                    return 183 /* LeftShiftAssignmentExpression */;

                case 113 /* GreaterThanGreaterThanEqualsToken */:
                    return 184 /* SignedRightShiftAssignmentExpression */;

                case 114 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    return 185 /* UnsignedRightShiftAssignmentExpression */;

                case 108 /* PlusEqualsToken */:
                    return 175 /* AddAssignmentExpression */;

                case 109 /* MinusEqualsToken */:
                    return 176 /* SubtractAssignmentExpression */;

                case 110 /* AsteriskEqualsToken */:
                    return 177 /* MultiplyAssignmentExpression */;

                case 119 /* SlashEqualsToken */:
                    return 178 /* DivideAssignmentExpression */;

                case 111 /* PercentEqualsToken */:
                    return 179 /* ModuloAssignmentExpression */;

                case 107 /* EqualsToken */:
                    return 174 /* AssignmentExpression */;

                case 79 /* CommaToken */:
                    return 173 /* CommaExpression */;

                default:
                    return 0 /* None */;
            }
        }
        SyntaxFacts.getBinaryExpressionFromOperatorToken = getBinaryExpressionFromOperatorToken;

        function getOperatorTokenFromBinaryExpression(tokenKind) {
            switch (tokenKind) {
                case 205 /* MultiplyExpression */:
                    return 91 /* AsteriskToken */;

                case 206 /* DivideExpression */:
                    return 118 /* SlashToken */;

                case 207 /* ModuloExpression */:
                    return 92 /* PercentToken */;

                case 208 /* AddExpression */:
                    return 89 /* PlusToken */;

                case 209 /* SubtractExpression */:
                    return 90 /* MinusToken */;

                case 202 /* LeftShiftExpression */:
                    return 95 /* LessThanLessThanToken */;

                case 203 /* SignedRightShiftExpression */:
                    return 96 /* GreaterThanGreaterThanToken */;

                case 204 /* UnsignedRightShiftExpression */:
                    return 97 /* GreaterThanGreaterThanGreaterThanToken */;

                case 196 /* LessThanExpression */:
                    return 80 /* LessThanToken */;

                case 197 /* GreaterThanExpression */:
                    return 81 /* GreaterThanToken */;

                case 198 /* LessThanOrEqualExpression */:
                    return 82 /* LessThanEqualsToken */;

                case 199 /* GreaterThanOrEqualExpression */:
                    return 83 /* GreaterThanEqualsToken */;

                case 200 /* InstanceOfExpression */:
                    return 30 /* InstanceOfKeyword */;

                case 201 /* InExpression */:
                    return 29 /* InKeyword */;

                case 192 /* EqualsWithTypeConversionExpression */:
                    return 84 /* EqualsEqualsToken */;

                case 193 /* NotEqualsWithTypeConversionExpression */:
                    return 86 /* ExclamationEqualsToken */;

                case 194 /* EqualsExpression */:
                    return 87 /* EqualsEqualsEqualsToken */;

                case 195 /* NotEqualsExpression */:
                    return 88 /* ExclamationEqualsEqualsToken */;

                case 191 /* BitwiseAndExpression */:
                    return 98 /* AmpersandToken */;

                case 190 /* BitwiseExclusiveOrExpression */:
                    return 100 /* CaretToken */;

                case 189 /* BitwiseOrExpression */:
                    return 99 /* BarToken */;

                case 188 /* LogicalAndExpression */:
                    return 103 /* AmpersandAmpersandToken */;

                case 187 /* LogicalOrExpression */:
                    return 104 /* BarBarToken */;

                case 182 /* OrAssignmentExpression */:
                    return 116 /* BarEqualsToken */;

                case 180 /* AndAssignmentExpression */:
                    return 115 /* AmpersandEqualsToken */;

                case 181 /* ExclusiveOrAssignmentExpression */:
                    return 117 /* CaretEqualsToken */;

                case 183 /* LeftShiftAssignmentExpression */:
                    return 112 /* LessThanLessThanEqualsToken */;

                case 184 /* SignedRightShiftAssignmentExpression */:
                    return 113 /* GreaterThanGreaterThanEqualsToken */;

                case 185 /* UnsignedRightShiftAssignmentExpression */:
                    return 114 /* GreaterThanGreaterThanGreaterThanEqualsToken */;

                case 175 /* AddAssignmentExpression */:
                    return 108 /* PlusEqualsToken */;

                case 176 /* SubtractAssignmentExpression */:
                    return 109 /* MinusEqualsToken */;

                case 177 /* MultiplyAssignmentExpression */:
                    return 110 /* AsteriskEqualsToken */;

                case 178 /* DivideAssignmentExpression */:
                    return 119 /* SlashEqualsToken */;

                case 179 /* ModuloAssignmentExpression */:
                    return 111 /* PercentEqualsToken */;

                case 174 /* AssignmentExpression */:
                    return 107 /* EqualsToken */;

                case 173 /* CommaExpression */:
                    return 79 /* CommaToken */;

                default:
                    return 0 /* None */;
            }
        }
        SyntaxFacts.getOperatorTokenFromBinaryExpression = getOperatorTokenFromBinaryExpression;

        function isAnyDivideToken(kind) {
            switch (kind) {
                case 118 /* SlashToken */:
                case 119 /* SlashEqualsToken */:
                    return true;
                default:
                    return false;
            }
        }
        SyntaxFacts.isAnyDivideToken = isAnyDivideToken;

        function isAnyDivideOrRegularExpressionToken(kind) {
            switch (kind) {
                case 118 /* SlashToken */:
                case 119 /* SlashEqualsToken */:
                case 12 /* RegularExpressionLiteral */:
                    return true;
                default:
                    return false;
            }
        }
        SyntaxFacts.isAnyDivideOrRegularExpressionToken = isAnyDivideOrRegularExpressionToken;
    })(TypeScript.SyntaxFacts || (TypeScript.SyntaxFacts = {}));
    var SyntaxFacts = TypeScript.SyntaxFacts;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var isKeywordStartCharacter = TypeScript.ArrayUtilities.createArray(127 /* maxAsciiCharacter */, false);
    var isIdentifierStartCharacter = TypeScript.ArrayUtilities.createArray(127 /* maxAsciiCharacter */, false);
    var isIdentifierPartCharacter = TypeScript.ArrayUtilities.createArray(127 /* maxAsciiCharacter */, false);
    var isNumericLiteralStart = TypeScript.ArrayUtilities.createArray(127 /* maxAsciiCharacter */, false);

    for (var character = 0; character < 127 /* maxAsciiCharacter */; character++) {
        if (character >= 97 /* a */ && character <= 122 /* z */) {
            isIdentifierStartCharacter[character] = true;
            isIdentifierPartCharacter[character] = true;
        } else if ((character >= 65 /* A */ && character <= 90 /* Z */) || character === 95 /* _ */ || character === 36 /* $ */) {
            isIdentifierStartCharacter[character] = true;
            isIdentifierPartCharacter[character] = true;
        } else if (character >= 48 /* _0 */ && character <= 57 /* _9 */) {
            isIdentifierPartCharacter[character] = true;
            isNumericLiteralStart[character] = true;
        }
    }

    isNumericLiteralStart[46 /* dot */] = true;

    for (var keywordKind = 15 /* FirstKeyword */; keywordKind <= 69 /* LastKeyword */; keywordKind++) {
        var keyword = TypeScript.SyntaxFacts.getText(keywordKind);
        isKeywordStartCharacter[keyword.charCodeAt(0)] = true;
    }

    var Scanner = (function () {
        function Scanner(fileName, text, languageVersion, window) {
            if (typeof window === "undefined") { window = TypeScript.ArrayUtilities.createArray(2048, 0); }
            this.slidingWindow = new TypeScript.SlidingWindow(this, window, 0, text.length());
            this.fileName = fileName;
            this.text = text;
            this._languageVersion = languageVersion;
        }
        Scanner.prototype.languageVersion = function () {
            return this._languageVersion;
        };

        Scanner.prototype.fetchMoreItems = function (argument, sourceIndex, window, destinationIndex, spaceAvailable) {
            var charactersRemaining = this.text.length() - sourceIndex;
            var amountToRead = TypeScript.MathPrototype.min(charactersRemaining, spaceAvailable);
            this.text.copyTo(sourceIndex, window, destinationIndex, amountToRead);
            return amountToRead;
        };

        Scanner.prototype.currentCharCode = function () {
            return this.slidingWindow.currentItem(null);
        };

        Scanner.prototype.absoluteIndex = function () {
            return this.slidingWindow.absoluteIndex();
        };

        Scanner.prototype.setAbsoluteIndex = function (index) {
            this.slidingWindow.setAbsoluteIndex(index);
        };

        Scanner.prototype.scan = function (diagnostics, allowRegularExpression) {
            var diagnosticsLength = diagnostics.length;
            var fullStart = this.slidingWindow.absoluteIndex();
            var leadingTriviaInfo = this.scanTriviaInfo(diagnostics, false);

            var start = this.slidingWindow.absoluteIndex();
            var kindAndFlags = this.scanSyntaxToken(diagnostics, allowRegularExpression);
            var end = this.slidingWindow.absoluteIndex();

            var trailingTriviaInfo = this.scanTriviaInfo(diagnostics, true);
            var fullEnd = this.slidingWindow.absoluteIndex();

            var isVariableWidthKeyword = (kindAndFlags & -2147483648 /* IsVariableWidthKeyword */) !== 0;
            var kind = kindAndFlags & ~-2147483648 /* IsVariableWidthKeyword */;

            var token = this.createToken(fullStart, leadingTriviaInfo, start, kind, end, fullEnd, trailingTriviaInfo, isVariableWidthKeyword);

            return diagnosticsLength !== diagnostics.length ? TypeScript.Syntax.realizeToken(token) : token;
        };

        Scanner.prototype.createToken = function (fullStart, leadingTriviaInfo, start, kind, end, fullEnd, trailingTriviaInfo, isVariableWidthKeyword) {
            if (!isVariableWidthKeyword && kind >= 15 /* FirstFixedWidth */) {
                if (leadingTriviaInfo === 0) {
                    if (trailingTriviaInfo === 0) {
                        return new TypeScript.Syntax.FixedWidthTokenWithNoTrivia(kind);
                    } else {
                        var fullText = this.text.substr(fullStart, fullEnd - fullStart, false);
                        return new TypeScript.Syntax.FixedWidthTokenWithTrailingTrivia(fullText, kind, trailingTriviaInfo);
                    }
                } else if (trailingTriviaInfo === 0) {
                    var fullText = this.text.substr(fullStart, fullEnd - fullStart, false);
                    return new TypeScript.Syntax.FixedWidthTokenWithLeadingTrivia(fullText, kind, leadingTriviaInfo);
                } else {
                    var fullText = this.text.substr(fullStart, fullEnd - fullStart, false);
                    return new TypeScript.Syntax.FixedWidthTokenWithLeadingAndTrailingTrivia(fullText, kind, leadingTriviaInfo, trailingTriviaInfo);
                }
            } else {
                var width = end - start;

                var fullText = this.text.substr(fullStart, fullEnd - fullStart, false);

                if (leadingTriviaInfo === 0) {
                    if (trailingTriviaInfo === 0) {
                        return new TypeScript.Syntax.VariableWidthTokenWithNoTrivia(fullText, kind);
                    } else {
                        return new TypeScript.Syntax.VariableWidthTokenWithTrailingTrivia(fullText, kind, trailingTriviaInfo);
                    }
                } else if (trailingTriviaInfo === 0) {
                    return new TypeScript.Syntax.VariableWidthTokenWithLeadingTrivia(fullText, kind, leadingTriviaInfo);
                } else {
                    return new TypeScript.Syntax.VariableWidthTokenWithLeadingAndTrailingTrivia(fullText, kind, leadingTriviaInfo, trailingTriviaInfo);
                }
            }
        };

        Scanner.scanTrivia = function (text, start, length, isTrailing) {
            var scanner = new Scanner(null, text.subText(new TypeScript.TextSpan(start, length)), 1 /* EcmaScript5 */, Scanner.triviaWindow);
            return scanner.scanTrivia(text, start, isTrailing);
        };

        Scanner.prototype.scanTrivia = function (underlyingText, underlyingTextStart, isTrailing) {
            var trivia = new Array();

            while (true) {
                if (!this.slidingWindow.isAtEndOfSource()) {
                    var ch = this.currentCharCode();

                    switch (ch) {
                        case 32 /* space */:
                        case 160 /* nonBreakingSpace */:
                        case 8192 /* enQuad */:
                        case 8193 /* emQuad */:
                        case 8194 /* enSpace */:
                        case 8195 /* emSpace */:
                        case 8196 /* threePerEmSpace */:
                        case 8197 /* fourPerEmSpace */:
                        case 8198 /* sixPerEmSpace */:
                        case 8199 /* figureSpace */:
                        case 8200 /* punctuationSpace */:
                        case 8201 /* thinSpace */:
                        case 8202 /* hairSpace */:
                        case 8203 /* zeroWidthSpace */:
                        case 8239 /* narrowNoBreakSpace */:
                        case 12288 /* ideographicSpace */:

                        case 9 /* tab */:
                        case 11 /* verticalTab */:
                        case 12 /* formFeed */:
                        case 65279 /* byteOrderMark */:
                            trivia.push(this.scanWhitespaceTrivia(underlyingText, underlyingTextStart));
                            continue;

                        case 47 /* slash */:
                            var ch2 = this.slidingWindow.peekItemN(1);
                            if (ch2 === 47 /* slash */) {
                                trivia.push(this.scanSingleLineCommentTrivia(underlyingText, underlyingTextStart));
                                continue;
                            }

                            if (ch2 === 42 /* asterisk */) {
                                trivia.push(this.scanMultiLineCommentTrivia(underlyingText, underlyingTextStart));
                                continue;
                            }

                            throw TypeScript.Errors.invalidOperation();

                        case 13 /* carriageReturn */:
                        case 10 /* lineFeed */:
                        case 8233 /* paragraphSeparator */:
                        case 8232 /* lineSeparator */:
                            trivia.push(this.scanLineTerminatorSequenceTrivia(ch));

                            if (!isTrailing) {
                                continue;
                            }

                            break;

                        default:
                            throw TypeScript.Errors.invalidOperation();
                    }
                }

                return TypeScript.Syntax.triviaList(trivia);
            }
        };

        Scanner.prototype.scanTriviaInfo = function (diagnostics, isTrailing) {
            var width = 0;
            var hasCommentOrNewLine = 0;

            while (true) {
                var ch = this.currentCharCode();

                switch (ch) {
                    case 32 /* space */:
                    case 160 /* nonBreakingSpace */:
                    case 8192 /* enQuad */:
                    case 8193 /* emQuad */:
                    case 8194 /* enSpace */:
                    case 8195 /* emSpace */:
                    case 8196 /* threePerEmSpace */:
                    case 8197 /* fourPerEmSpace */:
                    case 8198 /* sixPerEmSpace */:
                    case 8199 /* figureSpace */:
                    case 8200 /* punctuationSpace */:
                    case 8201 /* thinSpace */:
                    case 8202 /* hairSpace */:
                    case 8203 /* zeroWidthSpace */:
                    case 8239 /* narrowNoBreakSpace */:
                    case 12288 /* ideographicSpace */:

                    case 9 /* tab */:
                    case 11 /* verticalTab */:
                    case 12 /* formFeed */:
                    case 65279 /* byteOrderMark */:
                        this.slidingWindow.moveToNextItem();
                        width++;
                        continue;

                    case 47 /* slash */:
                        var ch2 = this.slidingWindow.peekItemN(1);
                        if (ch2 === 47 /* slash */) {
                            hasCommentOrNewLine |= 2 /* TriviaCommentMask */;
                            width += this.scanSingleLineCommentTriviaLength();
                            continue;
                        }

                        if (ch2 === 42 /* asterisk */) {
                            hasCommentOrNewLine |= 2 /* TriviaCommentMask */;
                            width += this.scanMultiLineCommentTriviaLength(diagnostics);
                            continue;
                        }

                        break;

                    case 13 /* carriageReturn */:
                    case 10 /* lineFeed */:
                    case 8233 /* paragraphSeparator */:
                    case 8232 /* lineSeparator */:
                        hasCommentOrNewLine |= 1 /* TriviaNewLineMask */;
                        width += this.scanLineTerminatorSequenceLength(ch);

                        if (!isTrailing) {
                            continue;
                        }

                        break;
                }

                return (width << 2 /* TriviaFullWidthShift */) | hasCommentOrNewLine;
            }
        };

        Scanner.prototype.isNewLineCharacter = function (ch) {
            switch (ch) {
                case 13 /* carriageReturn */:
                case 10 /* lineFeed */:
                case 8233 /* paragraphSeparator */:
                case 8232 /* lineSeparator */:
                    return true;
                default:
                    return false;
            }
        };

        Scanner.prototype.scanWhitespaceTrivia = function (underlyingText, underlyingTextStart) {
            var absoluteStartIndex = this.absoluteIndex();

            var width = 0;
            while (true) {
                var ch = this.currentCharCode();

                switch (ch) {
                    case 32 /* space */:
                    case 160 /* nonBreakingSpace */:
                    case 8192 /* enQuad */:
                    case 8193 /* emQuad */:
                    case 8194 /* enSpace */:
                    case 8195 /* emSpace */:
                    case 8196 /* threePerEmSpace */:
                    case 8197 /* fourPerEmSpace */:
                    case 8198 /* sixPerEmSpace */:
                    case 8199 /* figureSpace */:
                    case 8200 /* punctuationSpace */:
                    case 8201 /* thinSpace */:
                    case 8202 /* hairSpace */:
                    case 8203 /* zeroWidthSpace */:
                    case 8239 /* narrowNoBreakSpace */:
                    case 12288 /* ideographicSpace */:

                    case 9 /* tab */:
                    case 11 /* verticalTab */:
                    case 12 /* formFeed */:
                    case 65279 /* byteOrderMark */:
                        this.slidingWindow.moveToNextItem();
                        width++;
                        continue;
                }

                break;
            }

            return TypeScript.Syntax.deferredTrivia(4 /* WhitespaceTrivia */, underlyingText, underlyingTextStart + absoluteStartIndex, width);
        };

        Scanner.prototype.scanSingleLineCommentTrivia = function (underlyingText, underlyingTextStart) {
            var absoluteStartIndex = this.slidingWindow.absoluteIndex();
            var width = this.scanSingleLineCommentTriviaLength();

            return TypeScript.Syntax.deferredTrivia(7 /* SingleLineCommentTrivia */, underlyingText, underlyingTextStart + absoluteStartIndex, width);
        };

        Scanner.prototype.scanSingleLineCommentTriviaLength = function () {
            this.slidingWindow.moveToNextItem();
            this.slidingWindow.moveToNextItem();

            var width = 2;
            while (true) {
                if (this.slidingWindow.isAtEndOfSource() || this.isNewLineCharacter(this.currentCharCode())) {
                    return width;
                }

                this.slidingWindow.moveToNextItem();
                width++;
            }
        };

        Scanner.prototype.scanMultiLineCommentTrivia = function (underlyingText, underlyingTextStart) {
            var absoluteStartIndex = this.absoluteIndex();
            var width = this.scanMultiLineCommentTriviaLength(null);

            return TypeScript.Syntax.deferredTrivia(6 /* MultiLineCommentTrivia */, underlyingText, underlyingTextStart + absoluteStartIndex, width);
        };

        Scanner.prototype.scanMultiLineCommentTriviaLength = function (diagnostics) {
            this.slidingWindow.moveToNextItem();
            this.slidingWindow.moveToNextItem();

            var width = 2;
            while (true) {
                if (this.slidingWindow.isAtEndOfSource()) {
                    if (diagnostics !== null) {
                        diagnostics.push(new TypeScript.Diagnostic(this.fileName, this.text.lineMap(), this.slidingWindow.absoluteIndex(), 0, TypeScript.DiagnosticCode.AsteriskSlash_expected, null));
                    }

                    return width;
                }

                var ch = this.currentCharCode();
                if (ch === 42 /* asterisk */ && this.slidingWindow.peekItemN(1) === 47 /* slash */) {
                    this.slidingWindow.moveToNextItem();
                    this.slidingWindow.moveToNextItem();
                    width += 2;
                    return width;
                }

                this.slidingWindow.moveToNextItem();
                width++;
            }
        };

        Scanner.prototype.scanLineTerminatorSequenceTrivia = function (ch) {
            var absoluteStartIndex = this.slidingWindow.getAndPinAbsoluteIndex();
            var width = this.scanLineTerminatorSequenceLength(ch);

            var text = this.substring(absoluteStartIndex, absoluteStartIndex + width, false);
            this.slidingWindow.releaseAndUnpinAbsoluteIndex(absoluteStartIndex);

            return TypeScript.Syntax.trivia(5 /* NewLineTrivia */, text);
        };

        Scanner.prototype.scanLineTerminatorSequenceLength = function (ch) {
            this.slidingWindow.moveToNextItem();

            if (ch === 13 /* carriageReturn */ && this.currentCharCode() === 10 /* lineFeed */) {
                this.slidingWindow.moveToNextItem();
                return 2;
            } else {
                return 1;
            }
        };

        Scanner.prototype.scanSyntaxToken = function (diagnostics, allowRegularExpression) {
            if (this.slidingWindow.isAtEndOfSource()) {
                return 10 /* EndOfFileToken */;
            }

            var character = this.currentCharCode();

            switch (character) {
                case 34 /* doubleQuote */:
                case 39 /* singleQuote */:
                    return this.scanStringLiteral(diagnostics);

                case 47 /* slash */:
                    return this.scanSlashToken(allowRegularExpression);

                case 46 /* dot */:
                    return this.scanDotToken(diagnostics);

                case 45 /* minus */:
                    return this.scanMinusToken();

                case 33 /* exclamation */:
                    return this.scanExclamationToken();

                case 61 /* equals */:
                    return this.scanEqualsToken();

                case 124 /* bar */:
                    return this.scanBarToken();

                case 42 /* asterisk */:
                    return this.scanAsteriskToken();

                case 43 /* plus */:
                    return this.scanPlusToken();

                case 37 /* percent */:
                    return this.scanPercentToken();

                case 38 /* ampersand */:
                    return this.scanAmpersandToken();

                case 94 /* caret */:
                    return this.scanCaretToken();

                case 60 /* lessThan */:
                    return this.scanLessThanToken();

                case 62 /* greaterThan */:
                    return this.advanceAndSetTokenKind(81 /* GreaterThanToken */);

                case 44 /* comma */:
                    return this.advanceAndSetTokenKind(79 /* CommaToken */);

                case 58 /* colon */:
                    return this.advanceAndSetTokenKind(106 /* ColonToken */);

                case 59 /* semicolon */:
                    return this.advanceAndSetTokenKind(78 /* SemicolonToken */);

                case 126 /* tilde */:
                    return this.advanceAndSetTokenKind(102 /* TildeToken */);

                case 40 /* openParen */:
                    return this.advanceAndSetTokenKind(72 /* OpenParenToken */);

                case 41 /* closeParen */:
                    return this.advanceAndSetTokenKind(73 /* CloseParenToken */);

                case 123 /* openBrace */:
                    return this.advanceAndSetTokenKind(70 /* OpenBraceToken */);

                case 125 /* closeBrace */:
                    return this.advanceAndSetTokenKind(71 /* CloseBraceToken */);

                case 91 /* openBracket */:
                    return this.advanceAndSetTokenKind(74 /* OpenBracketToken */);

                case 93 /* closeBracket */:
                    return this.advanceAndSetTokenKind(75 /* CloseBracketToken */);

                case 63 /* question */:
                    return this.advanceAndSetTokenKind(105 /* QuestionToken */);
            }

            if (isNumericLiteralStart[character]) {
                return this.scanNumericLiteral(diagnostics);
            }

            if (isIdentifierStartCharacter[character]) {
                var result = this.tryFastScanIdentifierOrKeyword(character);
                if (result !== 0 /* None */) {
                    return result;
                }
            }

            if (this.isIdentifierStart(this.peekCharOrUnicodeEscape())) {
                return this.slowScanIdentifierOrKeyword(diagnostics);
            }

            return this.scanDefaultCharacter(character, diagnostics);
        };

        Scanner.prototype.isIdentifierStart = function (interpretedChar) {
            if (isIdentifierStartCharacter[interpretedChar]) {
                return true;
            }

            return interpretedChar > 127 /* maxAsciiCharacter */ && TypeScript.Unicode.isIdentifierStart(interpretedChar, this._languageVersion);
        };

        Scanner.prototype.isIdentifierPart = function (interpretedChar) {
            if (isIdentifierPartCharacter[interpretedChar]) {
                return true;
            }

            return interpretedChar > 127 /* maxAsciiCharacter */ && TypeScript.Unicode.isIdentifierPart(interpretedChar, this._languageVersion);
        };

        Scanner.prototype.tryFastScanIdentifierOrKeyword = function (firstCharacter) {
            var slidingWindow = this.slidingWindow;
            var window = slidingWindow.window;

            var startIndex = slidingWindow.currentRelativeItemIndex;
            var endIndex = slidingWindow.windowCount;
            var currentIndex = startIndex;
            var character = 0;

            while (currentIndex < endIndex) {
                character = window[currentIndex];
                if (!isIdentifierPartCharacter[character]) {
                    break;
                }

                currentIndex++;
            }

            if (currentIndex === endIndex) {
                return 0 /* None */;
            } else if (character === 92 /* backslash */ || character > 127 /* maxAsciiCharacter */) {
                return 0 /* None */;
            } else {
                var kind;
                var identifierLength = currentIndex - startIndex;
                if (isKeywordStartCharacter[firstCharacter]) {
                    kind = TypeScript.ScannerUtilities.identifierKind(window, startIndex, identifierLength);
                } else {
                    kind = 11 /* IdentifierName */;
                }

                slidingWindow.setAbsoluteIndex(slidingWindow.absoluteIndex() + identifierLength);

                return kind;
            }
        };

        Scanner.prototype.slowScanIdentifierOrKeyword = function (diagnostics) {
            var startIndex = this.slidingWindow.absoluteIndex();
            var sawUnicodeEscape = false;

            do {
                var unicodeEscape = this.scanCharOrUnicodeEscape(diagnostics);
                sawUnicodeEscape = sawUnicodeEscape || unicodeEscape;
            } while(this.isIdentifierPart(this.peekCharOrUnicodeEscape()));

            var length = this.slidingWindow.absoluteIndex() - startIndex;
            var text = this.text.substr(startIndex, length, false);
            var valueText = TypeScript.Syntax.massageEscapes(text);

            var keywordKind = TypeScript.SyntaxFacts.getTokenKind(valueText);
            if (keywordKind >= 15 /* FirstKeyword */ && keywordKind <= 69 /* LastKeyword */) {
                if (sawUnicodeEscape) {
                    return keywordKind | -2147483648 /* IsVariableWidthKeyword */;
                } else {
                    return keywordKind;
                }
            }

            return 11 /* IdentifierName */;
        };

        Scanner.prototype.scanNumericLiteral = function (diagnostics) {
            if (this.isHexNumericLiteral()) {
                this.scanHexNumericLiteral();
            } else if (this.isOctalNumericLiteral()) {
                this.scanOctalNumericLiteral(diagnostics);
            } else {
                this.scanDecimalNumericLiteral();
            }

            return 13 /* NumericLiteral */;
        };

        Scanner.prototype.isOctalNumericLiteral = function () {
            return this.currentCharCode() === 48 /* _0 */ && TypeScript.CharacterInfo.isOctalDigit(this.slidingWindow.peekItemN(1));
        };

        Scanner.prototype.scanOctalNumericLiteral = function (diagnostics) {
            var position = this.absoluteIndex();

            while (TypeScript.CharacterInfo.isOctalDigit(this.currentCharCode())) {
                this.slidingWindow.moveToNextItem();
            }

            if (this.languageVersion() >= 1 /* EcmaScript5 */) {
                diagnostics.push(new TypeScript.Diagnostic(this.fileName, this.text.lineMap(), position, this.absoluteIndex() - position, TypeScript.DiagnosticCode.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher, null));
            }
        };

        Scanner.prototype.scanDecimalDigits = function () {
            while (TypeScript.CharacterInfo.isDecimalDigit(this.currentCharCode())) {
                this.slidingWindow.moveToNextItem();
            }
        };

        Scanner.prototype.scanDecimalNumericLiteral = function () {
            this.scanDecimalDigits();

            if (this.currentCharCode() === 46 /* dot */) {
                this.slidingWindow.moveToNextItem();
            }

            this.scanDecimalDigits();

            var ch = this.currentCharCode();
            if (ch === 101 /* e */ || ch === 69 /* E */) {
                var nextChar1 = this.slidingWindow.peekItemN(1);

                if (TypeScript.CharacterInfo.isDecimalDigit(nextChar1)) {
                    this.slidingWindow.moveToNextItem();
                    this.scanDecimalDigits();
                } else if (nextChar1 === 45 /* minus */ || nextChar1 === 43 /* plus */) {
                    var nextChar2 = this.slidingWindow.peekItemN(2);
                    if (TypeScript.CharacterInfo.isDecimalDigit(nextChar2)) {
                        this.slidingWindow.moveToNextItem();
                        this.slidingWindow.moveToNextItem();
                        this.scanDecimalDigits();
                    }
                }
            }
        };

        Scanner.prototype.scanHexNumericLiteral = function () {
            this.slidingWindow.moveToNextItem();
            this.slidingWindow.moveToNextItem();

            while (TypeScript.CharacterInfo.isHexDigit(this.currentCharCode())) {
                this.slidingWindow.moveToNextItem();
            }
        };

        Scanner.prototype.isHexNumericLiteral = function () {
            if (this.currentCharCode() === 48 /* _0 */) {
                var ch = this.slidingWindow.peekItemN(1);

                if (ch === 120 /* x */ || ch === 88 /* X */) {
                    ch = this.slidingWindow.peekItemN(2);

                    return TypeScript.CharacterInfo.isHexDigit(ch);
                }
            }

            return false;
        };

        Scanner.prototype.advanceAndSetTokenKind = function (kind) {
            this.slidingWindow.moveToNextItem();
            return kind;
        };

        Scanner.prototype.scanLessThanToken = function () {
            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 82 /* LessThanEqualsToken */;
            } else if (this.currentCharCode() === 60 /* lessThan */) {
                this.slidingWindow.moveToNextItem();
                if (this.currentCharCode() === 61 /* equals */) {
                    this.slidingWindow.moveToNextItem();
                    return 112 /* LessThanLessThanEqualsToken */;
                } else {
                    return 95 /* LessThanLessThanToken */;
                }
            } else {
                return 80 /* LessThanToken */;
            }
        };

        Scanner.prototype.scanBarToken = function () {
            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 116 /* BarEqualsToken */;
            } else if (this.currentCharCode() === 124 /* bar */) {
                this.slidingWindow.moveToNextItem();
                return 104 /* BarBarToken */;
            } else {
                return 99 /* BarToken */;
            }
        };

        Scanner.prototype.scanCaretToken = function () {
            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 117 /* CaretEqualsToken */;
            } else {
                return 100 /* CaretToken */;
            }
        };

        Scanner.prototype.scanAmpersandToken = function () {
            this.slidingWindow.moveToNextItem();
            var character = this.currentCharCode();
            if (character === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 115 /* AmpersandEqualsToken */;
            } else if (this.currentCharCode() === 38 /* ampersand */) {
                this.slidingWindow.moveToNextItem();
                return 103 /* AmpersandAmpersandToken */;
            } else {
                return 98 /* AmpersandToken */;
            }
        };

        Scanner.prototype.scanPercentToken = function () {
            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 111 /* PercentEqualsToken */;
            } else {
                return 92 /* PercentToken */;
            }
        };

        Scanner.prototype.scanMinusToken = function () {
            this.slidingWindow.moveToNextItem();
            var character = this.currentCharCode();

            if (character === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 109 /* MinusEqualsToken */;
            } else if (character === 45 /* minus */) {
                this.slidingWindow.moveToNextItem();
                return 94 /* MinusMinusToken */;
            } else {
                return 90 /* MinusToken */;
            }
        };

        Scanner.prototype.scanPlusToken = function () {
            this.slidingWindow.moveToNextItem();
            var character = this.currentCharCode();
            if (character === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 108 /* PlusEqualsToken */;
            } else if (character === 43 /* plus */) {
                this.slidingWindow.moveToNextItem();
                return 93 /* PlusPlusToken */;
            } else {
                return 89 /* PlusToken */;
            }
        };

        Scanner.prototype.scanAsteriskToken = function () {
            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 110 /* AsteriskEqualsToken */;
            } else {
                return 91 /* AsteriskToken */;
            }
        };

        Scanner.prototype.scanEqualsToken = function () {
            this.slidingWindow.moveToNextItem();
            var character = this.currentCharCode();
            if (character === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();

                if (this.currentCharCode() === 61 /* equals */) {
                    this.slidingWindow.moveToNextItem();

                    return 87 /* EqualsEqualsEqualsToken */;
                } else {
                    return 84 /* EqualsEqualsToken */;
                }
            } else if (character === 62 /* greaterThan */) {
                this.slidingWindow.moveToNextItem();
                return 85 /* EqualsGreaterThanToken */;
            } else {
                return 107 /* EqualsToken */;
            }
        };

        Scanner.prototype.isDotPrefixedNumericLiteral = function () {
            if (this.currentCharCode() === 46 /* dot */) {
                var ch = this.slidingWindow.peekItemN(1);
                return TypeScript.CharacterInfo.isDecimalDigit(ch);
            }

            return false;
        };

        Scanner.prototype.scanDotToken = function (diagnostics) {
            if (this.isDotPrefixedNumericLiteral()) {
                return this.scanNumericLiteral(diagnostics);
            }

            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 46 /* dot */ && this.slidingWindow.peekItemN(1) === 46 /* dot */) {
                this.slidingWindow.moveToNextItem();
                this.slidingWindow.moveToNextItem();
                return 77 /* DotDotDotToken */;
            } else {
                return 76 /* DotToken */;
            }
        };

        Scanner.prototype.scanSlashToken = function (allowRegularExpression) {
            if (allowRegularExpression) {
                var result = this.tryScanRegularExpressionToken();
                if (result !== 0 /* None */) {
                    return result;
                }
            }

            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();
                return 119 /* SlashEqualsToken */;
            } else {
                return 118 /* SlashToken */;
            }
        };

        Scanner.prototype.tryScanRegularExpressionToken = function () {
            var startIndex = this.slidingWindow.getAndPinAbsoluteIndex();

            this.slidingWindow.moveToNextItem();

            var inEscape = false;
            var inCharacterClass = false;
            while (true) {
                var ch = this.currentCharCode();

                if (this.isNewLineCharacter(ch) || this.slidingWindow.isAtEndOfSource()) {
                    this.slidingWindow.rewindToPinnedIndex(startIndex);
                    this.slidingWindow.releaseAndUnpinAbsoluteIndex(startIndex);
                    return 0 /* None */;
                }

                this.slidingWindow.moveToNextItem();
                if (inEscape) {
                    inEscape = false;
                    continue;
                }

                switch (ch) {
                    case 92 /* backslash */:
                        inEscape = true;
                        continue;

                    case 91 /* openBracket */:
                        inCharacterClass = true;
                        continue;

                    case 93 /* closeBracket */:
                        inCharacterClass = false;
                        continue;

                    case 47 /* slash */:
                        if (inCharacterClass) {
                            continue;
                        }

                        break;

                    default:
                        continue;
                }

                break;
            }

            while (isIdentifierPartCharacter[this.currentCharCode()]) {
                this.slidingWindow.moveToNextItem();
            }

            this.slidingWindow.releaseAndUnpinAbsoluteIndex(startIndex);
            return 12 /* RegularExpressionLiteral */;
        };

        Scanner.prototype.scanExclamationToken = function () {
            this.slidingWindow.moveToNextItem();
            if (this.currentCharCode() === 61 /* equals */) {
                this.slidingWindow.moveToNextItem();

                if (this.currentCharCode() === 61 /* equals */) {
                    this.slidingWindow.moveToNextItem();

                    return 88 /* ExclamationEqualsEqualsToken */;
                } else {
                    return 86 /* ExclamationEqualsToken */;
                }
            } else {
                return 101 /* ExclamationToken */;
            }
        };

        Scanner.prototype.scanDefaultCharacter = function (character, diagnostics) {
            var position = this.slidingWindow.absoluteIndex();
            this.slidingWindow.moveToNextItem();

            var text = String.fromCharCode(character);
            var messageText = this.getErrorMessageText(text);
            diagnostics.push(new TypeScript.Diagnostic(this.fileName, this.text.lineMap(), position, 1, TypeScript.DiagnosticCode.Unexpected_character_0, [messageText]));

            return 9 /* ErrorToken */;
        };

        Scanner.prototype.getErrorMessageText = function (text) {
            if (text === "\\") {
                return '"\\"';
            }

            return JSON.stringify(text);
        };

        Scanner.prototype.skipEscapeSequence = function (diagnostics) {
            var rewindPoint = this.slidingWindow.getAndPinAbsoluteIndex();

            this.slidingWindow.moveToNextItem();

            var ch = this.currentCharCode();
            this.slidingWindow.moveToNextItem();
            switch (ch) {
                case 120 /* x */:
                case 117 /* u */:
                    this.slidingWindow.rewindToPinnedIndex(rewindPoint);
                    var value = this.scanUnicodeOrHexEscape(diagnostics);
                    break;

                case 13 /* carriageReturn */:
                    if (this.currentCharCode() === 10 /* lineFeed */) {
                        this.slidingWindow.moveToNextItem();
                    }
                    break;

                default:
                    break;
            }

            this.slidingWindow.releaseAndUnpinAbsoluteIndex(rewindPoint);
        };

        Scanner.prototype.scanStringLiteral = function (diagnostics) {
            var quoteCharacter = this.currentCharCode();

            this.slidingWindow.moveToNextItem();

            while (true) {
                var ch = this.currentCharCode();
                if (ch === 92 /* backslash */) {
                    this.skipEscapeSequence(diagnostics);
                } else if (ch === quoteCharacter) {
                    this.slidingWindow.moveToNextItem();
                    break;
                } else if (this.isNewLineCharacter(ch) || this.slidingWindow.isAtEndOfSource()) {
                    diagnostics.push(new TypeScript.Diagnostic(this.fileName, this.text.lineMap(), TypeScript.MathPrototype.min(this.slidingWindow.absoluteIndex(), this.text.length()), 1, TypeScript.DiagnosticCode.Missing_close_quote_character, null));
                    break;
                } else {
                    this.slidingWindow.moveToNextItem();
                }
            }

            return 14 /* StringLiteral */;
        };

        Scanner.prototype.isUnicodeEscape = function (character) {
            if (character === 92 /* backslash */) {
                var ch2 = this.slidingWindow.peekItemN(1);
                if (ch2 === 117 /* u */) {
                    return true;
                }
            }

            return false;
        };

        Scanner.prototype.peekCharOrUnicodeEscape = function () {
            var character = this.currentCharCode();
            if (this.isUnicodeEscape(character)) {
                return this.peekUnicodeOrHexEscape();
            } else {
                return character;
            }
        };

        Scanner.prototype.peekUnicodeOrHexEscape = function () {
            var startIndex = this.slidingWindow.getAndPinAbsoluteIndex();

            var ch = this.scanUnicodeOrHexEscape(null);

            this.slidingWindow.rewindToPinnedIndex(startIndex);
            this.slidingWindow.releaseAndUnpinAbsoluteIndex(startIndex);

            return ch;
        };

        Scanner.prototype.scanCharOrUnicodeEscape = function (errors) {
            var ch = this.currentCharCode();
            if (ch === 92 /* backslash */) {
                var ch2 = this.slidingWindow.peekItemN(1);
                if (ch2 === 117 /* u */) {
                    this.scanUnicodeOrHexEscape(errors);
                    return true;
                }
            }

            this.slidingWindow.moveToNextItem();
            return false;
        };

        Scanner.prototype.scanUnicodeOrHexEscape = function (errors) {
            var start = this.slidingWindow.absoluteIndex();
            var character = this.currentCharCode();

            this.slidingWindow.moveToNextItem();

            character = this.currentCharCode();

            var intChar = 0;
            this.slidingWindow.moveToNextItem();

            var count = character === 117 /* u */ ? 4 : 2;

            for (var i = 0; i < count; i++) {
                var ch2 = this.currentCharCode();
                if (!TypeScript.CharacterInfo.isHexDigit(ch2)) {
                    if (errors !== null) {
                        var end = this.slidingWindow.absoluteIndex();
                        var info = this.createIllegalEscapeDiagnostic(start, end);
                        errors.push(info);
                    }

                    break;
                }

                intChar = (intChar << 4) + TypeScript.CharacterInfo.hexValue(ch2);
                this.slidingWindow.moveToNextItem();
            }

            return intChar;
        };

        Scanner.prototype.substring = function (start, end, intern) {
            var length = end - start;
            var offset = start - this.slidingWindow.windowAbsoluteStartIndex;

            if (intern) {
                return TypeScript.Collections.DefaultStringTable.addCharArray(this.slidingWindow.window, offset, length);
            } else {
                return TypeScript.StringUtilities.fromCharCodeArray(this.slidingWindow.window.slice(offset, offset + length));
            }
        };

        Scanner.prototype.createIllegalEscapeDiagnostic = function (start, end) {
            return new TypeScript.Diagnostic(this.fileName, this.text.lineMap(), start, end - start, TypeScript.DiagnosticCode.Unrecognized_escape_sequence, null);
        };

        Scanner.isValidIdentifier = function (text, languageVersion) {
            var scanner = new Scanner(null, text, languageVersion, Scanner.triviaWindow);
            var errors = new Array();
            var token = scanner.scan(errors, false);

            return errors.length === 0 && TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(token) && token.width() === text.length();
        };
        Scanner.triviaWindow = TypeScript.ArrayUtilities.createArray(2048, 0);
        return Scanner;
    })();
    TypeScript.Scanner = Scanner;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var ScannerUtilities = (function () {
        function ScannerUtilities() {
        }
        ScannerUtilities.identifierKind = function (array, startIndex, length) {
            switch (length) {
                case 2:
                    switch (array[startIndex]) {
                        case 100 /* d */:
                            return (array[startIndex + 1] === 111 /* o */) ? 22 /* DoKeyword */ : 11 /* IdentifierName */;
                        case 105 /* i */:
                            switch (array[startIndex + 1]) {
                                case 102 /* f */:
                                    return 28 /* IfKeyword */;
                                case 110 /* n */:
                                    return 29 /* InKeyword */;
                                default:
                                    return 11 /* IdentifierName */;
                            }

                        default:
                            return 11 /* IdentifierName */;
                    }

                case 3:
                    switch (array[startIndex]) {
                        case 102 /* f */:
                            return (array[startIndex + 1] === 111 /* o */ && array[startIndex + 2] === 114 /* r */) ? 26 /* ForKeyword */ : 11 /* IdentifierName */;
                        case 110 /* n */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 119 /* w */) ? 31 /* NewKeyword */ : 11 /* IdentifierName */;
                        case 116 /* t */:
                            return (array[startIndex + 1] === 114 /* r */ && array[startIndex + 2] === 121 /* y */) ? 38 /* TryKeyword */ : 11 /* IdentifierName */;
                        case 118 /* v */:
                            return (array[startIndex + 1] === 97 /* a */ && array[startIndex + 2] === 114 /* r */) ? 40 /* VarKeyword */ : 11 /* IdentifierName */;
                        case 108 /* l */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 116 /* t */) ? 53 /* LetKeyword */ : 11 /* IdentifierName */;
                        case 97 /* a */:
                            return (array[startIndex + 1] === 110 /* n */ && array[startIndex + 2] === 121 /* y */) ? 60 /* AnyKeyword */ : 11 /* IdentifierName */;
                        case 103 /* g */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 116 /* t */) ? 64 /* GetKeyword */ : 11 /* IdentifierName */;
                        case 115 /* s */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 116 /* t */) ? 68 /* SetKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 4:
                    switch (array[startIndex]) {
                        case 99 /* c */:
                            return (array[startIndex + 1] === 97 /* a */ && array[startIndex + 2] === 115 /* s */ && array[startIndex + 3] === 101 /* e */) ? 16 /* CaseKeyword */ : 11 /* IdentifierName */;
                        case 101 /* e */:
                            switch (array[startIndex + 1]) {
                                case 108 /* l */:
                                    return (array[startIndex + 2] === 115 /* s */ && array[startIndex + 3] === 101 /* e */) ? 23 /* ElseKeyword */ : 11 /* IdentifierName */;
                                case 110 /* n */:
                                    return (array[startIndex + 2] === 117 /* u */ && array[startIndex + 3] === 109 /* m */) ? 46 /* EnumKeyword */ : 11 /* IdentifierName */;
                                default:
                                    return 11 /* IdentifierName */;
                            }

                        case 110 /* n */:
                            return (array[startIndex + 1] === 117 /* u */ && array[startIndex + 2] === 108 /* l */ && array[startIndex + 3] === 108 /* l */) ? 32 /* NullKeyword */ : 11 /* IdentifierName */;
                        case 116 /* t */:
                            switch (array[startIndex + 1]) {
                                case 104 /* h */:
                                    return (array[startIndex + 2] === 105 /* i */ && array[startIndex + 3] === 115 /* s */) ? 35 /* ThisKeyword */ : 11 /* IdentifierName */;
                                case 114 /* r */:
                                    return (array[startIndex + 2] === 117 /* u */ && array[startIndex + 3] === 101 /* e */) ? 37 /* TrueKeyword */ : 11 /* IdentifierName */;
                                default:
                                    return 11 /* IdentifierName */;
                            }

                        case 118 /* v */:
                            return (array[startIndex + 1] === 111 /* o */ && array[startIndex + 2] === 105 /* i */ && array[startIndex + 3] === 100 /* d */) ? 41 /* VoidKeyword */ : 11 /* IdentifierName */;
                        case 119 /* w */:
                            return (array[startIndex + 1] === 105 /* i */ && array[startIndex + 2] === 116 /* t */ && array[startIndex + 3] === 104 /* h */) ? 43 /* WithKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 5:
                    switch (array[startIndex]) {
                        case 98 /* b */:
                            return (array[startIndex + 1] === 114 /* r */ && array[startIndex + 2] === 101 /* e */ && array[startIndex + 3] === 97 /* a */ && array[startIndex + 4] === 107 /* k */) ? 15 /* BreakKeyword */ : 11 /* IdentifierName */;
                        case 99 /* c */:
                            switch (array[startIndex + 1]) {
                                case 97 /* a */:
                                    return (array[startIndex + 2] === 116 /* t */ && array[startIndex + 3] === 99 /* c */ && array[startIndex + 4] === 104 /* h */) ? 17 /* CatchKeyword */ : 11 /* IdentifierName */;
                                case 108 /* l */:
                                    return (array[startIndex + 2] === 97 /* a */ && array[startIndex + 3] === 115 /* s */ && array[startIndex + 4] === 115 /* s */) ? 44 /* ClassKeyword */ : 11 /* IdentifierName */;
                                case 111 /* o */:
                                    return (array[startIndex + 2] === 110 /* n */ && array[startIndex + 3] === 115 /* s */ && array[startIndex + 4] === 116 /* t */) ? 45 /* ConstKeyword */ : 11 /* IdentifierName */;
                                default:
                                    return 11 /* IdentifierName */;
                            }

                        case 102 /* f */:
                            return (array[startIndex + 1] === 97 /* a */ && array[startIndex + 2] === 108 /* l */ && array[startIndex + 3] === 115 /* s */ && array[startIndex + 4] === 101 /* e */) ? 24 /* FalseKeyword */ : 11 /* IdentifierName */;
                        case 116 /* t */:
                            return (array[startIndex + 1] === 104 /* h */ && array[startIndex + 2] === 114 /* r */ && array[startIndex + 3] === 111 /* o */ && array[startIndex + 4] === 119 /* w */) ? 36 /* ThrowKeyword */ : 11 /* IdentifierName */;
                        case 119 /* w */:
                            return (array[startIndex + 1] === 104 /* h */ && array[startIndex + 2] === 105 /* i */ && array[startIndex + 3] === 108 /* l */ && array[startIndex + 4] === 101 /* e */) ? 42 /* WhileKeyword */ : 11 /* IdentifierName */;
                        case 115 /* s */:
                            return (array[startIndex + 1] === 117 /* u */ && array[startIndex + 2] === 112 /* p */ && array[startIndex + 3] === 101 /* e */ && array[startIndex + 4] === 114 /* r */) ? 50 /* SuperKeyword */ : 11 /* IdentifierName */;
                        case 121 /* y */:
                            return (array[startIndex + 1] === 105 /* i */ && array[startIndex + 2] === 101 /* e */ && array[startIndex + 3] === 108 /* l */ && array[startIndex + 4] === 100 /* d */) ? 59 /* YieldKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 6:
                    switch (array[startIndex]) {
                        case 100 /* d */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 108 /* l */ && array[startIndex + 3] === 101 /* e */ && array[startIndex + 4] === 116 /* t */ && array[startIndex + 5] === 101 /* e */) ? 21 /* DeleteKeyword */ : 11 /* IdentifierName */;
                        case 114 /* r */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 116 /* t */ && array[startIndex + 3] === 117 /* u */ && array[startIndex + 4] === 114 /* r */ && array[startIndex + 5] === 110 /* n */) ? 33 /* ReturnKeyword */ : 11 /* IdentifierName */;
                        case 115 /* s */:
                            switch (array[startIndex + 1]) {
                                case 119 /* w */:
                                    return (array[startIndex + 2] === 105 /* i */ && array[startIndex + 3] === 116 /* t */ && array[startIndex + 4] === 99 /* c */ && array[startIndex + 5] === 104 /* h */) ? 34 /* SwitchKeyword */ : 11 /* IdentifierName */;
                                case 116 /* t */:
                                    switch (array[startIndex + 2]) {
                                        case 97 /* a */:
                                            return (array[startIndex + 3] === 116 /* t */ && array[startIndex + 4] === 105 /* i */ && array[startIndex + 5] === 99 /* c */) ? 58 /* StaticKeyword */ : 11 /* IdentifierName */;
                                        case 114 /* r */:
                                            return (array[startIndex + 3] === 105 /* i */ && array[startIndex + 4] === 110 /* n */ && array[startIndex + 5] === 103 /* g */) ? 69 /* StringKeyword */ : 11 /* IdentifierName */;
                                        default:
                                            return 11 /* IdentifierName */;
                                    }

                                default:
                                    return 11 /* IdentifierName */;
                            }

                        case 116 /* t */:
                            return (array[startIndex + 1] === 121 /* y */ && array[startIndex + 2] === 112 /* p */ && array[startIndex + 3] === 101 /* e */ && array[startIndex + 4] === 111 /* o */ && array[startIndex + 5] === 102 /* f */) ? 39 /* TypeOfKeyword */ : 11 /* IdentifierName */;
                        case 101 /* e */:
                            return (array[startIndex + 1] === 120 /* x */ && array[startIndex + 2] === 112 /* p */ && array[startIndex + 3] === 111 /* o */ && array[startIndex + 4] === 114 /* r */ && array[startIndex + 5] === 116 /* t */) ? 47 /* ExportKeyword */ : 11 /* IdentifierName */;
                        case 105 /* i */:
                            return (array[startIndex + 1] === 109 /* m */ && array[startIndex + 2] === 112 /* p */ && array[startIndex + 3] === 111 /* o */ && array[startIndex + 4] === 114 /* r */ && array[startIndex + 5] === 116 /* t */) ? 49 /* ImportKeyword */ : 11 /* IdentifierName */;
                        case 112 /* p */:
                            return (array[startIndex + 1] === 117 /* u */ && array[startIndex + 2] === 98 /* b */ && array[startIndex + 3] === 108 /* l */ && array[startIndex + 4] === 105 /* i */ && array[startIndex + 5] === 99 /* c */) ? 57 /* PublicKeyword */ : 11 /* IdentifierName */;
                        case 109 /* m */:
                            return (array[startIndex + 1] === 111 /* o */ && array[startIndex + 2] === 100 /* d */ && array[startIndex + 3] === 117 /* u */ && array[startIndex + 4] === 108 /* l */ && array[startIndex + 5] === 101 /* e */) ? 65 /* ModuleKeyword */ : 11 /* IdentifierName */;
                        case 110 /* n */:
                            return (array[startIndex + 1] === 117 /* u */ && array[startIndex + 2] === 109 /* m */ && array[startIndex + 3] === 98 /* b */ && array[startIndex + 4] === 101 /* e */ && array[startIndex + 5] === 114 /* r */) ? 67 /* NumberKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 7:
                    switch (array[startIndex]) {
                        case 100 /* d */:
                            switch (array[startIndex + 1]) {
                                case 101 /* e */:
                                    switch (array[startIndex + 2]) {
                                        case 102 /* f */:
                                            return (array[startIndex + 3] === 97 /* a */ && array[startIndex + 4] === 117 /* u */ && array[startIndex + 5] === 108 /* l */ && array[startIndex + 6] === 116 /* t */) ? 20 /* DefaultKeyword */ : 11 /* IdentifierName */;
                                        case 99 /* c */:
                                            return (array[startIndex + 3] === 108 /* l */ && array[startIndex + 4] === 97 /* a */ && array[startIndex + 5] === 114 /* r */ && array[startIndex + 6] === 101 /* e */) ? 63 /* DeclareKeyword */ : 11 /* IdentifierName */;
                                        default:
                                            return 11 /* IdentifierName */;
                                    }

                                default:
                                    return 11 /* IdentifierName */;
                            }

                        case 102 /* f */:
                            return (array[startIndex + 1] === 105 /* i */ && array[startIndex + 2] === 110 /* n */ && array[startIndex + 3] === 97 /* a */ && array[startIndex + 4] === 108 /* l */ && array[startIndex + 5] === 108 /* l */ && array[startIndex + 6] === 121 /* y */) ? 25 /* FinallyKeyword */ : 11 /* IdentifierName */;
                        case 101 /* e */:
                            return (array[startIndex + 1] === 120 /* x */ && array[startIndex + 2] === 116 /* t */ && array[startIndex + 3] === 101 /* e */ && array[startIndex + 4] === 110 /* n */ && array[startIndex + 5] === 100 /* d */ && array[startIndex + 6] === 115 /* s */) ? 48 /* ExtendsKeyword */ : 11 /* IdentifierName */;
                        case 112 /* p */:
                            switch (array[startIndex + 1]) {
                                case 97 /* a */:
                                    return (array[startIndex + 2] === 99 /* c */ && array[startIndex + 3] === 107 /* k */ && array[startIndex + 4] === 97 /* a */ && array[startIndex + 5] === 103 /* g */ && array[startIndex + 6] === 101 /* e */) ? 54 /* PackageKeyword */ : 11 /* IdentifierName */;
                                case 114 /* r */:
                                    return (array[startIndex + 2] === 105 /* i */ && array[startIndex + 3] === 118 /* v */ && array[startIndex + 4] === 97 /* a */ && array[startIndex + 5] === 116 /* t */ && array[startIndex + 6] === 101 /* e */) ? 55 /* PrivateKeyword */ : 11 /* IdentifierName */;
                                default:
                                    return 11 /* IdentifierName */;
                            }

                        case 98 /* b */:
                            return (array[startIndex + 1] === 111 /* o */ && array[startIndex + 2] === 111 /* o */ && array[startIndex + 3] === 108 /* l */ && array[startIndex + 4] === 101 /* e */ && array[startIndex + 5] === 97 /* a */ && array[startIndex + 6] === 110 /* n */) ? 61 /* BooleanKeyword */ : 11 /* IdentifierName */;
                        case 114 /* r */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 113 /* q */ && array[startIndex + 3] === 117 /* u */ && array[startIndex + 4] === 105 /* i */ && array[startIndex + 5] === 114 /* r */ && array[startIndex + 6] === 101 /* e */) ? 66 /* RequireKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 8:
                    switch (array[startIndex]) {
                        case 99 /* c */:
                            return (array[startIndex + 1] === 111 /* o */ && array[startIndex + 2] === 110 /* n */ && array[startIndex + 3] === 116 /* t */ && array[startIndex + 4] === 105 /* i */ && array[startIndex + 5] === 110 /* n */ && array[startIndex + 6] === 117 /* u */ && array[startIndex + 7] === 101 /* e */) ? 18 /* ContinueKeyword */ : 11 /* IdentifierName */;
                        case 100 /* d */:
                            return (array[startIndex + 1] === 101 /* e */ && array[startIndex + 2] === 98 /* b */ && array[startIndex + 3] === 117 /* u */ && array[startIndex + 4] === 103 /* g */ && array[startIndex + 5] === 103 /* g */ && array[startIndex + 6] === 101 /* e */ && array[startIndex + 7] === 114 /* r */) ? 19 /* DebuggerKeyword */ : 11 /* IdentifierName */;
                        case 102 /* f */:
                            return (array[startIndex + 1] === 117 /* u */ && array[startIndex + 2] === 110 /* n */ && array[startIndex + 3] === 99 /* c */ && array[startIndex + 4] === 116 /* t */ && array[startIndex + 5] === 105 /* i */ && array[startIndex + 6] === 111 /* o */ && array[startIndex + 7] === 110 /* n */) ? 27 /* FunctionKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 9:
                    switch (array[startIndex]) {
                        case 105 /* i */:
                            return (array[startIndex + 1] === 110 /* n */ && array[startIndex + 2] === 116 /* t */ && array[startIndex + 3] === 101 /* e */ && array[startIndex + 4] === 114 /* r */ && array[startIndex + 5] === 102 /* f */ && array[startIndex + 6] === 97 /* a */ && array[startIndex + 7] === 99 /* c */ && array[startIndex + 8] === 101 /* e */) ? 52 /* InterfaceKeyword */ : 11 /* IdentifierName */;
                        case 112 /* p */:
                            return (array[startIndex + 1] === 114 /* r */ && array[startIndex + 2] === 111 /* o */ && array[startIndex + 3] === 116 /* t */ && array[startIndex + 4] === 101 /* e */ && array[startIndex + 5] === 99 /* c */ && array[startIndex + 6] === 116 /* t */ && array[startIndex + 7] === 101 /* e */ && array[startIndex + 8] === 100 /* d */) ? 56 /* ProtectedKeyword */ : 11 /* IdentifierName */;
                        default:
                            return 11 /* IdentifierName */;
                    }

                case 10:
                    switch (array[startIndex]) {
                        case 105 /* i */:
                            switch (array[startIndex + 1]) {
                                case 110 /* n */:
                                    return (array[startIndex + 2] === 115 /* s */ && array[startIndex + 3] === 116 /* t */ && array[startIndex + 4] === 97 /* a */ && array[startIndex + 5] === 110 /* n */ && array[startIndex + 6] === 99 /* c */ && array[startIndex + 7] === 101 /* e */ && array[startIndex + 8] === 111 /* o */ && array[startIndex + 9] === 102 /* f */) ? 30 /* InstanceOfKeyword */ : 11 /* IdentifierName */;
                                case 109 /* m */:
                                    return (array[startIndex + 2] === 112 /* p */ && array[startIndex + 3] === 108 /* l */ && array[startIndex + 4] === 101 /* e */ && array[startIndex + 5] === 109 /* m */ && array[startIndex + 6] === 101 /* e */ && array[startIndex + 7] === 110 /* n */ && array[startIndex + 8] === 116 /* t */ && array[startIndex + 9] === 115 /* s */) ? 51 /* ImplementsKeyword */ : 11 /* IdentifierName */;
                                default:
                                    return 11 /* IdentifierName */;
                            }

                        default:
                            return 11 /* IdentifierName */;
                    }

                case 11:
                    return (array[startIndex] === 99 /* c */ && array[startIndex + 1] === 111 /* o */ && array[startIndex + 2] === 110 /* n */ && array[startIndex + 3] === 115 /* s */ && array[startIndex + 4] === 116 /* t */ && array[startIndex + 5] === 114 /* r */ && array[startIndex + 6] === 117 /* u */ && array[startIndex + 7] === 99 /* c */ && array[startIndex + 8] === 116 /* t */ && array[startIndex + 9] === 111 /* o */ && array[startIndex + 10] === 114 /* r */) ? 62 /* ConstructorKeyword */ : 11 /* IdentifierName */;
                default:
                    return 11 /* IdentifierName */;
            }
        };
        return ScannerUtilities;
    })();
    TypeScript.ScannerUtilities = ScannerUtilities;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        var EmptySeparatedSyntaxList = (function () {
            function EmptySeparatedSyntaxList() {
            }
            EmptySeparatedSyntaxList.prototype.kind = function () {
                return 2 /* SeparatedList */;
            };

            EmptySeparatedSyntaxList.prototype.isNode = function () {
                return false;
            };

            EmptySeparatedSyntaxList.prototype.isToken = function () {
                return false;
            };

            EmptySeparatedSyntaxList.prototype.isList = function () {
                return false;
            };

            EmptySeparatedSyntaxList.prototype.isSeparatedList = function () {
                return true;
            };

            EmptySeparatedSyntaxList.prototype.toJSON = function (key) {
                return [];
            };

            EmptySeparatedSyntaxList.prototype.childCount = function () {
                return 0;
            };

            EmptySeparatedSyntaxList.prototype.nonSeparatorCount = function () {
                return 0;
            };

            EmptySeparatedSyntaxList.prototype.separatorCount = function () {
                return 0;
            };

            EmptySeparatedSyntaxList.prototype.toArray = function () {
                return [];
            };

            EmptySeparatedSyntaxList.prototype.toNonSeparatorArray = function () {
                return [];
            };

            EmptySeparatedSyntaxList.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            EmptySeparatedSyntaxList.prototype.nonSeparatorAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            EmptySeparatedSyntaxList.prototype.separatorAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            EmptySeparatedSyntaxList.prototype.collectTextElements = function (elements) {
            };

            EmptySeparatedSyntaxList.prototype.firstToken = function () {
                return null;
            };

            EmptySeparatedSyntaxList.prototype.lastToken = function () {
                return null;
            };

            EmptySeparatedSyntaxList.prototype.fullWidth = function () {
                return 0;
            };

            EmptySeparatedSyntaxList.prototype.fullText = function () {
                return "";
            };

            EmptySeparatedSyntaxList.prototype.width = function () {
                return 0;
            };

            EmptySeparatedSyntaxList.prototype.isTypeScriptSpecific = function () {
                return false;
            };

            EmptySeparatedSyntaxList.prototype.isIncrementallyUnusable = function () {
                return false;
            };

            EmptySeparatedSyntaxList.prototype.findTokenInternal = function (parent, position, fullStart) {
                throw TypeScript.Errors.invalidOperation();
            };

            EmptySeparatedSyntaxList.prototype.insertChildrenInto = function (array, index) {
            };

            EmptySeparatedSyntaxList.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            EmptySeparatedSyntaxList.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            EmptySeparatedSyntaxList.prototype.leadingTriviaWidth = function () {
                return 0;
            };

            EmptySeparatedSyntaxList.prototype.trailingTriviaWidth = function () {
                return 0;
            };
            return EmptySeparatedSyntaxList;
        })();

        Syntax.emptySeparatedList = new EmptySeparatedSyntaxList();

        var SingletonSeparatedSyntaxList = (function () {
            function SingletonSeparatedSyntaxList(item) {
                this.item = item;
            }
            SingletonSeparatedSyntaxList.prototype.toJSON = function (key) {
                return [this.item];
            };

            SingletonSeparatedSyntaxList.prototype.kind = function () {
                return 2 /* SeparatedList */;
            };

            SingletonSeparatedSyntaxList.prototype.isNode = function () {
                return false;
            };
            SingletonSeparatedSyntaxList.prototype.isToken = function () {
                return false;
            };
            SingletonSeparatedSyntaxList.prototype.isList = function () {
                return false;
            };
            SingletonSeparatedSyntaxList.prototype.isSeparatedList = function () {
                return true;
            };

            SingletonSeparatedSyntaxList.prototype.childCount = function () {
                return 1;
            };
            SingletonSeparatedSyntaxList.prototype.nonSeparatorCount = function () {
                return 1;
            };
            SingletonSeparatedSyntaxList.prototype.separatorCount = function () {
                return 0;
            };

            SingletonSeparatedSyntaxList.prototype.toArray = function () {
                return [this.item];
            };
            SingletonSeparatedSyntaxList.prototype.toNonSeparatorArray = function () {
                return [this.item];
            };

            SingletonSeparatedSyntaxList.prototype.childAt = function (index) {
                if (index !== 0) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.item;
            };

            SingletonSeparatedSyntaxList.prototype.nonSeparatorAt = function (index) {
                if (index !== 0) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.item;
            };

            SingletonSeparatedSyntaxList.prototype.separatorAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            SingletonSeparatedSyntaxList.prototype.collectTextElements = function (elements) {
                this.item.collectTextElements(elements);
            };

            SingletonSeparatedSyntaxList.prototype.firstToken = function () {
                return this.item.firstToken();
            };

            SingletonSeparatedSyntaxList.prototype.lastToken = function () {
                return this.item.lastToken();
            };

            SingletonSeparatedSyntaxList.prototype.fullWidth = function () {
                return this.item.fullWidth();
            };

            SingletonSeparatedSyntaxList.prototype.width = function () {
                return this.item.width();
            };

            SingletonSeparatedSyntaxList.prototype.fullText = function () {
                return this.item.fullText();
            };

            SingletonSeparatedSyntaxList.prototype.leadingTrivia = function () {
                return this.item.leadingTrivia();
            };

            SingletonSeparatedSyntaxList.prototype.trailingTrivia = function () {
                return this.item.trailingTrivia();
            };

            SingletonSeparatedSyntaxList.prototype.leadingTriviaWidth = function () {
                return this.item.leadingTriviaWidth();
            };

            SingletonSeparatedSyntaxList.prototype.trailingTriviaWidth = function () {
                return this.item.trailingTriviaWidth();
            };

            SingletonSeparatedSyntaxList.prototype.isTypeScriptSpecific = function () {
                return this.item.isTypeScriptSpecific();
            };

            SingletonSeparatedSyntaxList.prototype.isIncrementallyUnusable = function () {
                return this.item.isIncrementallyUnusable();
            };

            SingletonSeparatedSyntaxList.prototype.findTokenInternal = function (parent, position, fullStart) {
                return this.item.findTokenInternal(new TypeScript.PositionedSeparatedList(parent, this, fullStart), position, fullStart);
            };

            SingletonSeparatedSyntaxList.prototype.insertChildrenInto = function (array, index) {
                array.splice(index, 0, this.item);
            };
            return SingletonSeparatedSyntaxList;
        })();

        var NormalSeparatedSyntaxList = (function () {
            function NormalSeparatedSyntaxList(elements) {
                this._data = 0;
                this.elements = elements;
            }
            NormalSeparatedSyntaxList.prototype.kind = function () {
                return 2 /* SeparatedList */;
            };

            NormalSeparatedSyntaxList.prototype.isToken = function () {
                return false;
            };
            NormalSeparatedSyntaxList.prototype.isNode = function () {
                return false;
            };
            NormalSeparatedSyntaxList.prototype.isList = function () {
                return false;
            };
            NormalSeparatedSyntaxList.prototype.isSeparatedList = function () {
                return true;
            };
            NormalSeparatedSyntaxList.prototype.toJSON = function (key) {
                return this.elements;
            };

            NormalSeparatedSyntaxList.prototype.childCount = function () {
                return this.elements.length;
            };
            NormalSeparatedSyntaxList.prototype.nonSeparatorCount = function () {
                return TypeScript.IntegerUtilities.integerDivide(this.elements.length + 1, 2);
            };
            NormalSeparatedSyntaxList.prototype.separatorCount = function () {
                return TypeScript.IntegerUtilities.integerDivide(this.elements.length, 2);
            };

            NormalSeparatedSyntaxList.prototype.toArray = function () {
                return this.elements.slice(0);
            };

            NormalSeparatedSyntaxList.prototype.toNonSeparatorArray = function () {
                var result = [];
                for (var i = 0, n = this.nonSeparatorCount(); i < n; i++) {
                    result.push(this.nonSeparatorAt(i));
                }

                return result;
            };

            NormalSeparatedSyntaxList.prototype.childAt = function (index) {
                if (index < 0 || index >= this.elements.length) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.elements[index];
            };

            NormalSeparatedSyntaxList.prototype.nonSeparatorAt = function (index) {
                var value = index * 2;
                if (value < 0 || value >= this.elements.length) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.elements[value];
            };

            NormalSeparatedSyntaxList.prototype.separatorAt = function (index) {
                var value = index * 2 + 1;
                if (value < 0 || value >= this.elements.length) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.elements[value];
            };

            NormalSeparatedSyntaxList.prototype.firstToken = function () {
                var token;
                for (var i = 0, n = this.elements.length; i < n; i++) {
                    if (i % 2 === 0) {
                        var nodeOrToken = this.elements[i];
                        token = nodeOrToken.firstToken();
                        if (token !== null) {
                            return token;
                        }
                    } else {
                        token = this.elements[i];
                        if (token.width() > 0) {
                            return token;
                        }
                    }
                }

                return null;
            };

            NormalSeparatedSyntaxList.prototype.lastToken = function () {
                var token;
                for (var i = this.elements.length - 1; i >= 0; i--) {
                    if (i % 2 === 0) {
                        var nodeOrToken = this.elements[i];
                        token = nodeOrToken.lastToken();
                        if (token !== null) {
                            return token;
                        }
                    } else {
                        token = this.elements[i];
                        if (token.width() > 0) {
                            return token;
                        }
                    }
                }

                return null;
            };

            NormalSeparatedSyntaxList.prototype.fullText = function () {
                var elements = [];
                this.collectTextElements(elements);
                return elements.join("");
            };

            NormalSeparatedSyntaxList.prototype.isTypeScriptSpecific = function () {
                for (var i = 0, n = this.nonSeparatorCount(); i < n; i++) {
                    if (this.nonSeparatorAt(i).isTypeScriptSpecific()) {
                        return true;
                    }
                }

                return false;
            };

            NormalSeparatedSyntaxList.prototype.isIncrementallyUnusable = function () {
                return (this.data() & 2 /* NodeIncrementallyUnusableMask */) !== 0;
            };

            NormalSeparatedSyntaxList.prototype.fullWidth = function () {
                return this.data() >>> 3 /* NodeFullWidthShift */;
            };

            NormalSeparatedSyntaxList.prototype.width = function () {
                var fullWidth = this.fullWidth();
                return fullWidth - this.leadingTriviaWidth() - this.trailingTriviaWidth();
            };

            NormalSeparatedSyntaxList.prototype.leadingTrivia = function () {
                return this.firstToken().leadingTrivia();
            };

            NormalSeparatedSyntaxList.prototype.trailingTrivia = function () {
                return this.lastToken().trailingTrivia();
            };

            NormalSeparatedSyntaxList.prototype.leadingTriviaWidth = function () {
                return this.firstToken().leadingTriviaWidth();
            };

            NormalSeparatedSyntaxList.prototype.trailingTriviaWidth = function () {
                return this.lastToken().trailingTriviaWidth();
            };

            NormalSeparatedSyntaxList.prototype.computeData = function () {
                var fullWidth = 0;
                var isIncrementallyUnusable = false;

                for (var i = 0, n = this.elements.length; i < n; i++) {
                    var element = this.elements[i];

                    var childWidth = element.fullWidth();
                    fullWidth += childWidth;

                    isIncrementallyUnusable = isIncrementallyUnusable || element.isIncrementallyUnusable();
                }

                return (fullWidth << 3 /* NodeFullWidthShift */) | (isIncrementallyUnusable ? 2 /* NodeIncrementallyUnusableMask */ : 0) | 1 /* NodeDataComputed */;
            };

            NormalSeparatedSyntaxList.prototype.data = function () {
                if ((this._data & 1 /* NodeDataComputed */) === 0) {
                    this._data = this.computeData();
                }

                return this._data;
            };

            NormalSeparatedSyntaxList.prototype.findTokenInternal = function (parent, position, fullStart) {
                parent = new TypeScript.PositionedSeparatedList(parent, this, fullStart);
                for (var i = 0, n = this.elements.length; i < n; i++) {
                    var element = this.elements[i];

                    var childWidth = element.fullWidth();
                    if (position < childWidth) {
                        return element.findTokenInternal(parent, position, fullStart);
                    }

                    position -= childWidth;
                    fullStart += childWidth;
                }

                throw TypeScript.Errors.invalidOperation();
            };

            NormalSeparatedSyntaxList.prototype.collectTextElements = function (elements) {
                for (var i = 0, n = this.elements.length; i < n; i++) {
                    var element = this.elements[i];
                    element.collectTextElements(elements);
                }
            };

            NormalSeparatedSyntaxList.prototype.insertChildrenInto = function (array, index) {
                if (index === 0) {
                    array.unshift.apply(array, this.elements);
                } else {
                    array.splice.apply(array, [index, 0].concat(this.elements));
                }
            };
            return NormalSeparatedSyntaxList;
        })();

        function separatedList(nodes) {
            return separatedListAndValidate(nodes, false);
        }
        Syntax.separatedList = separatedList;

        function separatedListAndValidate(nodes, validate) {
            if (nodes === undefined || nodes === null || nodes.length === 0) {
                return Syntax.emptySeparatedList;
            }

            if (validate) {
                for (var i = 0; i < nodes.length; i++) {
                    var item = nodes[i];

                    if (i % 2 === 1) {
                    }
                }
            }

            if (nodes.length === 1) {
                return new SingletonSeparatedSyntaxList(nodes[0]);
            }

            return new NormalSeparatedSyntaxList(nodes);
        }
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SlidingWindow = (function () {
        function SlidingWindow(source, window, defaultValue, sourceLength) {
            if (typeof sourceLength === "undefined") { sourceLength = -1; }
            this.source = source;
            this.window = window;
            this.defaultValue = defaultValue;
            this.sourceLength = sourceLength;
            this.windowCount = 0;
            this.windowAbsoluteStartIndex = 0;
            this.currentRelativeItemIndex = 0;
            this._pinCount = 0;
            this.firstPinnedAbsoluteIndex = -1;
        }
        SlidingWindow.prototype.windowAbsoluteEndIndex = function () {
            return this.windowAbsoluteStartIndex + this.windowCount;
        };

        SlidingWindow.prototype.addMoreItemsToWindow = function (argument) {
            if (this.sourceLength >= 0 && this.absoluteIndex() >= this.sourceLength) {
                return false;
            }

            if (this.windowCount >= this.window.length) {
                this.tryShiftOrGrowWindow();
            }

            var spaceAvailable = this.window.length - this.windowCount;
            var amountFetched = this.source.fetchMoreItems(argument, this.windowAbsoluteEndIndex(), this.window, this.windowCount, spaceAvailable);

            this.windowCount += amountFetched;
            return amountFetched > 0;
        };

        SlidingWindow.prototype.tryShiftOrGrowWindow = function () {
            var currentIndexIsPastWindowHalfwayPoint = this.currentRelativeItemIndex > (this.window.length >>> 1);

            var isAllowedToShift = this.firstPinnedAbsoluteIndex === -1 || this.firstPinnedAbsoluteIndex > this.windowAbsoluteStartIndex;

            if (currentIndexIsPastWindowHalfwayPoint && isAllowedToShift) {
                var shiftStartIndex = this.firstPinnedAbsoluteIndex === -1 ? this.currentRelativeItemIndex : this.firstPinnedAbsoluteIndex - this.windowAbsoluteStartIndex;

                var shiftCount = this.windowCount - shiftStartIndex;

                if (shiftCount > 0) {
                    TypeScript.ArrayUtilities.copy(this.window, shiftStartIndex, this.window, 0, shiftCount);
                }

                this.windowAbsoluteStartIndex += shiftStartIndex;

                this.windowCount -= shiftStartIndex;

                this.currentRelativeItemIndex -= shiftStartIndex;
            } else {
                TypeScript.ArrayUtilities.grow(this.window, this.window.length * 2, this.defaultValue);
            }
        };

        SlidingWindow.prototype.absoluteIndex = function () {
            return this.windowAbsoluteStartIndex + this.currentRelativeItemIndex;
        };

        SlidingWindow.prototype.isAtEndOfSource = function () {
            return this.absoluteIndex() >= this.sourceLength;
        };

        SlidingWindow.prototype.getAndPinAbsoluteIndex = function () {
            var absoluteIndex = this.absoluteIndex();
            var pinCount = this._pinCount++;
            if (pinCount === 0) {
                this.firstPinnedAbsoluteIndex = absoluteIndex;
            }

            return absoluteIndex;
        };

        SlidingWindow.prototype.releaseAndUnpinAbsoluteIndex = function (absoluteIndex) {
            this._pinCount--;
            if (this._pinCount === 0) {
                this.firstPinnedAbsoluteIndex = -1;
            }
        };

        SlidingWindow.prototype.rewindToPinnedIndex = function (absoluteIndex) {
            var relativeIndex = absoluteIndex - this.windowAbsoluteStartIndex;

            this.currentRelativeItemIndex = relativeIndex;
        };

        SlidingWindow.prototype.currentItem = function (argument) {
            if (this.currentRelativeItemIndex >= this.windowCount) {
                if (!this.addMoreItemsToWindow(argument)) {
                    return this.defaultValue;
                }
            }

            return this.window[this.currentRelativeItemIndex];
        };

        SlidingWindow.prototype.peekItemN = function (n) {
            while (this.currentRelativeItemIndex + n >= this.windowCount) {
                if (!this.addMoreItemsToWindow(null)) {
                    return this.defaultValue;
                }
            }

            return this.window[this.currentRelativeItemIndex + n];
        };

        SlidingWindow.prototype.moveToNextItem = function () {
            this.currentRelativeItemIndex++;
        };

        SlidingWindow.prototype.disgardAllItemsFromCurrentIndexOnwards = function () {
            this.windowCount = this.currentRelativeItemIndex;
        };

        SlidingWindow.prototype.setAbsoluteIndex = function (absoluteIndex) {
            if (this.absoluteIndex() === absoluteIndex) {
                return;
            }

            if (this._pinCount > 0) {
            }

            if (absoluteIndex >= this.windowAbsoluteStartIndex && absoluteIndex < this.windowAbsoluteEndIndex()) {
                this.currentRelativeItemIndex = (absoluteIndex - this.windowAbsoluteStartIndex);
            } else {
                this.windowAbsoluteStartIndex = absoluteIndex;

                this.windowCount = 0;

                this.currentRelativeItemIndex = 0;
            }
        };

        SlidingWindow.prototype.pinCount = function () {
            return this._pinCount;
        };
        return SlidingWindow;
    })();
    TypeScript.SlidingWindow = SlidingWindow;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        function emptySourceUnit() {
            return Syntax.normalModeFactory.sourceUnit(Syntax.emptyList, Syntax.token(10 /* EndOfFileToken */, { text: "" }));
        }
        Syntax.emptySourceUnit = emptySourceUnit;

        function getStandaloneExpression(positionedToken) {
            var token = positionedToken.token();
            if (positionedToken !== null && positionedToken.kind() === 11 /* IdentifierName */) {
                var parentPositionedNode = positionedToken.containingNode();
                var parentNode = parentPositionedNode.node();

                if (parentNode.kind() === 121 /* QualifiedName */ && parentNode.right === token) {
                    return parentPositionedNode;
                } else if (parentNode.kind() === 212 /* MemberAccessExpression */ && parentNode.name === token) {
                    return parentPositionedNode;
                }
            }

            return positionedToken;
        }
        Syntax.getStandaloneExpression = getStandaloneExpression;

        function isInModuleOrTypeContext(positionedToken) {
            if (positionedToken !== null) {
                var positionedNodeOrToken = Syntax.getStandaloneExpression(positionedToken);
                var parent = positionedNodeOrToken.containingNode();

                if (parent !== null) {
                    switch (parent.kind()) {
                        case 246 /* ModuleNameModuleReference */:
                            return true;
                        case 121 /* QualifiedName */:
                            return true;
                        default:
                            return isInTypeOnlyContext(positionedToken);
                    }
                }
            }

            return false;
        }
        Syntax.isInModuleOrTypeContext = isInModuleOrTypeContext;

        function isInTypeOnlyContext(positionedToken) {
            var positionedNodeOrToken = Syntax.getStandaloneExpression(positionedToken);
            var positionedParent = positionedNodeOrToken.containingNode();

            var parent = positionedParent.node();
            var nodeOrToken = positionedNodeOrToken.nodeOrToken();

            if (parent !== null) {
                switch (parent.kind()) {
                    case 124 /* ArrayType */:
                        return parent.type === nodeOrToken;
                    case 220 /* CastExpression */:
                        return parent.type === nodeOrToken;
                    case 244 /* TypeAnnotation */:
                    case 230 /* ExtendsHeritageClause */:
                    case 231 /* ImplementsHeritageClause */:
                    case 228 /* TypeArgumentList */:
                        return true;
                }
            }

            return false;
        }
        Syntax.isInTypeOnlyContext = isInTypeOnlyContext;

        function childOffset(parent, child) {
            var offset = 0;
            for (var i = 0, n = parent.childCount(); i < n; i++) {
                var current = parent.childAt(i);
                if (current === child) {
                    return offset;
                }

                if (current !== null) {
                    offset += current.fullWidth();
                }
            }

            throw TypeScript.Errors.invalidOperation();
        }
        Syntax.childOffset = childOffset;

        function childOffsetAt(parent, index) {
            var offset = 0;
            for (var i = 0; i < index; i++) {
                var current = parent.childAt(i);
                if (current !== null) {
                    offset += current.fullWidth();
                }
            }

            return offset;
        }
        Syntax.childOffsetAt = childOffsetAt;

        function childIndex(parent, child) {
            for (var i = 0, n = parent.childCount(); i < n; i++) {
                var current = parent.childAt(i);
                if (current === child) {
                    return i;
                }
            }

            throw TypeScript.Errors.invalidOperation();
        }
        Syntax.childIndex = childIndex;

        function nodeStructuralEquals(node1, node2) {
            if (node1 === null) {
                return node2 === null;
            }

            return node1.structuralEquals(node2);
        }
        Syntax.nodeStructuralEquals = nodeStructuralEquals;

        function nodeOrTokenStructuralEquals(node1, node2) {
            if (node1 === node2) {
                return true;
            }

            if (node1 === null || node2 === null) {
                return false;
            }

            if (node1.isToken()) {
                return node2.isToken() ? tokenStructuralEquals(node1, node2) : false;
            }

            return node2.isNode() ? nodeStructuralEquals(node1, node2) : false;
        }
        Syntax.nodeOrTokenStructuralEquals = nodeOrTokenStructuralEquals;

        function tokenStructuralEquals(token1, token2) {
            if (token1 === token2) {
                return true;
            }

            if (token1 === null || token2 === null) {
                return false;
            }

            return token1.kind() === token2.kind() && token1.width() === token2.width() && token1.fullWidth() === token2.fullWidth() && token1.text() === token2.text() && Syntax.triviaListStructuralEquals(token1.leadingTrivia(), token2.leadingTrivia()) && Syntax.triviaListStructuralEquals(token1.trailingTrivia(), token2.trailingTrivia());
        }
        Syntax.tokenStructuralEquals = tokenStructuralEquals;

        function triviaListStructuralEquals(triviaList1, triviaList2) {
            if (triviaList1.count() !== triviaList2.count()) {
                return false;
            }

            for (var i = 0, n = triviaList1.count(); i < n; i++) {
                if (!Syntax.triviaStructuralEquals(triviaList1.syntaxTriviaAt(i), triviaList2.syntaxTriviaAt(i))) {
                    return false;
                }
            }

            return true;
        }
        Syntax.triviaListStructuralEquals = triviaListStructuralEquals;

        function triviaStructuralEquals(trivia1, trivia2) {
            return trivia1.kind() === trivia2.kind() && trivia1.fullWidth() === trivia2.fullWidth() && trivia1.fullText() === trivia2.fullText();
        }
        Syntax.triviaStructuralEquals = triviaStructuralEquals;

        function listStructuralEquals(list1, list2) {
            if (list1.childCount() !== list2.childCount()) {
                return false;
            }

            for (var i = 0, n = list1.childCount(); i < n; i++) {
                var child1 = list1.childAt(i);
                var child2 = list2.childAt(i);

                if (!Syntax.nodeOrTokenStructuralEquals(child1, child2)) {
                    return false;
                }
            }

            return true;
        }
        Syntax.listStructuralEquals = listStructuralEquals;

        function separatedListStructuralEquals(list1, list2) {
            if (list1.childCount() !== list2.childCount()) {
                return false;
            }

            for (var i = 0, n = list1.childCount(); i < n; i++) {
                var element1 = list1.childAt(i);
                var element2 = list2.childAt(i);
                if (!Syntax.nodeOrTokenStructuralEquals(element1, element2)) {
                    return false;
                }
            }

            return true;
        }
        Syntax.separatedListStructuralEquals = separatedListStructuralEquals;

        function elementStructuralEquals(element1, element2) {
            if (element1 === element2) {
                return true;
            }

            if (element1 === null || element2 === null) {
                return false;
            }

            if (element2.kind() !== element2.kind()) {
                return false;
            }

            if (element1.isToken()) {
                return tokenStructuralEquals(element1, element2);
            } else if (element1.isNode()) {
                return nodeStructuralEquals(element1, element2);
            } else if (element1.isList()) {
                return listStructuralEquals(element1, element2);
            } else if (element1.isSeparatedList()) {
                return separatedListStructuralEquals(element1, element2);
            }

            throw TypeScript.Errors.invalidOperation();
        }
        Syntax.elementStructuralEquals = elementStructuralEquals;

        function identifierName(text, info) {
            if (typeof info === "undefined") { info = null; }
            return Syntax.identifier(text);
        }
        Syntax.identifierName = identifierName;

        function trueExpression() {
            return Syntax.token(37 /* TrueKeyword */);
        }
        Syntax.trueExpression = trueExpression;

        function falseExpression() {
            return Syntax.token(24 /* FalseKeyword */);
        }
        Syntax.falseExpression = falseExpression;

        function numericLiteralExpression(text) {
            return Syntax.token(13 /* NumericLiteral */, { text: text });
        }
        Syntax.numericLiteralExpression = numericLiteralExpression;

        function stringLiteralExpression(text) {
            return Syntax.token(14 /* StringLiteral */, { text: text });
        }
        Syntax.stringLiteralExpression = stringLiteralExpression;

        function isSuperInvocationExpression(node) {
            return node.kind() === 213 /* InvocationExpression */ && node.expression.kind() === 50 /* SuperKeyword */;
        }
        Syntax.isSuperInvocationExpression = isSuperInvocationExpression;

        function isSuperInvocationExpressionStatement(node) {
            return node.kind() === 149 /* ExpressionStatement */ && isSuperInvocationExpression(node.expression);
        }
        Syntax.isSuperInvocationExpressionStatement = isSuperInvocationExpressionStatement;

        function isSuperMemberAccessExpression(node) {
            return node.kind() === 212 /* MemberAccessExpression */ && node.expression.kind() === 50 /* SuperKeyword */;
        }
        Syntax.isSuperMemberAccessExpression = isSuperMemberAccessExpression;

        function isSuperMemberAccessInvocationExpression(node) {
            return node.kind() === 213 /* InvocationExpression */ && isSuperMemberAccessExpression(node.expression);
        }
        Syntax.isSuperMemberAccessInvocationExpression = isSuperMemberAccessInvocationExpression;

        function assignmentExpression(left, token, right) {
            return Syntax.normalModeFactory.binaryExpression(174 /* AssignmentExpression */, left, token, right);
        }
        Syntax.assignmentExpression = assignmentExpression;

        function nodeHasSkippedOrMissingTokens(node) {
            for (var i = 0; i < node.childCount(); i++) {
                var child = node.childAt(i);
                if (child !== null && child.isToken()) {
                    var token = child;

                    if (token.hasSkippedToken() || (token.width() === 0 && token.kind() !== 10 /* EndOfFileToken */)) {
                        return true;
                    }
                }
            }
            return false;
        }
        Syntax.nodeHasSkippedOrMissingTokens = nodeHasSkippedOrMissingTokens;

        function isUnterminatedStringLiteral(token) {
            if (token && token.kind() === 14 /* StringLiteral */) {
                var text = token.text();
                return text.length < 2 || text.charCodeAt(text.length - 1) !== text.charCodeAt(0);
            }

            return false;
        }
        Syntax.isUnterminatedStringLiteral = isUnterminatedStringLiteral;

        function isUnterminatedMultilineCommentTrivia(trivia) {
            if (trivia && trivia.kind() === 6 /* MultiLineCommentTrivia */) {
                var text = trivia.fullText();
                return text.length < 4 || text.substring(text.length - 2) !== "*/";
            }
            return false;
        }
        Syntax.isUnterminatedMultilineCommentTrivia = isUnterminatedMultilineCommentTrivia;

        function isEntirelyInsideCommentTrivia(trivia, fullStart, position) {
            if (trivia && trivia.isComment() && position > fullStart) {
                var end = fullStart + trivia.fullWidth();
                if (position < end) {
                    return true;
                } else if (position === end) {
                    return trivia.kind() === 7 /* SingleLineCommentTrivia */ || isUnterminatedMultilineCommentTrivia(trivia);
                }
            }

            return false;
        }
        Syntax.isEntirelyInsideCommentTrivia = isEntirelyInsideCommentTrivia;

        function isEntirelyInsideComment(sourceUnit, position) {
            var positionedToken = sourceUnit.findToken(position);
            var fullStart = positionedToken.fullStart();
            var triviaList = null;
            var lastTriviaBeforeToken = null;

            if (positionedToken.kind() === 10 /* EndOfFileToken */) {
                if (positionedToken.token().hasLeadingTrivia()) {
                    triviaList = positionedToken.token().leadingTrivia();
                } else {
                    positionedToken = positionedToken.previousToken();
                    if (positionedToken) {
                        if (positionedToken && positionedToken.token().hasTrailingTrivia()) {
                            triviaList = positionedToken.token().trailingTrivia();
                            fullStart = positionedToken.end();
                        }
                    }
                }
            } else {
                if (position <= (fullStart + positionedToken.token().leadingTriviaWidth())) {
                    triviaList = positionedToken.token().leadingTrivia();
                } else if (position >= (fullStart + positionedToken.token().width())) {
                    triviaList = positionedToken.token().trailingTrivia();
                    fullStart = positionedToken.end();
                }
            }

            if (triviaList) {
                for (var i = 0, n = triviaList.count(); i < n; i++) {
                    var trivia = triviaList.syntaxTriviaAt(i);
                    if (position <= fullStart) {
                        break;
                    } else if (position <= fullStart + trivia.fullWidth() && trivia.isComment()) {
                        lastTriviaBeforeToken = trivia;
                        break;
                    }

                    fullStart += trivia.fullWidth();
                }
            }

            return lastTriviaBeforeToken && isEntirelyInsideCommentTrivia(lastTriviaBeforeToken, fullStart, position);
        }
        Syntax.isEntirelyInsideComment = isEntirelyInsideComment;

        function isEntirelyInStringOrRegularExpressionLiteral(sourceUnit, position) {
            var positionedToken = sourceUnit.findToken(position);

            if (positionedToken) {
                if (positionedToken.kind() === 10 /* EndOfFileToken */) {
                    positionedToken = positionedToken.previousToken();
                    return positionedToken && positionedToken.token().trailingTriviaWidth() === 0 && isUnterminatedStringLiteral(positionedToken.token());
                } else if (position > positionedToken.start()) {
                    return (position < positionedToken.end() && (positionedToken.kind() === 14 /* StringLiteral */ || positionedToken.kind() === 12 /* RegularExpressionLiteral */)) || (position <= positionedToken.end() && isUnterminatedStringLiteral(positionedToken.token()));
                }
            }

            return false;
        }
        Syntax.isEntirelyInStringOrRegularExpressionLiteral = isEntirelyInStringOrRegularExpressionLiteral;

        function findSkippedTokenInTriviaList(positionedToken, position, lookInLeadingTriviaList) {
            var triviaList = null;
            var fullStart;

            if (lookInLeadingTriviaList) {
                triviaList = positionedToken.token().leadingTrivia();
                fullStart = positionedToken.fullStart();
            } else {
                triviaList = positionedToken.token().trailingTrivia();
                fullStart = positionedToken.end();
            }

            if (triviaList && triviaList.hasSkippedToken()) {
                for (var i = 0, n = triviaList.count(); i < n; i++) {
                    var trivia = triviaList.syntaxTriviaAt(i);
                    var triviaWidth = trivia.fullWidth();

                    if (trivia.isSkippedToken() && position >= fullStart && position <= fullStart + triviaWidth) {
                        return new TypeScript.PositionedSkippedToken(positionedToken, trivia.skippedToken(), fullStart);
                    }

                    fullStart += triviaWidth;
                }
            }

            return null;
        }

        function findSkippedTokenOnLeftInTriviaList(positionedToken, position, lookInLeadingTriviaList) {
            var triviaList = null;
            var fullEnd;

            if (lookInLeadingTriviaList) {
                triviaList = positionedToken.token().leadingTrivia();
                fullEnd = positionedToken.fullStart() + triviaList.fullWidth();
            } else {
                triviaList = positionedToken.token().trailingTrivia();
                fullEnd = positionedToken.fullEnd();
            }

            if (triviaList && triviaList.hasSkippedToken()) {
                for (var i = triviaList.count() - 1; i >= 0; i--) {
                    var trivia = triviaList.syntaxTriviaAt(i);
                    var triviaWidth = trivia.fullWidth();

                    if (trivia.isSkippedToken() && position >= fullEnd) {
                        return new TypeScript.PositionedSkippedToken(positionedToken, trivia.skippedToken(), fullEnd - triviaWidth);
                    }

                    fullEnd -= triviaWidth;
                }
            }

            return null;
        }

        function findSkippedTokenInLeadingTriviaList(positionedToken, position) {
            return findSkippedTokenInTriviaList(positionedToken, position, true);
        }
        Syntax.findSkippedTokenInLeadingTriviaList = findSkippedTokenInLeadingTriviaList;

        function findSkippedTokenInTrailingTriviaList(positionedToken, position) {
            return findSkippedTokenInTriviaList(positionedToken, position, false);
        }
        Syntax.findSkippedTokenInTrailingTriviaList = findSkippedTokenInTrailingTriviaList;

        function findSkippedTokenInPositionedToken(positionedToken, position) {
            var positionInLeadingTriviaList = (position < positionedToken.start());
            return findSkippedTokenInTriviaList(positionedToken, position, positionInLeadingTriviaList);
        }
        Syntax.findSkippedTokenInPositionedToken = findSkippedTokenInPositionedToken;

        function findSkippedTokenOnLeft(positionedToken, position) {
            var positionInLeadingTriviaList = (position < positionedToken.start());
            return findSkippedTokenOnLeftInTriviaList(positionedToken, position, positionInLeadingTriviaList);
        }
        Syntax.findSkippedTokenOnLeft = findSkippedTokenOnLeft;

        function getAncestorOfKind(positionedToken, kind) {
            while (positionedToken && positionedToken.parent()) {
                if (positionedToken.parent().kind() === kind) {
                    return positionedToken.parent();
                }

                positionedToken = positionedToken.parent();
            }

            return null;
        }
        Syntax.getAncestorOfKind = getAncestorOfKind;

        function hasAncestorOfKind(positionedToken, kind) {
            return Syntax.getAncestorOfKind(positionedToken, kind) !== null;
        }
        Syntax.hasAncestorOfKind = hasAncestorOfKind;

        function isIntegerLiteral(expression) {
            if (expression) {
                switch (expression.kind()) {
                    case 164 /* PlusExpression */:
                    case 165 /* NegateExpression */:
                        expression = expression.operand;
                        return expression.isToken() && TypeScript.IntegerUtilities.isInteger(expression.text());

                    case 13 /* NumericLiteral */:
                        var text = expression.text();
                        return TypeScript.IntegerUtilities.isInteger(text) || TypeScript.IntegerUtilities.isHexInteger(text);
                }
            }

            return false;
        }
        Syntax.isIntegerLiteral = isIntegerLiteral;
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        var NormalModeFactory = (function () {
            function NormalModeFactory() {
            }
            NormalModeFactory.prototype.sourceUnit = function (moduleElements, endOfFileToken) {
                return new TypeScript.SourceUnitSyntax(moduleElements, endOfFileToken, false);
            };
            NormalModeFactory.prototype.externalModuleReference = function (requireKeyword, openParenToken, stringLiteral, closeParenToken) {
                return new TypeScript.ExternalModuleReferenceSyntax(requireKeyword, openParenToken, stringLiteral, closeParenToken, false);
            };
            NormalModeFactory.prototype.moduleNameModuleReference = function (moduleName) {
                return new TypeScript.ModuleNameModuleReferenceSyntax(moduleName, false);
            };
            NormalModeFactory.prototype.importDeclaration = function (modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken) {
                return new TypeScript.ImportDeclarationSyntax(modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken, false);
            };
            NormalModeFactory.prototype.exportAssignment = function (exportKeyword, equalsToken, identifier, semicolonToken) {
                return new TypeScript.ExportAssignmentSyntax(exportKeyword, equalsToken, identifier, semicolonToken, false);
            };
            NormalModeFactory.prototype.classDeclaration = function (modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken) {
                return new TypeScript.ClassDeclarationSyntax(modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken, false);
            };
            NormalModeFactory.prototype.interfaceDeclaration = function (modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body) {
                return new TypeScript.InterfaceDeclarationSyntax(modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body, false);
            };
            NormalModeFactory.prototype.heritageClause = function (kind, extendsOrImplementsKeyword, typeNames) {
                return new TypeScript.HeritageClauseSyntax(kind, extendsOrImplementsKeyword, typeNames, false);
            };
            NormalModeFactory.prototype.moduleDeclaration = function (modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken) {
                return new TypeScript.ModuleDeclarationSyntax(modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken, false);
            };
            NormalModeFactory.prototype.functionDeclaration = function (modifiers, functionKeyword, identifier, callSignature, block, semicolonToken) {
                return new TypeScript.FunctionDeclarationSyntax(modifiers, functionKeyword, identifier, callSignature, block, semicolonToken, false);
            };
            NormalModeFactory.prototype.variableStatement = function (modifiers, variableDeclaration, semicolonToken) {
                return new TypeScript.VariableStatementSyntax(modifiers, variableDeclaration, semicolonToken, false);
            };
            NormalModeFactory.prototype.variableDeclaration = function (varKeyword, variableDeclarators) {
                return new TypeScript.VariableDeclarationSyntax(varKeyword, variableDeclarators, false);
            };
            NormalModeFactory.prototype.variableDeclarator = function (propertyName, typeAnnotation, equalsValueClause) {
                return new TypeScript.VariableDeclaratorSyntax(propertyName, typeAnnotation, equalsValueClause, false);
            };
            NormalModeFactory.prototype.equalsValueClause = function (equalsToken, value) {
                return new TypeScript.EqualsValueClauseSyntax(equalsToken, value, false);
            };
            NormalModeFactory.prototype.prefixUnaryExpression = function (kind, operatorToken, operand) {
                return new TypeScript.PrefixUnaryExpressionSyntax(kind, operatorToken, operand, false);
            };
            NormalModeFactory.prototype.arrayLiteralExpression = function (openBracketToken, expressions, closeBracketToken) {
                return new TypeScript.ArrayLiteralExpressionSyntax(openBracketToken, expressions, closeBracketToken, false);
            };
            NormalModeFactory.prototype.omittedExpression = function () {
                return new TypeScript.OmittedExpressionSyntax(false);
            };
            NormalModeFactory.prototype.parenthesizedExpression = function (openParenToken, expression, closeParenToken) {
                return new TypeScript.ParenthesizedExpressionSyntax(openParenToken, expression, closeParenToken, false);
            };
            NormalModeFactory.prototype.simpleArrowFunctionExpression = function (identifier, equalsGreaterThanToken, block, expression) {
                return new TypeScript.SimpleArrowFunctionExpressionSyntax(identifier, equalsGreaterThanToken, block, expression, false);
            };
            NormalModeFactory.prototype.parenthesizedArrowFunctionExpression = function (callSignature, equalsGreaterThanToken, block, expression) {
                return new TypeScript.ParenthesizedArrowFunctionExpressionSyntax(callSignature, equalsGreaterThanToken, block, expression, false);
            };
            NormalModeFactory.prototype.qualifiedName = function (left, dotToken, right) {
                return new TypeScript.QualifiedNameSyntax(left, dotToken, right, false);
            };
            NormalModeFactory.prototype.typeArgumentList = function (lessThanToken, typeArguments, greaterThanToken) {
                return new TypeScript.TypeArgumentListSyntax(lessThanToken, typeArguments, greaterThanToken, false);
            };
            NormalModeFactory.prototype.constructorType = function (newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type) {
                return new TypeScript.ConstructorTypeSyntax(newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type, false);
            };
            NormalModeFactory.prototype.functionType = function (typeParameterList, parameterList, equalsGreaterThanToken, type) {
                return new TypeScript.FunctionTypeSyntax(typeParameterList, parameterList, equalsGreaterThanToken, type, false);
            };
            NormalModeFactory.prototype.objectType = function (openBraceToken, typeMembers, closeBraceToken) {
                return new TypeScript.ObjectTypeSyntax(openBraceToken, typeMembers, closeBraceToken, false);
            };
            NormalModeFactory.prototype.arrayType = function (type, openBracketToken, closeBracketToken) {
                return new TypeScript.ArrayTypeSyntax(type, openBracketToken, closeBracketToken, false);
            };
            NormalModeFactory.prototype.genericType = function (name, typeArgumentList) {
                return new TypeScript.GenericTypeSyntax(name, typeArgumentList, false);
            };
            NormalModeFactory.prototype.typeQuery = function (typeOfKeyword, name) {
                return new TypeScript.TypeQuerySyntax(typeOfKeyword, name, false);
            };
            NormalModeFactory.prototype.typeAnnotation = function (colonToken, type) {
                return new TypeScript.TypeAnnotationSyntax(colonToken, type, false);
            };
            NormalModeFactory.prototype.block = function (openBraceToken, statements, closeBraceToken) {
                return new TypeScript.BlockSyntax(openBraceToken, statements, closeBraceToken, false);
            };
            NormalModeFactory.prototype.parameter = function (dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause) {
                return new TypeScript.ParameterSyntax(dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause, false);
            };
            NormalModeFactory.prototype.memberAccessExpression = function (expression, dotToken, name) {
                return new TypeScript.MemberAccessExpressionSyntax(expression, dotToken, name, false);
            };
            NormalModeFactory.prototype.postfixUnaryExpression = function (kind, operand, operatorToken) {
                return new TypeScript.PostfixUnaryExpressionSyntax(kind, operand, operatorToken, false);
            };
            NormalModeFactory.prototype.elementAccessExpression = function (expression, openBracketToken, argumentExpression, closeBracketToken) {
                return new TypeScript.ElementAccessExpressionSyntax(expression, openBracketToken, argumentExpression, closeBracketToken, false);
            };
            NormalModeFactory.prototype.invocationExpression = function (expression, argumentList) {
                return new TypeScript.InvocationExpressionSyntax(expression, argumentList, false);
            };
            NormalModeFactory.prototype.argumentList = function (typeArgumentList, openParenToken, _arguments, closeParenToken) {
                return new TypeScript.ArgumentListSyntax(typeArgumentList, openParenToken, _arguments, closeParenToken, false);
            };
            NormalModeFactory.prototype.binaryExpression = function (kind, left, operatorToken, right) {
                return new TypeScript.BinaryExpressionSyntax(kind, left, operatorToken, right, false);
            };
            NormalModeFactory.prototype.conditionalExpression = function (condition, questionToken, whenTrue, colonToken, whenFalse) {
                return new TypeScript.ConditionalExpressionSyntax(condition, questionToken, whenTrue, colonToken, whenFalse, false);
            };
            NormalModeFactory.prototype.constructSignature = function (newKeyword, callSignature) {
                return new TypeScript.ConstructSignatureSyntax(newKeyword, callSignature, false);
            };
            NormalModeFactory.prototype.methodSignature = function (propertyName, questionToken, callSignature) {
                return new TypeScript.MethodSignatureSyntax(propertyName, questionToken, callSignature, false);
            };
            NormalModeFactory.prototype.indexSignature = function (openBracketToken, parameter, closeBracketToken, typeAnnotation) {
                return new TypeScript.IndexSignatureSyntax(openBracketToken, parameter, closeBracketToken, typeAnnotation, false);
            };
            NormalModeFactory.prototype.propertySignature = function (propertyName, questionToken, typeAnnotation) {
                return new TypeScript.PropertySignatureSyntax(propertyName, questionToken, typeAnnotation, false);
            };
            NormalModeFactory.prototype.callSignature = function (typeParameterList, parameterList, typeAnnotation) {
                return new TypeScript.CallSignatureSyntax(typeParameterList, parameterList, typeAnnotation, false);
            };
            NormalModeFactory.prototype.parameterList = function (openParenToken, parameters, closeParenToken) {
                return new TypeScript.ParameterListSyntax(openParenToken, parameters, closeParenToken, false);
            };
            NormalModeFactory.prototype.typeParameterList = function (lessThanToken, typeParameters, greaterThanToken) {
                return new TypeScript.TypeParameterListSyntax(lessThanToken, typeParameters, greaterThanToken, false);
            };
            NormalModeFactory.prototype.typeParameter = function (identifier, constraint) {
                return new TypeScript.TypeParameterSyntax(identifier, constraint, false);
            };
            NormalModeFactory.prototype.constraint = function (extendsKeyword, type) {
                return new TypeScript.ConstraintSyntax(extendsKeyword, type, false);
            };
            NormalModeFactory.prototype.elseClause = function (elseKeyword, statement) {
                return new TypeScript.ElseClauseSyntax(elseKeyword, statement, false);
            };
            NormalModeFactory.prototype.ifStatement = function (ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause) {
                return new TypeScript.IfStatementSyntax(ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause, false);
            };
            NormalModeFactory.prototype.expressionStatement = function (expression, semicolonToken) {
                return new TypeScript.ExpressionStatementSyntax(expression, semicolonToken, false);
            };
            NormalModeFactory.prototype.constructorDeclaration = function (modifiers, constructorKeyword, callSignature, block, semicolonToken) {
                return new TypeScript.ConstructorDeclarationSyntax(modifiers, constructorKeyword, callSignature, block, semicolonToken, false);
            };
            NormalModeFactory.prototype.memberFunctionDeclaration = function (modifiers, propertyName, callSignature, block, semicolonToken) {
                return new TypeScript.MemberFunctionDeclarationSyntax(modifiers, propertyName, callSignature, block, semicolonToken, false);
            };
            NormalModeFactory.prototype.getAccessor = function (modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block) {
                return new TypeScript.GetAccessorSyntax(modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block, false);
            };
            NormalModeFactory.prototype.setAccessor = function (modifiers, setKeyword, propertyName, parameterList, block) {
                return new TypeScript.SetAccessorSyntax(modifiers, setKeyword, propertyName, parameterList, block, false);
            };
            NormalModeFactory.prototype.memberVariableDeclaration = function (modifiers, variableDeclarator, semicolonToken) {
                return new TypeScript.MemberVariableDeclarationSyntax(modifiers, variableDeclarator, semicolonToken, false);
            };
            NormalModeFactory.prototype.indexMemberDeclaration = function (modifiers, indexSignature, semicolonToken) {
                return new TypeScript.IndexMemberDeclarationSyntax(modifiers, indexSignature, semicolonToken, false);
            };
            NormalModeFactory.prototype.throwStatement = function (throwKeyword, expression, semicolonToken) {
                return new TypeScript.ThrowStatementSyntax(throwKeyword, expression, semicolonToken, false);
            };
            NormalModeFactory.prototype.returnStatement = function (returnKeyword, expression, semicolonToken) {
                return new TypeScript.ReturnStatementSyntax(returnKeyword, expression, semicolonToken, false);
            };
            NormalModeFactory.prototype.objectCreationExpression = function (newKeyword, expression, argumentList) {
                return new TypeScript.ObjectCreationExpressionSyntax(newKeyword, expression, argumentList, false);
            };
            NormalModeFactory.prototype.switchStatement = function (switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken) {
                return new TypeScript.SwitchStatementSyntax(switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken, false);
            };
            NormalModeFactory.prototype.caseSwitchClause = function (caseKeyword, expression, colonToken, statements) {
                return new TypeScript.CaseSwitchClauseSyntax(caseKeyword, expression, colonToken, statements, false);
            };
            NormalModeFactory.prototype.defaultSwitchClause = function (defaultKeyword, colonToken, statements) {
                return new TypeScript.DefaultSwitchClauseSyntax(defaultKeyword, colonToken, statements, false);
            };
            NormalModeFactory.prototype.breakStatement = function (breakKeyword, identifier, semicolonToken) {
                return new TypeScript.BreakStatementSyntax(breakKeyword, identifier, semicolonToken, false);
            };
            NormalModeFactory.prototype.continueStatement = function (continueKeyword, identifier, semicolonToken) {
                return new TypeScript.ContinueStatementSyntax(continueKeyword, identifier, semicolonToken, false);
            };
            NormalModeFactory.prototype.forStatement = function (forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement) {
                return new TypeScript.ForStatementSyntax(forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement, false);
            };
            NormalModeFactory.prototype.forInStatement = function (forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement) {
                return new TypeScript.ForInStatementSyntax(forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement, false);
            };
            NormalModeFactory.prototype.whileStatement = function (whileKeyword, openParenToken, condition, closeParenToken, statement) {
                return new TypeScript.WhileStatementSyntax(whileKeyword, openParenToken, condition, closeParenToken, statement, false);
            };
            NormalModeFactory.prototype.withStatement = function (withKeyword, openParenToken, condition, closeParenToken, statement) {
                return new TypeScript.WithStatementSyntax(withKeyword, openParenToken, condition, closeParenToken, statement, false);
            };
            NormalModeFactory.prototype.enumDeclaration = function (modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken) {
                return new TypeScript.EnumDeclarationSyntax(modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken, false);
            };
            NormalModeFactory.prototype.enumElement = function (propertyName, equalsValueClause) {
                return new TypeScript.EnumElementSyntax(propertyName, equalsValueClause, false);
            };
            NormalModeFactory.prototype.castExpression = function (lessThanToken, type, greaterThanToken, expression) {
                return new TypeScript.CastExpressionSyntax(lessThanToken, type, greaterThanToken, expression, false);
            };
            NormalModeFactory.prototype.objectLiteralExpression = function (openBraceToken, propertyAssignments, closeBraceToken) {
                return new TypeScript.ObjectLiteralExpressionSyntax(openBraceToken, propertyAssignments, closeBraceToken, false);
            };
            NormalModeFactory.prototype.simplePropertyAssignment = function (propertyName, colonToken, expression) {
                return new TypeScript.SimplePropertyAssignmentSyntax(propertyName, colonToken, expression, false);
            };
            NormalModeFactory.prototype.functionPropertyAssignment = function (propertyName, callSignature, block) {
                return new TypeScript.FunctionPropertyAssignmentSyntax(propertyName, callSignature, block, false);
            };
            NormalModeFactory.prototype.functionExpression = function (functionKeyword, identifier, callSignature, block) {
                return new TypeScript.FunctionExpressionSyntax(functionKeyword, identifier, callSignature, block, false);
            };
            NormalModeFactory.prototype.emptyStatement = function (semicolonToken) {
                return new TypeScript.EmptyStatementSyntax(semicolonToken, false);
            };
            NormalModeFactory.prototype.tryStatement = function (tryKeyword, block, catchClause, finallyClause) {
                return new TypeScript.TryStatementSyntax(tryKeyword, block, catchClause, finallyClause, false);
            };
            NormalModeFactory.prototype.catchClause = function (catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block) {
                return new TypeScript.CatchClauseSyntax(catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block, false);
            };
            NormalModeFactory.prototype.finallyClause = function (finallyKeyword, block) {
                return new TypeScript.FinallyClauseSyntax(finallyKeyword, block, false);
            };
            NormalModeFactory.prototype.labeledStatement = function (identifier, colonToken, statement) {
                return new TypeScript.LabeledStatementSyntax(identifier, colonToken, statement, false);
            };
            NormalModeFactory.prototype.doStatement = function (doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken) {
                return new TypeScript.DoStatementSyntax(doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken, false);
            };
            NormalModeFactory.prototype.typeOfExpression = function (typeOfKeyword, expression) {
                return new TypeScript.TypeOfExpressionSyntax(typeOfKeyword, expression, false);
            };
            NormalModeFactory.prototype.deleteExpression = function (deleteKeyword, expression) {
                return new TypeScript.DeleteExpressionSyntax(deleteKeyword, expression, false);
            };
            NormalModeFactory.prototype.voidExpression = function (voidKeyword, expression) {
                return new TypeScript.VoidExpressionSyntax(voidKeyword, expression, false);
            };
            NormalModeFactory.prototype.debuggerStatement = function (debuggerKeyword, semicolonToken) {
                return new TypeScript.DebuggerStatementSyntax(debuggerKeyword, semicolonToken, false);
            };
            return NormalModeFactory;
        })();
        Syntax.NormalModeFactory = NormalModeFactory;

        var StrictModeFactory = (function () {
            function StrictModeFactory() {
            }
            StrictModeFactory.prototype.sourceUnit = function (moduleElements, endOfFileToken) {
                return new TypeScript.SourceUnitSyntax(moduleElements, endOfFileToken, true);
            };
            StrictModeFactory.prototype.externalModuleReference = function (requireKeyword, openParenToken, stringLiteral, closeParenToken) {
                return new TypeScript.ExternalModuleReferenceSyntax(requireKeyword, openParenToken, stringLiteral, closeParenToken, true);
            };
            StrictModeFactory.prototype.moduleNameModuleReference = function (moduleName) {
                return new TypeScript.ModuleNameModuleReferenceSyntax(moduleName, true);
            };
            StrictModeFactory.prototype.importDeclaration = function (modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken) {
                return new TypeScript.ImportDeclarationSyntax(modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken, true);
            };
            StrictModeFactory.prototype.exportAssignment = function (exportKeyword, equalsToken, identifier, semicolonToken) {
                return new TypeScript.ExportAssignmentSyntax(exportKeyword, equalsToken, identifier, semicolonToken, true);
            };
            StrictModeFactory.prototype.classDeclaration = function (modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken) {
                return new TypeScript.ClassDeclarationSyntax(modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken, true);
            };
            StrictModeFactory.prototype.interfaceDeclaration = function (modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body) {
                return new TypeScript.InterfaceDeclarationSyntax(modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body, true);
            };
            StrictModeFactory.prototype.heritageClause = function (kind, extendsOrImplementsKeyword, typeNames) {
                return new TypeScript.HeritageClauseSyntax(kind, extendsOrImplementsKeyword, typeNames, true);
            };
            StrictModeFactory.prototype.moduleDeclaration = function (modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken) {
                return new TypeScript.ModuleDeclarationSyntax(modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken, true);
            };
            StrictModeFactory.prototype.functionDeclaration = function (modifiers, functionKeyword, identifier, callSignature, block, semicolonToken) {
                return new TypeScript.FunctionDeclarationSyntax(modifiers, functionKeyword, identifier, callSignature, block, semicolonToken, true);
            };
            StrictModeFactory.prototype.variableStatement = function (modifiers, variableDeclaration, semicolonToken) {
                return new TypeScript.VariableStatementSyntax(modifiers, variableDeclaration, semicolonToken, true);
            };
            StrictModeFactory.prototype.variableDeclaration = function (varKeyword, variableDeclarators) {
                return new TypeScript.VariableDeclarationSyntax(varKeyword, variableDeclarators, true);
            };
            StrictModeFactory.prototype.variableDeclarator = function (propertyName, typeAnnotation, equalsValueClause) {
                return new TypeScript.VariableDeclaratorSyntax(propertyName, typeAnnotation, equalsValueClause, true);
            };
            StrictModeFactory.prototype.equalsValueClause = function (equalsToken, value) {
                return new TypeScript.EqualsValueClauseSyntax(equalsToken, value, true);
            };
            StrictModeFactory.prototype.prefixUnaryExpression = function (kind, operatorToken, operand) {
                return new TypeScript.PrefixUnaryExpressionSyntax(kind, operatorToken, operand, true);
            };
            StrictModeFactory.prototype.arrayLiteralExpression = function (openBracketToken, expressions, closeBracketToken) {
                return new TypeScript.ArrayLiteralExpressionSyntax(openBracketToken, expressions, closeBracketToken, true);
            };
            StrictModeFactory.prototype.omittedExpression = function () {
                return new TypeScript.OmittedExpressionSyntax(true);
            };
            StrictModeFactory.prototype.parenthesizedExpression = function (openParenToken, expression, closeParenToken) {
                return new TypeScript.ParenthesizedExpressionSyntax(openParenToken, expression, closeParenToken, true);
            };
            StrictModeFactory.prototype.simpleArrowFunctionExpression = function (identifier, equalsGreaterThanToken, block, expression) {
                return new TypeScript.SimpleArrowFunctionExpressionSyntax(identifier, equalsGreaterThanToken, block, expression, true);
            };
            StrictModeFactory.prototype.parenthesizedArrowFunctionExpression = function (callSignature, equalsGreaterThanToken, block, expression) {
                return new TypeScript.ParenthesizedArrowFunctionExpressionSyntax(callSignature, equalsGreaterThanToken, block, expression, true);
            };
            StrictModeFactory.prototype.qualifiedName = function (left, dotToken, right) {
                return new TypeScript.QualifiedNameSyntax(left, dotToken, right, true);
            };
            StrictModeFactory.prototype.typeArgumentList = function (lessThanToken, typeArguments, greaterThanToken) {
                return new TypeScript.TypeArgumentListSyntax(lessThanToken, typeArguments, greaterThanToken, true);
            };
            StrictModeFactory.prototype.constructorType = function (newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type) {
                return new TypeScript.ConstructorTypeSyntax(newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type, true);
            };
            StrictModeFactory.prototype.functionType = function (typeParameterList, parameterList, equalsGreaterThanToken, type) {
                return new TypeScript.FunctionTypeSyntax(typeParameterList, parameterList, equalsGreaterThanToken, type, true);
            };
            StrictModeFactory.prototype.objectType = function (openBraceToken, typeMembers, closeBraceToken) {
                return new TypeScript.ObjectTypeSyntax(openBraceToken, typeMembers, closeBraceToken, true);
            };
            StrictModeFactory.prototype.arrayType = function (type, openBracketToken, closeBracketToken) {
                return new TypeScript.ArrayTypeSyntax(type, openBracketToken, closeBracketToken, true);
            };
            StrictModeFactory.prototype.genericType = function (name, typeArgumentList) {
                return new TypeScript.GenericTypeSyntax(name, typeArgumentList, true);
            };
            StrictModeFactory.prototype.typeQuery = function (typeOfKeyword, name) {
                return new TypeScript.TypeQuerySyntax(typeOfKeyword, name, true);
            };
            StrictModeFactory.prototype.typeAnnotation = function (colonToken, type) {
                return new TypeScript.TypeAnnotationSyntax(colonToken, type, true);
            };
            StrictModeFactory.prototype.block = function (openBraceToken, statements, closeBraceToken) {
                return new TypeScript.BlockSyntax(openBraceToken, statements, closeBraceToken, true);
            };
            StrictModeFactory.prototype.parameter = function (dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause) {
                return new TypeScript.ParameterSyntax(dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause, true);
            };
            StrictModeFactory.prototype.memberAccessExpression = function (expression, dotToken, name) {
                return new TypeScript.MemberAccessExpressionSyntax(expression, dotToken, name, true);
            };
            StrictModeFactory.prototype.postfixUnaryExpression = function (kind, operand, operatorToken) {
                return new TypeScript.PostfixUnaryExpressionSyntax(kind, operand, operatorToken, true);
            };
            StrictModeFactory.prototype.elementAccessExpression = function (expression, openBracketToken, argumentExpression, closeBracketToken) {
                return new TypeScript.ElementAccessExpressionSyntax(expression, openBracketToken, argumentExpression, closeBracketToken, true);
            };
            StrictModeFactory.prototype.invocationExpression = function (expression, argumentList) {
                return new TypeScript.InvocationExpressionSyntax(expression, argumentList, true);
            };
            StrictModeFactory.prototype.argumentList = function (typeArgumentList, openParenToken, _arguments, closeParenToken) {
                return new TypeScript.ArgumentListSyntax(typeArgumentList, openParenToken, _arguments, closeParenToken, true);
            };
            StrictModeFactory.prototype.binaryExpression = function (kind, left, operatorToken, right) {
                return new TypeScript.BinaryExpressionSyntax(kind, left, operatorToken, right, true);
            };
            StrictModeFactory.prototype.conditionalExpression = function (condition, questionToken, whenTrue, colonToken, whenFalse) {
                return new TypeScript.ConditionalExpressionSyntax(condition, questionToken, whenTrue, colonToken, whenFalse, true);
            };
            StrictModeFactory.prototype.constructSignature = function (newKeyword, callSignature) {
                return new TypeScript.ConstructSignatureSyntax(newKeyword, callSignature, true);
            };
            StrictModeFactory.prototype.methodSignature = function (propertyName, questionToken, callSignature) {
                return new TypeScript.MethodSignatureSyntax(propertyName, questionToken, callSignature, true);
            };
            StrictModeFactory.prototype.indexSignature = function (openBracketToken, parameter, closeBracketToken, typeAnnotation) {
                return new TypeScript.IndexSignatureSyntax(openBracketToken, parameter, closeBracketToken, typeAnnotation, true);
            };
            StrictModeFactory.prototype.propertySignature = function (propertyName, questionToken, typeAnnotation) {
                return new TypeScript.PropertySignatureSyntax(propertyName, questionToken, typeAnnotation, true);
            };
            StrictModeFactory.prototype.callSignature = function (typeParameterList, parameterList, typeAnnotation) {
                return new TypeScript.CallSignatureSyntax(typeParameterList, parameterList, typeAnnotation, true);
            };
            StrictModeFactory.prototype.parameterList = function (openParenToken, parameters, closeParenToken) {
                return new TypeScript.ParameterListSyntax(openParenToken, parameters, closeParenToken, true);
            };
            StrictModeFactory.prototype.typeParameterList = function (lessThanToken, typeParameters, greaterThanToken) {
                return new TypeScript.TypeParameterListSyntax(lessThanToken, typeParameters, greaterThanToken, true);
            };
            StrictModeFactory.prototype.typeParameter = function (identifier, constraint) {
                return new TypeScript.TypeParameterSyntax(identifier, constraint, true);
            };
            StrictModeFactory.prototype.constraint = function (extendsKeyword, type) {
                return new TypeScript.ConstraintSyntax(extendsKeyword, type, true);
            };
            StrictModeFactory.prototype.elseClause = function (elseKeyword, statement) {
                return new TypeScript.ElseClauseSyntax(elseKeyword, statement, true);
            };
            StrictModeFactory.prototype.ifStatement = function (ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause) {
                return new TypeScript.IfStatementSyntax(ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause, true);
            };
            StrictModeFactory.prototype.expressionStatement = function (expression, semicolonToken) {
                return new TypeScript.ExpressionStatementSyntax(expression, semicolonToken, true);
            };
            StrictModeFactory.prototype.constructorDeclaration = function (modifiers, constructorKeyword, callSignature, block, semicolonToken) {
                return new TypeScript.ConstructorDeclarationSyntax(modifiers, constructorKeyword, callSignature, block, semicolonToken, true);
            };
            StrictModeFactory.prototype.memberFunctionDeclaration = function (modifiers, propertyName, callSignature, block, semicolonToken) {
                return new TypeScript.MemberFunctionDeclarationSyntax(modifiers, propertyName, callSignature, block, semicolonToken, true);
            };
            StrictModeFactory.prototype.getAccessor = function (modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block) {
                return new TypeScript.GetAccessorSyntax(modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block, true);
            };
            StrictModeFactory.prototype.setAccessor = function (modifiers, setKeyword, propertyName, parameterList, block) {
                return new TypeScript.SetAccessorSyntax(modifiers, setKeyword, propertyName, parameterList, block, true);
            };
            StrictModeFactory.prototype.memberVariableDeclaration = function (modifiers, variableDeclarator, semicolonToken) {
                return new TypeScript.MemberVariableDeclarationSyntax(modifiers, variableDeclarator, semicolonToken, true);
            };
            StrictModeFactory.prototype.indexMemberDeclaration = function (modifiers, indexSignature, semicolonToken) {
                return new TypeScript.IndexMemberDeclarationSyntax(modifiers, indexSignature, semicolonToken, true);
            };
            StrictModeFactory.prototype.throwStatement = function (throwKeyword, expression, semicolonToken) {
                return new TypeScript.ThrowStatementSyntax(throwKeyword, expression, semicolonToken, true);
            };
            StrictModeFactory.prototype.returnStatement = function (returnKeyword, expression, semicolonToken) {
                return new TypeScript.ReturnStatementSyntax(returnKeyword, expression, semicolonToken, true);
            };
            StrictModeFactory.prototype.objectCreationExpression = function (newKeyword, expression, argumentList) {
                return new TypeScript.ObjectCreationExpressionSyntax(newKeyword, expression, argumentList, true);
            };
            StrictModeFactory.prototype.switchStatement = function (switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken) {
                return new TypeScript.SwitchStatementSyntax(switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken, true);
            };
            StrictModeFactory.prototype.caseSwitchClause = function (caseKeyword, expression, colonToken, statements) {
                return new TypeScript.CaseSwitchClauseSyntax(caseKeyword, expression, colonToken, statements, true);
            };
            StrictModeFactory.prototype.defaultSwitchClause = function (defaultKeyword, colonToken, statements) {
                return new TypeScript.DefaultSwitchClauseSyntax(defaultKeyword, colonToken, statements, true);
            };
            StrictModeFactory.prototype.breakStatement = function (breakKeyword, identifier, semicolonToken) {
                return new TypeScript.BreakStatementSyntax(breakKeyword, identifier, semicolonToken, true);
            };
            StrictModeFactory.prototype.continueStatement = function (continueKeyword, identifier, semicolonToken) {
                return new TypeScript.ContinueStatementSyntax(continueKeyword, identifier, semicolonToken, true);
            };
            StrictModeFactory.prototype.forStatement = function (forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement) {
                return new TypeScript.ForStatementSyntax(forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement, true);
            };
            StrictModeFactory.prototype.forInStatement = function (forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement) {
                return new TypeScript.ForInStatementSyntax(forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement, true);
            };
            StrictModeFactory.prototype.whileStatement = function (whileKeyword, openParenToken, condition, closeParenToken, statement) {
                return new TypeScript.WhileStatementSyntax(whileKeyword, openParenToken, condition, closeParenToken, statement, true);
            };
            StrictModeFactory.prototype.withStatement = function (withKeyword, openParenToken, condition, closeParenToken, statement) {
                return new TypeScript.WithStatementSyntax(withKeyword, openParenToken, condition, closeParenToken, statement, true);
            };
            StrictModeFactory.prototype.enumDeclaration = function (modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken) {
                return new TypeScript.EnumDeclarationSyntax(modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken, true);
            };
            StrictModeFactory.prototype.enumElement = function (propertyName, equalsValueClause) {
                return new TypeScript.EnumElementSyntax(propertyName, equalsValueClause, true);
            };
            StrictModeFactory.prototype.castExpression = function (lessThanToken, type, greaterThanToken, expression) {
                return new TypeScript.CastExpressionSyntax(lessThanToken, type, greaterThanToken, expression, true);
            };
            StrictModeFactory.prototype.objectLiteralExpression = function (openBraceToken, propertyAssignments, closeBraceToken) {
                return new TypeScript.ObjectLiteralExpressionSyntax(openBraceToken, propertyAssignments, closeBraceToken, true);
            };
            StrictModeFactory.prototype.simplePropertyAssignment = function (propertyName, colonToken, expression) {
                return new TypeScript.SimplePropertyAssignmentSyntax(propertyName, colonToken, expression, true);
            };
            StrictModeFactory.prototype.functionPropertyAssignment = function (propertyName, callSignature, block) {
                return new TypeScript.FunctionPropertyAssignmentSyntax(propertyName, callSignature, block, true);
            };
            StrictModeFactory.prototype.functionExpression = function (functionKeyword, identifier, callSignature, block) {
                return new TypeScript.FunctionExpressionSyntax(functionKeyword, identifier, callSignature, block, true);
            };
            StrictModeFactory.prototype.emptyStatement = function (semicolonToken) {
                return new TypeScript.EmptyStatementSyntax(semicolonToken, true);
            };
            StrictModeFactory.prototype.tryStatement = function (tryKeyword, block, catchClause, finallyClause) {
                return new TypeScript.TryStatementSyntax(tryKeyword, block, catchClause, finallyClause, true);
            };
            StrictModeFactory.prototype.catchClause = function (catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block) {
                return new TypeScript.CatchClauseSyntax(catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block, true);
            };
            StrictModeFactory.prototype.finallyClause = function (finallyKeyword, block) {
                return new TypeScript.FinallyClauseSyntax(finallyKeyword, block, true);
            };
            StrictModeFactory.prototype.labeledStatement = function (identifier, colonToken, statement) {
                return new TypeScript.LabeledStatementSyntax(identifier, colonToken, statement, true);
            };
            StrictModeFactory.prototype.doStatement = function (doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken) {
                return new TypeScript.DoStatementSyntax(doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken, true);
            };
            StrictModeFactory.prototype.typeOfExpression = function (typeOfKeyword, expression) {
                return new TypeScript.TypeOfExpressionSyntax(typeOfKeyword, expression, true);
            };
            StrictModeFactory.prototype.deleteExpression = function (deleteKeyword, expression) {
                return new TypeScript.DeleteExpressionSyntax(deleteKeyword, expression, true);
            };
            StrictModeFactory.prototype.voidExpression = function (voidKeyword, expression) {
                return new TypeScript.VoidExpressionSyntax(voidKeyword, expression, true);
            };
            StrictModeFactory.prototype.debuggerStatement = function (debuggerKeyword, semicolonToken) {
                return new TypeScript.DebuggerStatementSyntax(debuggerKeyword, semicolonToken, true);
            };
            return StrictModeFactory;
        })();
        Syntax.StrictModeFactory = StrictModeFactory;

        Syntax.normalModeFactory = new NormalModeFactory();
        Syntax.strictModeFactory = new StrictModeFactory();
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (SyntaxFacts) {
        function isDirectivePrologueElement(node) {
            if (node.kind() === 149 /* ExpressionStatement */) {
                var expressionStatement = node;
                var expression = expressionStatement.expression;

                if (expression.kind() === 14 /* StringLiteral */) {
                    return true;
                }
            }

            return false;
        }
        SyntaxFacts.isDirectivePrologueElement = isDirectivePrologueElement;

        function isUseStrictDirective(node) {
            var expressionStatement = node;
            var stringLiteral = expressionStatement.expression;

            var text = stringLiteral.text();
            return text === '"use strict"' || text === "'use strict'";
        }
        SyntaxFacts.isUseStrictDirective = isUseStrictDirective;

        function isIdentifierNameOrAnyKeyword(token) {
            var tokenKind = token.tokenKind;
            return tokenKind === 11 /* IdentifierName */ || SyntaxFacts.isAnyKeyword(tokenKind);
        }
        SyntaxFacts.isIdentifierNameOrAnyKeyword = isIdentifierNameOrAnyKeyword;
    })(TypeScript.SyntaxFacts || (TypeScript.SyntaxFacts = {}));
    var SyntaxFacts = TypeScript.SyntaxFacts;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        var EmptySyntaxList = (function () {
            function EmptySyntaxList() {
            }
            EmptySyntaxList.prototype.kind = function () {
                return 1 /* List */;
            };

            EmptySyntaxList.prototype.isNode = function () {
                return false;
            };
            EmptySyntaxList.prototype.isToken = function () {
                return false;
            };
            EmptySyntaxList.prototype.isList = function () {
                return true;
            };
            EmptySyntaxList.prototype.isSeparatedList = function () {
                return false;
            };

            EmptySyntaxList.prototype.toJSON = function (key) {
                return [];
            };

            EmptySyntaxList.prototype.childCount = function () {
                return 0;
            };

            EmptySyntaxList.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            EmptySyntaxList.prototype.toArray = function () {
                return [];
            };

            EmptySyntaxList.prototype.collectTextElements = function (elements) {
            };

            EmptySyntaxList.prototype.firstToken = function () {
                return null;
            };

            EmptySyntaxList.prototype.lastToken = function () {
                return null;
            };

            EmptySyntaxList.prototype.fullWidth = function () {
                return 0;
            };

            EmptySyntaxList.prototype.width = function () {
                return 0;
            };

            EmptySyntaxList.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            EmptySyntaxList.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            EmptySyntaxList.prototype.leadingTriviaWidth = function () {
                return 0;
            };

            EmptySyntaxList.prototype.trailingTriviaWidth = function () {
                return 0;
            };

            EmptySyntaxList.prototype.fullText = function () {
                return "";
            };

            EmptySyntaxList.prototype.isTypeScriptSpecific = function () {
                return false;
            };

            EmptySyntaxList.prototype.isIncrementallyUnusable = function () {
                return false;
            };

            EmptySyntaxList.prototype.findTokenInternal = function (parent, position, fullStart) {
                throw TypeScript.Errors.invalidOperation();
            };

            EmptySyntaxList.prototype.insertChildrenInto = function (array, index) {
            };
            return EmptySyntaxList;
        })();
        Syntax.EmptySyntaxList = EmptySyntaxList;

        Syntax.emptyList = new EmptySyntaxList();

        var SingletonSyntaxList = (function () {
            function SingletonSyntaxList(item) {
                this.item = item;
            }
            SingletonSyntaxList.prototype.kind = function () {
                return 1 /* List */;
            };

            SingletonSyntaxList.prototype.isToken = function () {
                return false;
            };
            SingletonSyntaxList.prototype.isNode = function () {
                return false;
            };
            SingletonSyntaxList.prototype.isList = function () {
                return true;
            };
            SingletonSyntaxList.prototype.isSeparatedList = function () {
                return false;
            };

            SingletonSyntaxList.prototype.toJSON = function (key) {
                return [this.item];
            };

            SingletonSyntaxList.prototype.childCount = function () {
                return 1;
            };

            SingletonSyntaxList.prototype.childAt = function (index) {
                if (index !== 0) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.item;
            };

            SingletonSyntaxList.prototype.toArray = function () {
                return [this.item];
            };

            SingletonSyntaxList.prototype.collectTextElements = function (elements) {
                this.item.collectTextElements(elements);
            };

            SingletonSyntaxList.prototype.firstToken = function () {
                return this.item.firstToken();
            };

            SingletonSyntaxList.prototype.lastToken = function () {
                return this.item.lastToken();
            };

            SingletonSyntaxList.prototype.fullWidth = function () {
                return this.item.fullWidth();
            };

            SingletonSyntaxList.prototype.width = function () {
                return this.item.width();
            };

            SingletonSyntaxList.prototype.leadingTrivia = function () {
                return this.item.leadingTrivia();
            };

            SingletonSyntaxList.prototype.trailingTrivia = function () {
                return this.item.trailingTrivia();
            };

            SingletonSyntaxList.prototype.leadingTriviaWidth = function () {
                return this.item.leadingTriviaWidth();
            };

            SingletonSyntaxList.prototype.trailingTriviaWidth = function () {
                return this.item.trailingTriviaWidth();
            };

            SingletonSyntaxList.prototype.fullText = function () {
                return this.item.fullText();
            };

            SingletonSyntaxList.prototype.isTypeScriptSpecific = function () {
                return this.item.isTypeScriptSpecific();
            };

            SingletonSyntaxList.prototype.isIncrementallyUnusable = function () {
                return this.item.isIncrementallyUnusable();
            };

            SingletonSyntaxList.prototype.findTokenInternal = function (parent, position, fullStart) {
                return this.item.findTokenInternal(new TypeScript.PositionedList(parent, this, fullStart), position, fullStart);
            };

            SingletonSyntaxList.prototype.insertChildrenInto = function (array, index) {
                array.splice(index, 0, this.item);
            };
            return SingletonSyntaxList;
        })();

        var NormalSyntaxList = (function () {
            function NormalSyntaxList(nodeOrTokens) {
                this._data = 0;
                this.nodeOrTokens = nodeOrTokens;
            }
            NormalSyntaxList.prototype.kind = function () {
                return 1 /* List */;
            };

            NormalSyntaxList.prototype.isNode = function () {
                return false;
            };
            NormalSyntaxList.prototype.isToken = function () {
                return false;
            };
            NormalSyntaxList.prototype.isList = function () {
                return true;
            };
            NormalSyntaxList.prototype.isSeparatedList = function () {
                return false;
            };

            NormalSyntaxList.prototype.toJSON = function (key) {
                return this.nodeOrTokens;
            };

            NormalSyntaxList.prototype.childCount = function () {
                return this.nodeOrTokens.length;
            };

            NormalSyntaxList.prototype.childAt = function (index) {
                if (index < 0 || index >= this.nodeOrTokens.length) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.nodeOrTokens[index];
            };

            NormalSyntaxList.prototype.toArray = function () {
                return this.nodeOrTokens.slice(0);
            };

            NormalSyntaxList.prototype.collectTextElements = function (elements) {
                for (var i = 0, n = this.nodeOrTokens.length; i < n; i++) {
                    var element = this.nodeOrTokens[i];
                    element.collectTextElements(elements);
                }
            };

            NormalSyntaxList.prototype.firstToken = function () {
                for (var i = 0, n = this.nodeOrTokens.length; i < n; i++) {
                    var token = this.nodeOrTokens[i].firstToken();
                    if (token !== null) {
                        return token;
                    }
                }

                return null;
            };

            NormalSyntaxList.prototype.lastToken = function () {
                for (var i = this.nodeOrTokens.length - 1; i >= 0; i--) {
                    var token = this.nodeOrTokens[i].lastToken();
                    if (token !== null) {
                        return token;
                    }
                }

                return null;
            };

            NormalSyntaxList.prototype.fullText = function () {
                var elements = new Array();
                this.collectTextElements(elements);
                return elements.join("");
            };

            NormalSyntaxList.prototype.isTypeScriptSpecific = function () {
                for (var i = 0, n = this.nodeOrTokens.length; i < n; i++) {
                    if (this.nodeOrTokens[i].isTypeScriptSpecific()) {
                        return true;
                    }
                }

                return false;
            };

            NormalSyntaxList.prototype.isIncrementallyUnusable = function () {
                return (this.data() & 2 /* NodeIncrementallyUnusableMask */) !== 0;
            };

            NormalSyntaxList.prototype.fullWidth = function () {
                return this.data() >>> 3 /* NodeFullWidthShift */;
            };

            NormalSyntaxList.prototype.width = function () {
                var fullWidth = this.fullWidth();
                return fullWidth - this.leadingTriviaWidth() - this.trailingTriviaWidth();
            };

            NormalSyntaxList.prototype.leadingTrivia = function () {
                return this.firstToken().leadingTrivia();
            };

            NormalSyntaxList.prototype.trailingTrivia = function () {
                return this.lastToken().trailingTrivia();
            };

            NormalSyntaxList.prototype.leadingTriviaWidth = function () {
                return this.firstToken().leadingTriviaWidth();
            };

            NormalSyntaxList.prototype.trailingTriviaWidth = function () {
                return this.lastToken().trailingTriviaWidth();
            };

            NormalSyntaxList.prototype.computeData = function () {
                var fullWidth = 0;
                var isIncrementallyUnusable = false;

                for (var i = 0, n = this.nodeOrTokens.length; i < n; i++) {
                    var node = this.nodeOrTokens[i];
                    fullWidth += node.fullWidth();
                    isIncrementallyUnusable = isIncrementallyUnusable || node.isIncrementallyUnusable();
                }

                return (fullWidth << 3 /* NodeFullWidthShift */) | (isIncrementallyUnusable ? 2 /* NodeIncrementallyUnusableMask */ : 0) | 1 /* NodeDataComputed */;
            };

            NormalSyntaxList.prototype.data = function () {
                if ((this._data & 1 /* NodeDataComputed */) === 0) {
                    this._data = this.computeData();
                }

                return this._data;
            };

            NormalSyntaxList.prototype.findTokenInternal = function (parent, position, fullStart) {
                parent = new TypeScript.PositionedList(parent, this, fullStart);
                for (var i = 0, n = this.nodeOrTokens.length; i < n; i++) {
                    var nodeOrToken = this.nodeOrTokens[i];

                    var childWidth = nodeOrToken.fullWidth();
                    if (position < childWidth) {
                        return nodeOrToken.findTokenInternal(parent, position, fullStart);
                    }

                    position -= childWidth;
                    fullStart += childWidth;
                }

                throw TypeScript.Errors.invalidOperation();
            };

            NormalSyntaxList.prototype.insertChildrenInto = function (array, index) {
                if (index === 0) {
                    array.unshift.apply(array, this.nodeOrTokens);
                } else {
                    array.splice.apply(array, [index, 0].concat(this.nodeOrTokens));
                }
            };
            return NormalSyntaxList;
        })();

        function list(nodes) {
            if (nodes === undefined || nodes === null || nodes.length === 0) {
                return Syntax.emptyList;
            }

            if (nodes.length === 1) {
                var item = nodes[0];
                return new SingletonSyntaxList(item);
            }

            return new NormalSyntaxList(nodes);
        }
        Syntax.list = list;
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxNode = (function () {
        function SyntaxNode(parsedInStrictMode) {
            this._data = parsedInStrictMode ? 4 /* NodeParsedInStrictModeMask */ : 0;
        }
        SyntaxNode.prototype.isNode = function () {
            return true;
        };
        SyntaxNode.prototype.isToken = function () {
            return false;
        };
        SyntaxNode.prototype.isList = function () {
            return false;
        };
        SyntaxNode.prototype.isSeparatedList = function () {
            return false;
        };

        SyntaxNode.prototype.kind = function () {
            throw TypeScript.Errors.abstract();
        };

        SyntaxNode.prototype.childCount = function () {
            throw TypeScript.Errors.abstract();
        };

        SyntaxNode.prototype.childAt = function (slot) {
            throw TypeScript.Errors.abstract();
        };

        SyntaxNode.prototype.firstToken = function () {
            for (var i = 0, n = this.childCount(); i < n; i++) {
                var element = this.childAt(i);

                if (element !== null) {
                    if (element.fullWidth() > 0 || element.kind() === 10 /* EndOfFileToken */) {
                        return element.firstToken();
                    }
                }
            }

            return null;
        };

        SyntaxNode.prototype.lastToken = function () {
            for (var i = this.childCount() - 1; i >= 0; i--) {
                var element = this.childAt(i);

                if (element !== null) {
                    if (element.fullWidth() > 0 || element.kind() === 10 /* EndOfFileToken */) {
                        return element.lastToken();
                    }
                }
            }

            return null;
        };

        SyntaxNode.prototype.insertChildrenInto = function (array, index) {
            for (var i = this.childCount() - 1; i >= 0; i--) {
                var element = this.childAt(i);

                if (element !== null) {
                    if (element.isNode() || element.isToken()) {
                        array.splice(index, 0, element);
                    } else if (element.isList()) {
                        element.insertChildrenInto(array, index);
                    } else if (element.isSeparatedList()) {
                        element.insertChildrenInto(array, index);
                    } else {
                        throw TypeScript.Errors.invalidOperation();
                    }
                }
            }
        };

        SyntaxNode.prototype.leadingTrivia = function () {
            var firstToken = this.firstToken();
            return firstToken ? firstToken.leadingTrivia() : TypeScript.Syntax.emptyTriviaList;
        };

        SyntaxNode.prototype.trailingTrivia = function () {
            var lastToken = this.lastToken();
            return lastToken ? lastToken.trailingTrivia() : TypeScript.Syntax.emptyTriviaList;
        };

        SyntaxNode.prototype.toJSON = function (key) {
            var result = {
                kind: TypeScript.SyntaxKind[this.kind()],
                fullWidth: this.fullWidth()
            };

            if (this.isIncrementallyUnusable()) {
                result.isIncrementallyUnusable = true;
            }

            if (this.parsedInStrictMode()) {
                result.parsedInStrictMode = true;
            }

            var thisAsIndexable = this;
            for (var i = 0, n = this.childCount(); i < n; i++) {
                var value = this.childAt(i);

                if (value) {
                    for (var name in this) {
                        if (value === thisAsIndexable[name]) {
                            result[name] = value;
                            break;
                        }
                    }
                }
            }

            return result;
        };

        SyntaxNode.prototype.accept = function (visitor) {
            throw TypeScript.Errors.abstract();
        };

        SyntaxNode.prototype.fullText = function () {
            var elements = [];
            this.collectTextElements(elements);
            return elements.join("");
        };

        SyntaxNode.prototype.collectTextElements = function (elements) {
            for (var i = 0, n = this.childCount(); i < n; i++) {
                var element = this.childAt(i);

                if (element !== null) {
                    element.collectTextElements(elements);
                }
            }
        };

        SyntaxNode.prototype.replaceToken = function (token1, token2) {
            if (token1 === token2) {
                return this;
            }

            return this.accept(new TypeScript.SyntaxTokenReplacer(token1, token2));
        };

        SyntaxNode.prototype.withLeadingTrivia = function (trivia) {
            return this.replaceToken(this.firstToken(), this.firstToken().withLeadingTrivia(trivia));
        };

        SyntaxNode.prototype.withTrailingTrivia = function (trivia) {
            return this.replaceToken(this.lastToken(), this.lastToken().withTrailingTrivia(trivia));
        };

        SyntaxNode.prototype.hasLeadingTrivia = function () {
            return this.lastToken().hasLeadingTrivia();
        };

        SyntaxNode.prototype.hasTrailingTrivia = function () {
            return this.lastToken().hasTrailingTrivia();
        };

        SyntaxNode.prototype.isTypeScriptSpecific = function () {
            return false;
        };

        SyntaxNode.prototype.isIncrementallyUnusable = function () {
            return (this.data() & 2 /* NodeIncrementallyUnusableMask */) !== 0;
        };

        SyntaxNode.prototype.parsedInStrictMode = function () {
            return (this.data() & 4 /* NodeParsedInStrictModeMask */) !== 0;
        };

        SyntaxNode.prototype.fullWidth = function () {
            return this.data() >>> 3 /* NodeFullWidthShift */;
        };

        SyntaxNode.prototype.computeData = function () {
            var slotCount = this.childCount();

            var fullWidth = 0;
            var childWidth = 0;

            var isIncrementallyUnusable = ((this._data & 2 /* NodeIncrementallyUnusableMask */) !== 0) || slotCount === 0;

            for (var i = 0, n = slotCount; i < n; i++) {
                var element = this.childAt(i);

                if (element !== null) {
                    childWidth = element.fullWidth();
                    fullWidth += childWidth;

                    if (!isIncrementallyUnusable) {
                        isIncrementallyUnusable = element.isIncrementallyUnusable();
                    }
                }
            }

            return (fullWidth << 3 /* NodeFullWidthShift */) | (isIncrementallyUnusable ? 2 /* NodeIncrementallyUnusableMask */ : 0) | 1 /* NodeDataComputed */;
        };

        SyntaxNode.prototype.data = function () {
            if ((this._data & 1 /* NodeDataComputed */) === 0) {
                this._data |= this.computeData();
            }

            return this._data;
        };

        SyntaxNode.prototype.findToken = function (position, includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            var endOfFileToken = this.tryGetEndOfFileAt(position);
            if (endOfFileToken !== null) {
                return endOfFileToken;
            }

            if (position < 0 || position >= this.fullWidth()) {
                throw TypeScript.Errors.argumentOutOfRange("position");
            }

            var positionedToken = this.findTokenInternal(null, position, 0);

            if (includeSkippedTokens) {
                return TypeScript.Syntax.findSkippedTokenInPositionedToken(positionedToken, position) || positionedToken;
            }

            return positionedToken;
        };

        SyntaxNode.prototype.tryGetEndOfFileAt = function (position) {
            if (this.kind() === 120 /* SourceUnit */ && position === this.fullWidth()) {
                var sourceUnit = this;
                return new TypeScript.PositionedToken(new TypeScript.PositionedNode(null, sourceUnit, 0), sourceUnit.endOfFileToken, sourceUnit.moduleElements.fullWidth());
            }

            return null;
        };

        SyntaxNode.prototype.findTokenInternal = function (parent, position, fullStart) {
            parent = new TypeScript.PositionedNode(parent, this, fullStart);
            for (var i = 0, n = this.childCount(); i < n; i++) {
                var element = this.childAt(i);

                if (element !== null) {
                    var childWidth = element.fullWidth();

                    if (position < childWidth) {
                        return element.findTokenInternal(parent, position, fullStart);
                    }

                    position -= childWidth;
                    fullStart += childWidth;
                }
            }

            throw TypeScript.Errors.invalidOperation();
        };

        SyntaxNode.prototype.findTokenOnLeft = function (position, includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            var positionedToken = this.findToken(position, false);
            var start = positionedToken.start();

            if (includeSkippedTokens) {
                positionedToken = TypeScript.Syntax.findSkippedTokenOnLeft(positionedToken, position) || positionedToken;
            }

            if (position > start) {
                return positionedToken;
            }

            if (positionedToken.fullStart() === 0) {
                return null;
            }

            return positionedToken.previousToken(includeSkippedTokens);
        };

        SyntaxNode.prototype.findCompleteTokenOnLeft = function (position, includeSkippedTokens) {
            if (typeof includeSkippedTokens === "undefined") { includeSkippedTokens = false; }
            var positionedToken = this.findToken(position, false);

            if (includeSkippedTokens) {
                positionedToken = TypeScript.Syntax.findSkippedTokenOnLeft(positionedToken, position) || positionedToken;
            }

            if (positionedToken.token().width() > 0 && position >= positionedToken.end()) {
                return positionedToken;
            }

            return positionedToken.previousToken(includeSkippedTokens);
        };

        SyntaxNode.prototype.isModuleElement = function () {
            return false;
        };

        SyntaxNode.prototype.isClassElement = function () {
            return false;
        };

        SyntaxNode.prototype.isTypeMember = function () {
            return false;
        };

        SyntaxNode.prototype.isStatement = function () {
            return false;
        };

        SyntaxNode.prototype.isExpression = function () {
            return false;
        };

        SyntaxNode.prototype.isSwitchClause = function () {
            return false;
        };

        SyntaxNode.prototype.structuralEquals = function (node) {
            if (this === node) {
                return true;
            }
            if (node === null) {
                return false;
            }
            if (this.kind() !== node.kind()) {
                return false;
            }

            for (var i = 0, n = this.childCount(); i < n; i++) {
                var element1 = this.childAt(i);
                var element2 = node.childAt(i);

                if (!TypeScript.Syntax.elementStructuralEquals(element1, element2)) {
                    return false;
                }
            }

            return true;
        };

        SyntaxNode.prototype.width = function () {
            return this.fullWidth() - this.leadingTriviaWidth() - this.trailingTriviaWidth();
        };

        SyntaxNode.prototype.leadingTriviaWidth = function () {
            var firstToken = this.firstToken();
            return firstToken === null ? 0 : firstToken.leadingTriviaWidth();
        };

        SyntaxNode.prototype.trailingTriviaWidth = function () {
            var lastToken = this.lastToken();
            return lastToken === null ? 0 : lastToken.trailingTriviaWidth();
        };
        return SyntaxNode;
    })();
    TypeScript.SyntaxNode = SyntaxNode;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SourceUnitSyntax = (function (_super) {
        __extends(SourceUnitSyntax, _super);
        function SourceUnitSyntax(moduleElements, endOfFileToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.moduleElements = moduleElements;
            this.endOfFileToken = endOfFileToken;
        }
        SourceUnitSyntax.prototype.accept = function (visitor) {
            return visitor.visitSourceUnit(this);
        };

        SourceUnitSyntax.prototype.kind = function () {
            return 120 /* SourceUnit */;
        };

        SourceUnitSyntax.prototype.childCount = function () {
            return 2;
        };

        SourceUnitSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.moduleElements;
                case 1:
                    return this.endOfFileToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        SourceUnitSyntax.prototype.update = function (moduleElements, endOfFileToken) {
            if (this.moduleElements === moduleElements && this.endOfFileToken === endOfFileToken) {
                return this;
            }

            return new SourceUnitSyntax(moduleElements, endOfFileToken, this.parsedInStrictMode());
        };

        SourceUnitSyntax.create = function (endOfFileToken) {
            return new SourceUnitSyntax(TypeScript.Syntax.emptyList, endOfFileToken, false);
        };

        SourceUnitSyntax.create1 = function (endOfFileToken) {
            return new SourceUnitSyntax(TypeScript.Syntax.emptyList, endOfFileToken, false);
        };

        SourceUnitSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        SourceUnitSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        SourceUnitSyntax.prototype.withModuleElements = function (moduleElements) {
            return this.update(moduleElements, this.endOfFileToken);
        };

        SourceUnitSyntax.prototype.withModuleElement = function (moduleElement) {
            return this.withModuleElements(TypeScript.Syntax.list([moduleElement]));
        };

        SourceUnitSyntax.prototype.withEndOfFileToken = function (endOfFileToken) {
            return this.update(this.moduleElements, endOfFileToken);
        };

        SourceUnitSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.moduleElements.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return SourceUnitSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.SourceUnitSyntax = SourceUnitSyntax;

    var ExternalModuleReferenceSyntax = (function (_super) {
        __extends(ExternalModuleReferenceSyntax, _super);
        function ExternalModuleReferenceSyntax(requireKeyword, openParenToken, stringLiteral, closeParenToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.requireKeyword = requireKeyword;
            this.openParenToken = openParenToken;
            this.stringLiteral = stringLiteral;
            this.closeParenToken = closeParenToken;
        }
        ExternalModuleReferenceSyntax.prototype.accept = function (visitor) {
            return visitor.visitExternalModuleReference(this);
        };

        ExternalModuleReferenceSyntax.prototype.kind = function () {
            return 245 /* ExternalModuleReference */;
        };

        ExternalModuleReferenceSyntax.prototype.childCount = function () {
            return 4;
        };

        ExternalModuleReferenceSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.requireKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.stringLiteral;
                case 3:
                    return this.closeParenToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ExternalModuleReferenceSyntax.prototype.isModuleReference = function () {
            return true;
        };

        ExternalModuleReferenceSyntax.prototype.update = function (requireKeyword, openParenToken, stringLiteral, closeParenToken) {
            if (this.requireKeyword === requireKeyword && this.openParenToken === openParenToken && this.stringLiteral === stringLiteral && this.closeParenToken === closeParenToken) {
                return this;
            }

            return new ExternalModuleReferenceSyntax(requireKeyword, openParenToken, stringLiteral, closeParenToken, this.parsedInStrictMode());
        };

        ExternalModuleReferenceSyntax.create1 = function (stringLiteral) {
            return new ExternalModuleReferenceSyntax(TypeScript.Syntax.token(66 /* RequireKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), stringLiteral, TypeScript.Syntax.token(73 /* CloseParenToken */), false);
        };

        ExternalModuleReferenceSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ExternalModuleReferenceSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ExternalModuleReferenceSyntax.prototype.withRequireKeyword = function (requireKeyword) {
            return this.update(requireKeyword, this.openParenToken, this.stringLiteral, this.closeParenToken);
        };

        ExternalModuleReferenceSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.requireKeyword, openParenToken, this.stringLiteral, this.closeParenToken);
        };

        ExternalModuleReferenceSyntax.prototype.withStringLiteral = function (stringLiteral) {
            return this.update(this.requireKeyword, this.openParenToken, stringLiteral, this.closeParenToken);
        };

        ExternalModuleReferenceSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.requireKeyword, this.openParenToken, this.stringLiteral, closeParenToken);
        };

        ExternalModuleReferenceSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ExternalModuleReferenceSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ExternalModuleReferenceSyntax = ExternalModuleReferenceSyntax;

    var ModuleNameModuleReferenceSyntax = (function (_super) {
        __extends(ModuleNameModuleReferenceSyntax, _super);
        function ModuleNameModuleReferenceSyntax(moduleName, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.moduleName = moduleName;
        }
        ModuleNameModuleReferenceSyntax.prototype.accept = function (visitor) {
            return visitor.visitModuleNameModuleReference(this);
        };

        ModuleNameModuleReferenceSyntax.prototype.kind = function () {
            return 246 /* ModuleNameModuleReference */;
        };

        ModuleNameModuleReferenceSyntax.prototype.childCount = function () {
            return 1;
        };

        ModuleNameModuleReferenceSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.moduleName;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ModuleNameModuleReferenceSyntax.prototype.isModuleReference = function () {
            return true;
        };

        ModuleNameModuleReferenceSyntax.prototype.update = function (moduleName) {
            if (this.moduleName === moduleName) {
                return this;
            }

            return new ModuleNameModuleReferenceSyntax(moduleName, this.parsedInStrictMode());
        };

        ModuleNameModuleReferenceSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ModuleNameModuleReferenceSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ModuleNameModuleReferenceSyntax.prototype.withModuleName = function (moduleName) {
            return this.update(moduleName);
        };

        ModuleNameModuleReferenceSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ModuleNameModuleReferenceSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ModuleNameModuleReferenceSyntax = ModuleNameModuleReferenceSyntax;

    var ImportDeclarationSyntax = (function (_super) {
        __extends(ImportDeclarationSyntax, _super);
        function ImportDeclarationSyntax(modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.importKeyword = importKeyword;
            this.identifier = identifier;
            this.equalsToken = equalsToken;
            this.moduleReference = moduleReference;
            this.semicolonToken = semicolonToken;
        }
        ImportDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitImportDeclaration(this);
        };

        ImportDeclarationSyntax.prototype.kind = function () {
            return 133 /* ImportDeclaration */;
        };

        ImportDeclarationSyntax.prototype.childCount = function () {
            return 6;
        };

        ImportDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.importKeyword;
                case 2:
                    return this.identifier;
                case 3:
                    return this.equalsToken;
                case 4:
                    return this.moduleReference;
                case 5:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ImportDeclarationSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ImportDeclarationSyntax.prototype.update = function (modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken) {
            if (this.modifiers === modifiers && this.importKeyword === importKeyword && this.identifier === identifier && this.equalsToken === equalsToken && this.moduleReference === moduleReference && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ImportDeclarationSyntax(modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken, this.parsedInStrictMode());
        };

        ImportDeclarationSyntax.create = function (importKeyword, identifier, equalsToken, moduleReference, semicolonToken) {
            return new ImportDeclarationSyntax(TypeScript.Syntax.emptyList, importKeyword, identifier, equalsToken, moduleReference, semicolonToken, false);
        };

        ImportDeclarationSyntax.create1 = function (identifier, moduleReference) {
            return new ImportDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(49 /* ImportKeyword */), identifier, TypeScript.Syntax.token(107 /* EqualsToken */), moduleReference, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        ImportDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ImportDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ImportDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.importKeyword, this.identifier, this.equalsToken, this.moduleReference, this.semicolonToken);
        };

        ImportDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        ImportDeclarationSyntax.prototype.withImportKeyword = function (importKeyword) {
            return this.update(this.modifiers, importKeyword, this.identifier, this.equalsToken, this.moduleReference, this.semicolonToken);
        };

        ImportDeclarationSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.modifiers, this.importKeyword, identifier, this.equalsToken, this.moduleReference, this.semicolonToken);
        };

        ImportDeclarationSyntax.prototype.withEqualsToken = function (equalsToken) {
            return this.update(this.modifiers, this.importKeyword, this.identifier, equalsToken, this.moduleReference, this.semicolonToken);
        };

        ImportDeclarationSyntax.prototype.withModuleReference = function (moduleReference) {
            return this.update(this.modifiers, this.importKeyword, this.identifier, this.equalsToken, moduleReference, this.semicolonToken);
        };

        ImportDeclarationSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.importKeyword, this.identifier, this.equalsToken, this.moduleReference, semicolonToken);
        };

        ImportDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ImportDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ImportDeclarationSyntax = ImportDeclarationSyntax;

    var ExportAssignmentSyntax = (function (_super) {
        __extends(ExportAssignmentSyntax, _super);
        function ExportAssignmentSyntax(exportKeyword, equalsToken, identifier, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.exportKeyword = exportKeyword;
            this.equalsToken = equalsToken;
            this.identifier = identifier;
            this.semicolonToken = semicolonToken;
        }
        ExportAssignmentSyntax.prototype.accept = function (visitor) {
            return visitor.visitExportAssignment(this);
        };

        ExportAssignmentSyntax.prototype.kind = function () {
            return 134 /* ExportAssignment */;
        };

        ExportAssignmentSyntax.prototype.childCount = function () {
            return 4;
        };

        ExportAssignmentSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.exportKeyword;
                case 1:
                    return this.equalsToken;
                case 2:
                    return this.identifier;
                case 3:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ExportAssignmentSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ExportAssignmentSyntax.prototype.update = function (exportKeyword, equalsToken, identifier, semicolonToken) {
            if (this.exportKeyword === exportKeyword && this.equalsToken === equalsToken && this.identifier === identifier && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ExportAssignmentSyntax(exportKeyword, equalsToken, identifier, semicolonToken, this.parsedInStrictMode());
        };

        ExportAssignmentSyntax.create1 = function (identifier) {
            return new ExportAssignmentSyntax(TypeScript.Syntax.token(47 /* ExportKeyword */), TypeScript.Syntax.token(107 /* EqualsToken */), identifier, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        ExportAssignmentSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ExportAssignmentSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ExportAssignmentSyntax.prototype.withExportKeyword = function (exportKeyword) {
            return this.update(exportKeyword, this.equalsToken, this.identifier, this.semicolonToken);
        };

        ExportAssignmentSyntax.prototype.withEqualsToken = function (equalsToken) {
            return this.update(this.exportKeyword, equalsToken, this.identifier, this.semicolonToken);
        };

        ExportAssignmentSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.exportKeyword, this.equalsToken, identifier, this.semicolonToken);
        };

        ExportAssignmentSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.exportKeyword, this.equalsToken, this.identifier, semicolonToken);
        };

        ExportAssignmentSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ExportAssignmentSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ExportAssignmentSyntax = ExportAssignmentSyntax;

    var ClassDeclarationSyntax = (function (_super) {
        __extends(ClassDeclarationSyntax, _super);
        function ClassDeclarationSyntax(modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.classKeyword = classKeyword;
            this.identifier = identifier;
            this.typeParameterList = typeParameterList;
            this.heritageClauses = heritageClauses;
            this.openBraceToken = openBraceToken;
            this.classElements = classElements;
            this.closeBraceToken = closeBraceToken;
        }
        ClassDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitClassDeclaration(this);
        };

        ClassDeclarationSyntax.prototype.kind = function () {
            return 131 /* ClassDeclaration */;
        };

        ClassDeclarationSyntax.prototype.childCount = function () {
            return 8;
        };

        ClassDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.classKeyword;
                case 2:
                    return this.identifier;
                case 3:
                    return this.typeParameterList;
                case 4:
                    return this.heritageClauses;
                case 5:
                    return this.openBraceToken;
                case 6:
                    return this.classElements;
                case 7:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ClassDeclarationSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ClassDeclarationSyntax.prototype.update = function (modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken) {
            if (this.modifiers === modifiers && this.classKeyword === classKeyword && this.identifier === identifier && this.typeParameterList === typeParameterList && this.heritageClauses === heritageClauses && this.openBraceToken === openBraceToken && this.classElements === classElements && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new ClassDeclarationSyntax(modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken, this.parsedInStrictMode());
        };

        ClassDeclarationSyntax.create = function (classKeyword, identifier, openBraceToken, closeBraceToken) {
            return new ClassDeclarationSyntax(TypeScript.Syntax.emptyList, classKeyword, identifier, null, TypeScript.Syntax.emptyList, openBraceToken, TypeScript.Syntax.emptyList, closeBraceToken, false);
        };

        ClassDeclarationSyntax.create1 = function (identifier) {
            return new ClassDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(44 /* ClassKeyword */), identifier, null, TypeScript.Syntax.emptyList, TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptyList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        ClassDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ClassDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ClassDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.classKeyword, this.identifier, this.typeParameterList, this.heritageClauses, this.openBraceToken, this.classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        ClassDeclarationSyntax.prototype.withClassKeyword = function (classKeyword) {
            return this.update(this.modifiers, classKeyword, this.identifier, this.typeParameterList, this.heritageClauses, this.openBraceToken, this.classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.modifiers, this.classKeyword, identifier, this.typeParameterList, this.heritageClauses, this.openBraceToken, this.classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withTypeParameterList = function (typeParameterList) {
            return this.update(this.modifiers, this.classKeyword, this.identifier, typeParameterList, this.heritageClauses, this.openBraceToken, this.classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withHeritageClauses = function (heritageClauses) {
            return this.update(this.modifiers, this.classKeyword, this.identifier, this.typeParameterList, heritageClauses, this.openBraceToken, this.classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withHeritageClause = function (heritageClause) {
            return this.withHeritageClauses(TypeScript.Syntax.list([heritageClause]));
        };

        ClassDeclarationSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(this.modifiers, this.classKeyword, this.identifier, this.typeParameterList, this.heritageClauses, openBraceToken, this.classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withClassElements = function (classElements) {
            return this.update(this.modifiers, this.classKeyword, this.identifier, this.typeParameterList, this.heritageClauses, this.openBraceToken, classElements, this.closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.withClassElement = function (classElement) {
            return this.withClassElements(TypeScript.Syntax.list([classElement]));
        };

        ClassDeclarationSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.modifiers, this.classKeyword, this.identifier, this.typeParameterList, this.heritageClauses, this.openBraceToken, this.classElements, closeBraceToken);
        };

        ClassDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ClassDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ClassDeclarationSyntax = ClassDeclarationSyntax;

    var InterfaceDeclarationSyntax = (function (_super) {
        __extends(InterfaceDeclarationSyntax, _super);
        function InterfaceDeclarationSyntax(modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.interfaceKeyword = interfaceKeyword;
            this.identifier = identifier;
            this.typeParameterList = typeParameterList;
            this.heritageClauses = heritageClauses;
            this.body = body;
        }
        InterfaceDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitInterfaceDeclaration(this);
        };

        InterfaceDeclarationSyntax.prototype.kind = function () {
            return 128 /* InterfaceDeclaration */;
        };

        InterfaceDeclarationSyntax.prototype.childCount = function () {
            return 6;
        };

        InterfaceDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.interfaceKeyword;
                case 2:
                    return this.identifier;
                case 3:
                    return this.typeParameterList;
                case 4:
                    return this.heritageClauses;
                case 5:
                    return this.body;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        InterfaceDeclarationSyntax.prototype.isModuleElement = function () {
            return true;
        };

        InterfaceDeclarationSyntax.prototype.update = function (modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body) {
            if (this.modifiers === modifiers && this.interfaceKeyword === interfaceKeyword && this.identifier === identifier && this.typeParameterList === typeParameterList && this.heritageClauses === heritageClauses && this.body === body) {
                return this;
            }

            return new InterfaceDeclarationSyntax(modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, body, this.parsedInStrictMode());
        };

        InterfaceDeclarationSyntax.create = function (interfaceKeyword, identifier, body) {
            return new InterfaceDeclarationSyntax(TypeScript.Syntax.emptyList, interfaceKeyword, identifier, null, TypeScript.Syntax.emptyList, body, false);
        };

        InterfaceDeclarationSyntax.create1 = function (identifier) {
            return new InterfaceDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(52 /* InterfaceKeyword */), identifier, null, TypeScript.Syntax.emptyList, ObjectTypeSyntax.create1(), false);
        };

        InterfaceDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        InterfaceDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        InterfaceDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.interfaceKeyword, this.identifier, this.typeParameterList, this.heritageClauses, this.body);
        };

        InterfaceDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        InterfaceDeclarationSyntax.prototype.withInterfaceKeyword = function (interfaceKeyword) {
            return this.update(this.modifiers, interfaceKeyword, this.identifier, this.typeParameterList, this.heritageClauses, this.body);
        };

        InterfaceDeclarationSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.modifiers, this.interfaceKeyword, identifier, this.typeParameterList, this.heritageClauses, this.body);
        };

        InterfaceDeclarationSyntax.prototype.withTypeParameterList = function (typeParameterList) {
            return this.update(this.modifiers, this.interfaceKeyword, this.identifier, typeParameterList, this.heritageClauses, this.body);
        };

        InterfaceDeclarationSyntax.prototype.withHeritageClauses = function (heritageClauses) {
            return this.update(this.modifiers, this.interfaceKeyword, this.identifier, this.typeParameterList, heritageClauses, this.body);
        };

        InterfaceDeclarationSyntax.prototype.withHeritageClause = function (heritageClause) {
            return this.withHeritageClauses(TypeScript.Syntax.list([heritageClause]));
        };

        InterfaceDeclarationSyntax.prototype.withBody = function (body) {
            return this.update(this.modifiers, this.interfaceKeyword, this.identifier, this.typeParameterList, this.heritageClauses, body);
        };

        InterfaceDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return InterfaceDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.InterfaceDeclarationSyntax = InterfaceDeclarationSyntax;

    var HeritageClauseSyntax = (function (_super) {
        __extends(HeritageClauseSyntax, _super);
        function HeritageClauseSyntax(kind, extendsOrImplementsKeyword, typeNames, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.extendsOrImplementsKeyword = extendsOrImplementsKeyword;
            this.typeNames = typeNames;

            this._kind = kind;
        }
        HeritageClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitHeritageClause(this);
        };

        HeritageClauseSyntax.prototype.childCount = function () {
            return 2;
        };

        HeritageClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.extendsOrImplementsKeyword;
                case 1:
                    return this.typeNames;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        HeritageClauseSyntax.prototype.kind = function () {
            return this._kind;
        };

        HeritageClauseSyntax.prototype.update = function (kind, extendsOrImplementsKeyword, typeNames) {
            if (this._kind === kind && this.extendsOrImplementsKeyword === extendsOrImplementsKeyword && this.typeNames === typeNames) {
                return this;
            }

            return new HeritageClauseSyntax(kind, extendsOrImplementsKeyword, typeNames, this.parsedInStrictMode());
        };

        HeritageClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        HeritageClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        HeritageClauseSyntax.prototype.withKind = function (kind) {
            return this.update(kind, this.extendsOrImplementsKeyword, this.typeNames);
        };

        HeritageClauseSyntax.prototype.withExtendsOrImplementsKeyword = function (extendsOrImplementsKeyword) {
            return this.update(this._kind, extendsOrImplementsKeyword, this.typeNames);
        };

        HeritageClauseSyntax.prototype.withTypeNames = function (typeNames) {
            return this.update(this._kind, this.extendsOrImplementsKeyword, typeNames);
        };

        HeritageClauseSyntax.prototype.withTypeName = function (typeName) {
            return this.withTypeNames(TypeScript.Syntax.separatedList([typeName]));
        };

        HeritageClauseSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return HeritageClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.HeritageClauseSyntax = HeritageClauseSyntax;

    var ModuleDeclarationSyntax = (function (_super) {
        __extends(ModuleDeclarationSyntax, _super);
        function ModuleDeclarationSyntax(modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.moduleKeyword = moduleKeyword;
            this.name = name;
            this.stringLiteral = stringLiteral;
            this.openBraceToken = openBraceToken;
            this.moduleElements = moduleElements;
            this.closeBraceToken = closeBraceToken;
        }
        ModuleDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitModuleDeclaration(this);
        };

        ModuleDeclarationSyntax.prototype.kind = function () {
            return 130 /* ModuleDeclaration */;
        };

        ModuleDeclarationSyntax.prototype.childCount = function () {
            return 7;
        };

        ModuleDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.moduleKeyword;
                case 2:
                    return this.name;
                case 3:
                    return this.stringLiteral;
                case 4:
                    return this.openBraceToken;
                case 5:
                    return this.moduleElements;
                case 6:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ModuleDeclarationSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ModuleDeclarationSyntax.prototype.update = function (modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken) {
            if (this.modifiers === modifiers && this.moduleKeyword === moduleKeyword && this.name === name && this.stringLiteral === stringLiteral && this.openBraceToken === openBraceToken && this.moduleElements === moduleElements && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new ModuleDeclarationSyntax(modifiers, moduleKeyword, name, stringLiteral, openBraceToken, moduleElements, closeBraceToken, this.parsedInStrictMode());
        };

        ModuleDeclarationSyntax.create = function (moduleKeyword, openBraceToken, closeBraceToken) {
            return new ModuleDeclarationSyntax(TypeScript.Syntax.emptyList, moduleKeyword, null, null, openBraceToken, TypeScript.Syntax.emptyList, closeBraceToken, false);
        };

        ModuleDeclarationSyntax.create1 = function () {
            return new ModuleDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(65 /* ModuleKeyword */), null, null, TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptyList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        ModuleDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ModuleDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ModuleDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.moduleKeyword, this.name, this.stringLiteral, this.openBraceToken, this.moduleElements, this.closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        ModuleDeclarationSyntax.prototype.withModuleKeyword = function (moduleKeyword) {
            return this.update(this.modifiers, moduleKeyword, this.name, this.stringLiteral, this.openBraceToken, this.moduleElements, this.closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.withName = function (name) {
            return this.update(this.modifiers, this.moduleKeyword, name, this.stringLiteral, this.openBraceToken, this.moduleElements, this.closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.withStringLiteral = function (stringLiteral) {
            return this.update(this.modifiers, this.moduleKeyword, this.name, stringLiteral, this.openBraceToken, this.moduleElements, this.closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(this.modifiers, this.moduleKeyword, this.name, this.stringLiteral, openBraceToken, this.moduleElements, this.closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.withModuleElements = function (moduleElements) {
            return this.update(this.modifiers, this.moduleKeyword, this.name, this.stringLiteral, this.openBraceToken, moduleElements, this.closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.withModuleElement = function (moduleElement) {
            return this.withModuleElements(TypeScript.Syntax.list([moduleElement]));
        };

        ModuleDeclarationSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.modifiers, this.moduleKeyword, this.name, this.stringLiteral, this.openBraceToken, this.moduleElements, closeBraceToken);
        };

        ModuleDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ModuleDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ModuleDeclarationSyntax = ModuleDeclarationSyntax;

    var FunctionDeclarationSyntax = (function (_super) {
        __extends(FunctionDeclarationSyntax, _super);
        function FunctionDeclarationSyntax(modifiers, functionKeyword, identifier, callSignature, block, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.functionKeyword = functionKeyword;
            this.identifier = identifier;
            this.callSignature = callSignature;
            this.block = block;
            this.semicolonToken = semicolonToken;
        }
        FunctionDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitFunctionDeclaration(this);
        };

        FunctionDeclarationSyntax.prototype.kind = function () {
            return 129 /* FunctionDeclaration */;
        };

        FunctionDeclarationSyntax.prototype.childCount = function () {
            return 6;
        };

        FunctionDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.functionKeyword;
                case 2:
                    return this.identifier;
                case 3:
                    return this.callSignature;
                case 4:
                    return this.block;
                case 5:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        FunctionDeclarationSyntax.prototype.isStatement = function () {
            return true;
        };

        FunctionDeclarationSyntax.prototype.isModuleElement = function () {
            return true;
        };

        FunctionDeclarationSyntax.prototype.update = function (modifiers, functionKeyword, identifier, callSignature, block, semicolonToken) {
            if (this.modifiers === modifiers && this.functionKeyword === functionKeyword && this.identifier === identifier && this.callSignature === callSignature && this.block === block && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new FunctionDeclarationSyntax(modifiers, functionKeyword, identifier, callSignature, block, semicolonToken, this.parsedInStrictMode());
        };

        FunctionDeclarationSyntax.create = function (functionKeyword, identifier, callSignature) {
            return new FunctionDeclarationSyntax(TypeScript.Syntax.emptyList, functionKeyword, identifier, callSignature, null, null, false);
        };

        FunctionDeclarationSyntax.create1 = function (identifier) {
            return new FunctionDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(27 /* FunctionKeyword */), identifier, CallSignatureSyntax.create1(), null, null, false);
        };

        FunctionDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        FunctionDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        FunctionDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.functionKeyword, this.identifier, this.callSignature, this.block, this.semicolonToken);
        };

        FunctionDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        FunctionDeclarationSyntax.prototype.withFunctionKeyword = function (functionKeyword) {
            return this.update(this.modifiers, functionKeyword, this.identifier, this.callSignature, this.block, this.semicolonToken);
        };

        FunctionDeclarationSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.modifiers, this.functionKeyword, identifier, this.callSignature, this.block, this.semicolonToken);
        };

        FunctionDeclarationSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.modifiers, this.functionKeyword, this.identifier, callSignature, this.block, this.semicolonToken);
        };

        FunctionDeclarationSyntax.prototype.withBlock = function (block) {
            return this.update(this.modifiers, this.functionKeyword, this.identifier, this.callSignature, block, this.semicolonToken);
        };

        FunctionDeclarationSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.functionKeyword, this.identifier, this.callSignature, this.block, semicolonToken);
        };

        FunctionDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.modifiers.childCount() > 0) {
                return true;
            }
            if (this.callSignature.isTypeScriptSpecific()) {
                return true;
            }
            if (this.block !== null && this.block.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return FunctionDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.FunctionDeclarationSyntax = FunctionDeclarationSyntax;

    var VariableStatementSyntax = (function (_super) {
        __extends(VariableStatementSyntax, _super);
        function VariableStatementSyntax(modifiers, variableDeclaration, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.variableDeclaration = variableDeclaration;
            this.semicolonToken = semicolonToken;
        }
        VariableStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitVariableStatement(this);
        };

        VariableStatementSyntax.prototype.kind = function () {
            return 148 /* VariableStatement */;
        };

        VariableStatementSyntax.prototype.childCount = function () {
            return 3;
        };

        VariableStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.variableDeclaration;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        VariableStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        VariableStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        VariableStatementSyntax.prototype.update = function (modifiers, variableDeclaration, semicolonToken) {
            if (this.modifiers === modifiers && this.variableDeclaration === variableDeclaration && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new VariableStatementSyntax(modifiers, variableDeclaration, semicolonToken, this.parsedInStrictMode());
        };

        VariableStatementSyntax.create = function (variableDeclaration, semicolonToken) {
            return new VariableStatementSyntax(TypeScript.Syntax.emptyList, variableDeclaration, semicolonToken, false);
        };

        VariableStatementSyntax.create1 = function (variableDeclaration) {
            return new VariableStatementSyntax(TypeScript.Syntax.emptyList, variableDeclaration, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        VariableStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        VariableStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        VariableStatementSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.variableDeclaration, this.semicolonToken);
        };

        VariableStatementSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        VariableStatementSyntax.prototype.withVariableDeclaration = function (variableDeclaration) {
            return this.update(this.modifiers, variableDeclaration, this.semicolonToken);
        };

        VariableStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.variableDeclaration, semicolonToken);
        };

        VariableStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.modifiers.childCount() > 0) {
                return true;
            }
            if (this.variableDeclaration.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return VariableStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.VariableStatementSyntax = VariableStatementSyntax;

    var VariableDeclarationSyntax = (function (_super) {
        __extends(VariableDeclarationSyntax, _super);
        function VariableDeclarationSyntax(varKeyword, variableDeclarators, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.varKeyword = varKeyword;
            this.variableDeclarators = variableDeclarators;
        }
        VariableDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitVariableDeclaration(this);
        };

        VariableDeclarationSyntax.prototype.kind = function () {
            return 224 /* VariableDeclaration */;
        };

        VariableDeclarationSyntax.prototype.childCount = function () {
            return 2;
        };

        VariableDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.varKeyword;
                case 1:
                    return this.variableDeclarators;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        VariableDeclarationSyntax.prototype.update = function (varKeyword, variableDeclarators) {
            if (this.varKeyword === varKeyword && this.variableDeclarators === variableDeclarators) {
                return this;
            }

            return new VariableDeclarationSyntax(varKeyword, variableDeclarators, this.parsedInStrictMode());
        };

        VariableDeclarationSyntax.create1 = function (variableDeclarators) {
            return new VariableDeclarationSyntax(TypeScript.Syntax.token(40 /* VarKeyword */), variableDeclarators, false);
        };

        VariableDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        VariableDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        VariableDeclarationSyntax.prototype.withVarKeyword = function (varKeyword) {
            return this.update(varKeyword, this.variableDeclarators);
        };

        VariableDeclarationSyntax.prototype.withVariableDeclarators = function (variableDeclarators) {
            return this.update(this.varKeyword, variableDeclarators);
        };

        VariableDeclarationSyntax.prototype.withVariableDeclarator = function (variableDeclarator) {
            return this.withVariableDeclarators(TypeScript.Syntax.separatedList([variableDeclarator]));
        };

        VariableDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.variableDeclarators.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return VariableDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.VariableDeclarationSyntax = VariableDeclarationSyntax;

    var VariableDeclaratorSyntax = (function (_super) {
        __extends(VariableDeclaratorSyntax, _super);
        function VariableDeclaratorSyntax(propertyName, typeAnnotation, equalsValueClause, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.propertyName = propertyName;
            this.typeAnnotation = typeAnnotation;
            this.equalsValueClause = equalsValueClause;
        }
        VariableDeclaratorSyntax.prototype.accept = function (visitor) {
            return visitor.visitVariableDeclarator(this);
        };

        VariableDeclaratorSyntax.prototype.kind = function () {
            return 225 /* VariableDeclarator */;
        };

        VariableDeclaratorSyntax.prototype.childCount = function () {
            return 3;
        };

        VariableDeclaratorSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.propertyName;
                case 1:
                    return this.typeAnnotation;
                case 2:
                    return this.equalsValueClause;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        VariableDeclaratorSyntax.prototype.update = function (propertyName, typeAnnotation, equalsValueClause) {
            if (this.propertyName === propertyName && this.typeAnnotation === typeAnnotation && this.equalsValueClause === equalsValueClause) {
                return this;
            }

            return new VariableDeclaratorSyntax(propertyName, typeAnnotation, equalsValueClause, this.parsedInStrictMode());
        };

        VariableDeclaratorSyntax.create = function (propertyName) {
            return new VariableDeclaratorSyntax(propertyName, null, null, false);
        };

        VariableDeclaratorSyntax.create1 = function (propertyName) {
            return new VariableDeclaratorSyntax(propertyName, null, null, false);
        };

        VariableDeclaratorSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        VariableDeclaratorSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        VariableDeclaratorSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(propertyName, this.typeAnnotation, this.equalsValueClause);
        };

        VariableDeclaratorSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.propertyName, typeAnnotation, this.equalsValueClause);
        };

        VariableDeclaratorSyntax.prototype.withEqualsValueClause = function (equalsValueClause) {
            return this.update(this.propertyName, this.typeAnnotation, equalsValueClause);
        };

        VariableDeclaratorSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.typeAnnotation !== null) {
                return true;
            }
            if (this.equalsValueClause !== null && this.equalsValueClause.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return VariableDeclaratorSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.VariableDeclaratorSyntax = VariableDeclaratorSyntax;

    var EqualsValueClauseSyntax = (function (_super) {
        __extends(EqualsValueClauseSyntax, _super);
        function EqualsValueClauseSyntax(equalsToken, value, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.equalsToken = equalsToken;
            this.value = value;
        }
        EqualsValueClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitEqualsValueClause(this);
        };

        EqualsValueClauseSyntax.prototype.kind = function () {
            return 232 /* EqualsValueClause */;
        };

        EqualsValueClauseSyntax.prototype.childCount = function () {
            return 2;
        };

        EqualsValueClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.equalsToken;
                case 1:
                    return this.value;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        EqualsValueClauseSyntax.prototype.update = function (equalsToken, value) {
            if (this.equalsToken === equalsToken && this.value === value) {
                return this;
            }

            return new EqualsValueClauseSyntax(equalsToken, value, this.parsedInStrictMode());
        };

        EqualsValueClauseSyntax.create1 = function (value) {
            return new EqualsValueClauseSyntax(TypeScript.Syntax.token(107 /* EqualsToken */), value, false);
        };

        EqualsValueClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        EqualsValueClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        EqualsValueClauseSyntax.prototype.withEqualsToken = function (equalsToken) {
            return this.update(equalsToken, this.value);
        };

        EqualsValueClauseSyntax.prototype.withValue = function (value) {
            return this.update(this.equalsToken, value);
        };

        EqualsValueClauseSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.value.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return EqualsValueClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.EqualsValueClauseSyntax = EqualsValueClauseSyntax;

    var PrefixUnaryExpressionSyntax = (function (_super) {
        __extends(PrefixUnaryExpressionSyntax, _super);
        function PrefixUnaryExpressionSyntax(kind, operatorToken, operand, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.operatorToken = operatorToken;
            this.operand = operand;

            this._kind = kind;
        }
        PrefixUnaryExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitPrefixUnaryExpression(this);
        };

        PrefixUnaryExpressionSyntax.prototype.childCount = function () {
            return 2;
        };

        PrefixUnaryExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.operatorToken;
                case 1:
                    return this.operand;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        PrefixUnaryExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        PrefixUnaryExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        PrefixUnaryExpressionSyntax.prototype.kind = function () {
            return this._kind;
        };

        PrefixUnaryExpressionSyntax.prototype.update = function (kind, operatorToken, operand) {
            if (this._kind === kind && this.operatorToken === operatorToken && this.operand === operand) {
                return this;
            }

            return new PrefixUnaryExpressionSyntax(kind, operatorToken, operand, this.parsedInStrictMode());
        };

        PrefixUnaryExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        PrefixUnaryExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        PrefixUnaryExpressionSyntax.prototype.withKind = function (kind) {
            return this.update(kind, this.operatorToken, this.operand);
        };

        PrefixUnaryExpressionSyntax.prototype.withOperatorToken = function (operatorToken) {
            return this.update(this._kind, operatorToken, this.operand);
        };

        PrefixUnaryExpressionSyntax.prototype.withOperand = function (operand) {
            return this.update(this._kind, this.operatorToken, operand);
        };

        PrefixUnaryExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.operand.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return PrefixUnaryExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.PrefixUnaryExpressionSyntax = PrefixUnaryExpressionSyntax;

    var ArrayLiteralExpressionSyntax = (function (_super) {
        __extends(ArrayLiteralExpressionSyntax, _super);
        function ArrayLiteralExpressionSyntax(openBracketToken, expressions, closeBracketToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openBracketToken = openBracketToken;
            this.expressions = expressions;
            this.closeBracketToken = closeBracketToken;
        }
        ArrayLiteralExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitArrayLiteralExpression(this);
        };

        ArrayLiteralExpressionSyntax.prototype.kind = function () {
            return 214 /* ArrayLiteralExpression */;
        };

        ArrayLiteralExpressionSyntax.prototype.childCount = function () {
            return 3;
        };

        ArrayLiteralExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openBracketToken;
                case 1:
                    return this.expressions;
                case 2:
                    return this.closeBracketToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ArrayLiteralExpressionSyntax.prototype.isPrimaryExpression = function () {
            return true;
        };

        ArrayLiteralExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        ArrayLiteralExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        ArrayLiteralExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        ArrayLiteralExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ArrayLiteralExpressionSyntax.prototype.update = function (openBracketToken, expressions, closeBracketToken) {
            if (this.openBracketToken === openBracketToken && this.expressions === expressions && this.closeBracketToken === closeBracketToken) {
                return this;
            }

            return new ArrayLiteralExpressionSyntax(openBracketToken, expressions, closeBracketToken, this.parsedInStrictMode());
        };

        ArrayLiteralExpressionSyntax.create = function (openBracketToken, closeBracketToken) {
            return new ArrayLiteralExpressionSyntax(openBracketToken, TypeScript.Syntax.emptySeparatedList, closeBracketToken, false);
        };

        ArrayLiteralExpressionSyntax.create1 = function () {
            return new ArrayLiteralExpressionSyntax(TypeScript.Syntax.token(74 /* OpenBracketToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(75 /* CloseBracketToken */), false);
        };

        ArrayLiteralExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ArrayLiteralExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ArrayLiteralExpressionSyntax.prototype.withOpenBracketToken = function (openBracketToken) {
            return this.update(openBracketToken, this.expressions, this.closeBracketToken);
        };

        ArrayLiteralExpressionSyntax.prototype.withExpressions = function (expressions) {
            return this.update(this.openBracketToken, expressions, this.closeBracketToken);
        };

        ArrayLiteralExpressionSyntax.prototype.withExpression = function (expression) {
            return this.withExpressions(TypeScript.Syntax.separatedList([expression]));
        };

        ArrayLiteralExpressionSyntax.prototype.withCloseBracketToken = function (closeBracketToken) {
            return this.update(this.openBracketToken, this.expressions, closeBracketToken);
        };

        ArrayLiteralExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expressions.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ArrayLiteralExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ArrayLiteralExpressionSyntax = ArrayLiteralExpressionSyntax;

    var OmittedExpressionSyntax = (function (_super) {
        __extends(OmittedExpressionSyntax, _super);
        function OmittedExpressionSyntax(parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
        }
        OmittedExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitOmittedExpression(this);
        };

        OmittedExpressionSyntax.prototype.kind = function () {
            return 223 /* OmittedExpression */;
        };

        OmittedExpressionSyntax.prototype.childCount = function () {
            return 0;
        };

        OmittedExpressionSyntax.prototype.childAt = function (slot) {
            throw TypeScript.Errors.invalidOperation();
        };

        OmittedExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        OmittedExpressionSyntax.prototype.update = function () {
            return this;
        };

        OmittedExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        OmittedExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        OmittedExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            return false;
        };
        return OmittedExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.OmittedExpressionSyntax = OmittedExpressionSyntax;

    var ParenthesizedExpressionSyntax = (function (_super) {
        __extends(ParenthesizedExpressionSyntax, _super);
        function ParenthesizedExpressionSyntax(openParenToken, expression, closeParenToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openParenToken = openParenToken;
            this.expression = expression;
            this.closeParenToken = closeParenToken;
        }
        ParenthesizedExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitParenthesizedExpression(this);
        };

        ParenthesizedExpressionSyntax.prototype.kind = function () {
            return 217 /* ParenthesizedExpression */;
        };

        ParenthesizedExpressionSyntax.prototype.childCount = function () {
            return 3;
        };

        ParenthesizedExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openParenToken;
                case 1:
                    return this.expression;
                case 2:
                    return this.closeParenToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ParenthesizedExpressionSyntax.prototype.isPrimaryExpression = function () {
            return true;
        };

        ParenthesizedExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        ParenthesizedExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        ParenthesizedExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        ParenthesizedExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ParenthesizedExpressionSyntax.prototype.update = function (openParenToken, expression, closeParenToken) {
            if (this.openParenToken === openParenToken && this.expression === expression && this.closeParenToken === closeParenToken) {
                return this;
            }

            return new ParenthesizedExpressionSyntax(openParenToken, expression, closeParenToken, this.parsedInStrictMode());
        };

        ParenthesizedExpressionSyntax.create1 = function (expression) {
            return new ParenthesizedExpressionSyntax(TypeScript.Syntax.token(72 /* OpenParenToken */), expression, TypeScript.Syntax.token(73 /* CloseParenToken */), false);
        };

        ParenthesizedExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ParenthesizedExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ParenthesizedExpressionSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(openParenToken, this.expression, this.closeParenToken);
        };

        ParenthesizedExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.openParenToken, expression, this.closeParenToken);
        };

        ParenthesizedExpressionSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.openParenToken, this.expression, closeParenToken);
        };

        ParenthesizedExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ParenthesizedExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ParenthesizedExpressionSyntax = ParenthesizedExpressionSyntax;

    var SimpleArrowFunctionExpressionSyntax = (function (_super) {
        __extends(SimpleArrowFunctionExpressionSyntax, _super);
        function SimpleArrowFunctionExpressionSyntax(identifier, equalsGreaterThanToken, block, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.identifier = identifier;
            this.equalsGreaterThanToken = equalsGreaterThanToken;
            this.block = block;
            this.expression = expression;
        }
        SimpleArrowFunctionExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitSimpleArrowFunctionExpression(this);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.kind = function () {
            return 219 /* SimpleArrowFunctionExpression */;
        };

        SimpleArrowFunctionExpressionSyntax.prototype.childCount = function () {
            return 4;
        };

        SimpleArrowFunctionExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.identifier;
                case 1:
                    return this.equalsGreaterThanToken;
                case 2:
                    return this.block;
                case 3:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        SimpleArrowFunctionExpressionSyntax.prototype.isArrowFunctionExpression = function () {
            return true;
        };

        SimpleArrowFunctionExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        SimpleArrowFunctionExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        SimpleArrowFunctionExpressionSyntax.prototype.update = function (identifier, equalsGreaterThanToken, block, expression) {
            if (this.identifier === identifier && this.equalsGreaterThanToken === equalsGreaterThanToken && this.block === block && this.expression === expression) {
                return this;
            }

            return new SimpleArrowFunctionExpressionSyntax(identifier, equalsGreaterThanToken, block, expression, this.parsedInStrictMode());
        };

        SimpleArrowFunctionExpressionSyntax.create = function (identifier, equalsGreaterThanToken) {
            return new SimpleArrowFunctionExpressionSyntax(identifier, equalsGreaterThanToken, null, null, false);
        };

        SimpleArrowFunctionExpressionSyntax.create1 = function (identifier) {
            return new SimpleArrowFunctionExpressionSyntax(identifier, TypeScript.Syntax.token(85 /* EqualsGreaterThanToken */), null, null, false);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(identifier, this.equalsGreaterThanToken, this.block, this.expression);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.withEqualsGreaterThanToken = function (equalsGreaterThanToken) {
            return this.update(this.identifier, equalsGreaterThanToken, this.block, this.expression);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.withBlock = function (block) {
            return this.update(this.identifier, this.equalsGreaterThanToken, block, this.expression);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.identifier, this.equalsGreaterThanToken, this.block, expression);
        };

        SimpleArrowFunctionExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return SimpleArrowFunctionExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.SimpleArrowFunctionExpressionSyntax = SimpleArrowFunctionExpressionSyntax;

    var ParenthesizedArrowFunctionExpressionSyntax = (function (_super) {
        __extends(ParenthesizedArrowFunctionExpressionSyntax, _super);
        function ParenthesizedArrowFunctionExpressionSyntax(callSignature, equalsGreaterThanToken, block, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.callSignature = callSignature;
            this.equalsGreaterThanToken = equalsGreaterThanToken;
            this.block = block;
            this.expression = expression;
        }
        ParenthesizedArrowFunctionExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitParenthesizedArrowFunctionExpression(this);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.kind = function () {
            return 218 /* ParenthesizedArrowFunctionExpression */;
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.childCount = function () {
            return 4;
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.callSignature;
                case 1:
                    return this.equalsGreaterThanToken;
                case 2:
                    return this.block;
                case 3:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.isArrowFunctionExpression = function () {
            return true;
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.update = function (callSignature, equalsGreaterThanToken, block, expression) {
            if (this.callSignature === callSignature && this.equalsGreaterThanToken === equalsGreaterThanToken && this.block === block && this.expression === expression) {
                return this;
            }

            return new ParenthesizedArrowFunctionExpressionSyntax(callSignature, equalsGreaterThanToken, block, expression, this.parsedInStrictMode());
        };

        ParenthesizedArrowFunctionExpressionSyntax.create = function (callSignature, equalsGreaterThanToken) {
            return new ParenthesizedArrowFunctionExpressionSyntax(callSignature, equalsGreaterThanToken, null, null, false);
        };

        ParenthesizedArrowFunctionExpressionSyntax.create1 = function () {
            return new ParenthesizedArrowFunctionExpressionSyntax(CallSignatureSyntax.create1(), TypeScript.Syntax.token(85 /* EqualsGreaterThanToken */), null, null, false);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(callSignature, this.equalsGreaterThanToken, this.block, this.expression);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.withEqualsGreaterThanToken = function (equalsGreaterThanToken) {
            return this.update(this.callSignature, equalsGreaterThanToken, this.block, this.expression);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.withBlock = function (block) {
            return this.update(this.callSignature, this.equalsGreaterThanToken, block, this.expression);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.callSignature, this.equalsGreaterThanToken, this.block, expression);
        };

        ParenthesizedArrowFunctionExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ParenthesizedArrowFunctionExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ParenthesizedArrowFunctionExpressionSyntax = ParenthesizedArrowFunctionExpressionSyntax;

    var QualifiedNameSyntax = (function (_super) {
        __extends(QualifiedNameSyntax, _super);
        function QualifiedNameSyntax(left, dotToken, right, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.left = left;
            this.dotToken = dotToken;
            this.right = right;
        }
        QualifiedNameSyntax.prototype.accept = function (visitor) {
            return visitor.visitQualifiedName(this);
        };

        QualifiedNameSyntax.prototype.kind = function () {
            return 121 /* QualifiedName */;
        };

        QualifiedNameSyntax.prototype.childCount = function () {
            return 3;
        };

        QualifiedNameSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.left;
                case 1:
                    return this.dotToken;
                case 2:
                    return this.right;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        QualifiedNameSyntax.prototype.isName = function () {
            return true;
        };

        QualifiedNameSyntax.prototype.isType = function () {
            return true;
        };

        QualifiedNameSyntax.prototype.update = function (left, dotToken, right) {
            if (this.left === left && this.dotToken === dotToken && this.right === right) {
                return this;
            }

            return new QualifiedNameSyntax(left, dotToken, right, this.parsedInStrictMode());
        };

        QualifiedNameSyntax.create1 = function (left, right) {
            return new QualifiedNameSyntax(left, TypeScript.Syntax.token(76 /* DotToken */), right, false);
        };

        QualifiedNameSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        QualifiedNameSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        QualifiedNameSyntax.prototype.withLeft = function (left) {
            return this.update(left, this.dotToken, this.right);
        };

        QualifiedNameSyntax.prototype.withDotToken = function (dotToken) {
            return this.update(this.left, dotToken, this.right);
        };

        QualifiedNameSyntax.prototype.withRight = function (right) {
            return this.update(this.left, this.dotToken, right);
        };

        QualifiedNameSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return QualifiedNameSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.QualifiedNameSyntax = QualifiedNameSyntax;

    var TypeArgumentListSyntax = (function (_super) {
        __extends(TypeArgumentListSyntax, _super);
        function TypeArgumentListSyntax(lessThanToken, typeArguments, greaterThanToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.lessThanToken = lessThanToken;
            this.typeArguments = typeArguments;
            this.greaterThanToken = greaterThanToken;
        }
        TypeArgumentListSyntax.prototype.accept = function (visitor) {
            return visitor.visitTypeArgumentList(this);
        };

        TypeArgumentListSyntax.prototype.kind = function () {
            return 228 /* TypeArgumentList */;
        };

        TypeArgumentListSyntax.prototype.childCount = function () {
            return 3;
        };

        TypeArgumentListSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.lessThanToken;
                case 1:
                    return this.typeArguments;
                case 2:
                    return this.greaterThanToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TypeArgumentListSyntax.prototype.update = function (lessThanToken, typeArguments, greaterThanToken) {
            if (this.lessThanToken === lessThanToken && this.typeArguments === typeArguments && this.greaterThanToken === greaterThanToken) {
                return this;
            }

            return new TypeArgumentListSyntax(lessThanToken, typeArguments, greaterThanToken, this.parsedInStrictMode());
        };

        TypeArgumentListSyntax.create = function (lessThanToken, greaterThanToken) {
            return new TypeArgumentListSyntax(lessThanToken, TypeScript.Syntax.emptySeparatedList, greaterThanToken, false);
        };

        TypeArgumentListSyntax.create1 = function () {
            return new TypeArgumentListSyntax(TypeScript.Syntax.token(80 /* LessThanToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(81 /* GreaterThanToken */), false);
        };

        TypeArgumentListSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TypeArgumentListSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TypeArgumentListSyntax.prototype.withLessThanToken = function (lessThanToken) {
            return this.update(lessThanToken, this.typeArguments, this.greaterThanToken);
        };

        TypeArgumentListSyntax.prototype.withTypeArguments = function (typeArguments) {
            return this.update(this.lessThanToken, typeArguments, this.greaterThanToken);
        };

        TypeArgumentListSyntax.prototype.withTypeArgument = function (typeArgument) {
            return this.withTypeArguments(TypeScript.Syntax.separatedList([typeArgument]));
        };

        TypeArgumentListSyntax.prototype.withGreaterThanToken = function (greaterThanToken) {
            return this.update(this.lessThanToken, this.typeArguments, greaterThanToken);
        };

        TypeArgumentListSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return TypeArgumentListSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TypeArgumentListSyntax = TypeArgumentListSyntax;

    var ConstructorTypeSyntax = (function (_super) {
        __extends(ConstructorTypeSyntax, _super);
        function ConstructorTypeSyntax(newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.newKeyword = newKeyword;
            this.typeParameterList = typeParameterList;
            this.parameterList = parameterList;
            this.equalsGreaterThanToken = equalsGreaterThanToken;
            this.type = type;
        }
        ConstructorTypeSyntax.prototype.accept = function (visitor) {
            return visitor.visitConstructorType(this);
        };

        ConstructorTypeSyntax.prototype.kind = function () {
            return 125 /* ConstructorType */;
        };

        ConstructorTypeSyntax.prototype.childCount = function () {
            return 5;
        };

        ConstructorTypeSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.newKeyword;
                case 1:
                    return this.typeParameterList;
                case 2:
                    return this.parameterList;
                case 3:
                    return this.equalsGreaterThanToken;
                case 4:
                    return this.type;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ConstructorTypeSyntax.prototype.isType = function () {
            return true;
        };

        ConstructorTypeSyntax.prototype.update = function (newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type) {
            if (this.newKeyword === newKeyword && this.typeParameterList === typeParameterList && this.parameterList === parameterList && this.equalsGreaterThanToken === equalsGreaterThanToken && this.type === type) {
                return this;
            }

            return new ConstructorTypeSyntax(newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type, this.parsedInStrictMode());
        };

        ConstructorTypeSyntax.create = function (newKeyword, parameterList, equalsGreaterThanToken, type) {
            return new ConstructorTypeSyntax(newKeyword, null, parameterList, equalsGreaterThanToken, type, false);
        };

        ConstructorTypeSyntax.create1 = function (type) {
            return new ConstructorTypeSyntax(TypeScript.Syntax.token(31 /* NewKeyword */), null, ParameterListSyntax.create1(), TypeScript.Syntax.token(85 /* EqualsGreaterThanToken */), type, false);
        };

        ConstructorTypeSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ConstructorTypeSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ConstructorTypeSyntax.prototype.withNewKeyword = function (newKeyword) {
            return this.update(newKeyword, this.typeParameterList, this.parameterList, this.equalsGreaterThanToken, this.type);
        };

        ConstructorTypeSyntax.prototype.withTypeParameterList = function (typeParameterList) {
            return this.update(this.newKeyword, typeParameterList, this.parameterList, this.equalsGreaterThanToken, this.type);
        };

        ConstructorTypeSyntax.prototype.withParameterList = function (parameterList) {
            return this.update(this.newKeyword, this.typeParameterList, parameterList, this.equalsGreaterThanToken, this.type);
        };

        ConstructorTypeSyntax.prototype.withEqualsGreaterThanToken = function (equalsGreaterThanToken) {
            return this.update(this.newKeyword, this.typeParameterList, this.parameterList, equalsGreaterThanToken, this.type);
        };

        ConstructorTypeSyntax.prototype.withType = function (type) {
            return this.update(this.newKeyword, this.typeParameterList, this.parameterList, this.equalsGreaterThanToken, type);
        };

        ConstructorTypeSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ConstructorTypeSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ConstructorTypeSyntax = ConstructorTypeSyntax;

    var FunctionTypeSyntax = (function (_super) {
        __extends(FunctionTypeSyntax, _super);
        function FunctionTypeSyntax(typeParameterList, parameterList, equalsGreaterThanToken, type, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.typeParameterList = typeParameterList;
            this.parameterList = parameterList;
            this.equalsGreaterThanToken = equalsGreaterThanToken;
            this.type = type;
        }
        FunctionTypeSyntax.prototype.accept = function (visitor) {
            return visitor.visitFunctionType(this);
        };

        FunctionTypeSyntax.prototype.kind = function () {
            return 123 /* FunctionType */;
        };

        FunctionTypeSyntax.prototype.childCount = function () {
            return 4;
        };

        FunctionTypeSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.typeParameterList;
                case 1:
                    return this.parameterList;
                case 2:
                    return this.equalsGreaterThanToken;
                case 3:
                    return this.type;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        FunctionTypeSyntax.prototype.isType = function () {
            return true;
        };

        FunctionTypeSyntax.prototype.update = function (typeParameterList, parameterList, equalsGreaterThanToken, type) {
            if (this.typeParameterList === typeParameterList && this.parameterList === parameterList && this.equalsGreaterThanToken === equalsGreaterThanToken && this.type === type) {
                return this;
            }

            return new FunctionTypeSyntax(typeParameterList, parameterList, equalsGreaterThanToken, type, this.parsedInStrictMode());
        };

        FunctionTypeSyntax.create = function (parameterList, equalsGreaterThanToken, type) {
            return new FunctionTypeSyntax(null, parameterList, equalsGreaterThanToken, type, false);
        };

        FunctionTypeSyntax.create1 = function (type) {
            return new FunctionTypeSyntax(null, ParameterListSyntax.create1(), TypeScript.Syntax.token(85 /* EqualsGreaterThanToken */), type, false);
        };

        FunctionTypeSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        FunctionTypeSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        FunctionTypeSyntax.prototype.withTypeParameterList = function (typeParameterList) {
            return this.update(typeParameterList, this.parameterList, this.equalsGreaterThanToken, this.type);
        };

        FunctionTypeSyntax.prototype.withParameterList = function (parameterList) {
            return this.update(this.typeParameterList, parameterList, this.equalsGreaterThanToken, this.type);
        };

        FunctionTypeSyntax.prototype.withEqualsGreaterThanToken = function (equalsGreaterThanToken) {
            return this.update(this.typeParameterList, this.parameterList, equalsGreaterThanToken, this.type);
        };

        FunctionTypeSyntax.prototype.withType = function (type) {
            return this.update(this.typeParameterList, this.parameterList, this.equalsGreaterThanToken, type);
        };

        FunctionTypeSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return FunctionTypeSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.FunctionTypeSyntax = FunctionTypeSyntax;

    var ObjectTypeSyntax = (function (_super) {
        __extends(ObjectTypeSyntax, _super);
        function ObjectTypeSyntax(openBraceToken, typeMembers, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openBraceToken = openBraceToken;
            this.typeMembers = typeMembers;
            this.closeBraceToken = closeBraceToken;
        }
        ObjectTypeSyntax.prototype.accept = function (visitor) {
            return visitor.visitObjectType(this);
        };

        ObjectTypeSyntax.prototype.kind = function () {
            return 122 /* ObjectType */;
        };

        ObjectTypeSyntax.prototype.childCount = function () {
            return 3;
        };

        ObjectTypeSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openBraceToken;
                case 1:
                    return this.typeMembers;
                case 2:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ObjectTypeSyntax.prototype.isType = function () {
            return true;
        };

        ObjectTypeSyntax.prototype.update = function (openBraceToken, typeMembers, closeBraceToken) {
            if (this.openBraceToken === openBraceToken && this.typeMembers === typeMembers && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new ObjectTypeSyntax(openBraceToken, typeMembers, closeBraceToken, this.parsedInStrictMode());
        };

        ObjectTypeSyntax.create = function (openBraceToken, closeBraceToken) {
            return new ObjectTypeSyntax(openBraceToken, TypeScript.Syntax.emptySeparatedList, closeBraceToken, false);
        };

        ObjectTypeSyntax.create1 = function () {
            return new ObjectTypeSyntax(TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        ObjectTypeSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ObjectTypeSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ObjectTypeSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(openBraceToken, this.typeMembers, this.closeBraceToken);
        };

        ObjectTypeSyntax.prototype.withTypeMembers = function (typeMembers) {
            return this.update(this.openBraceToken, typeMembers, this.closeBraceToken);
        };

        ObjectTypeSyntax.prototype.withTypeMember = function (typeMember) {
            return this.withTypeMembers(TypeScript.Syntax.separatedList([typeMember]));
        };

        ObjectTypeSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.openBraceToken, this.typeMembers, closeBraceToken);
        };

        ObjectTypeSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ObjectTypeSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ObjectTypeSyntax = ObjectTypeSyntax;

    var ArrayTypeSyntax = (function (_super) {
        __extends(ArrayTypeSyntax, _super);
        function ArrayTypeSyntax(type, openBracketToken, closeBracketToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.type = type;
            this.openBracketToken = openBracketToken;
            this.closeBracketToken = closeBracketToken;
        }
        ArrayTypeSyntax.prototype.accept = function (visitor) {
            return visitor.visitArrayType(this);
        };

        ArrayTypeSyntax.prototype.kind = function () {
            return 124 /* ArrayType */;
        };

        ArrayTypeSyntax.prototype.childCount = function () {
            return 3;
        };

        ArrayTypeSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.type;
                case 1:
                    return this.openBracketToken;
                case 2:
                    return this.closeBracketToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ArrayTypeSyntax.prototype.isType = function () {
            return true;
        };

        ArrayTypeSyntax.prototype.update = function (type, openBracketToken, closeBracketToken) {
            if (this.type === type && this.openBracketToken === openBracketToken && this.closeBracketToken === closeBracketToken) {
                return this;
            }

            return new ArrayTypeSyntax(type, openBracketToken, closeBracketToken, this.parsedInStrictMode());
        };

        ArrayTypeSyntax.create1 = function (type) {
            return new ArrayTypeSyntax(type, TypeScript.Syntax.token(74 /* OpenBracketToken */), TypeScript.Syntax.token(75 /* CloseBracketToken */), false);
        };

        ArrayTypeSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ArrayTypeSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ArrayTypeSyntax.prototype.withType = function (type) {
            return this.update(type, this.openBracketToken, this.closeBracketToken);
        };

        ArrayTypeSyntax.prototype.withOpenBracketToken = function (openBracketToken) {
            return this.update(this.type, openBracketToken, this.closeBracketToken);
        };

        ArrayTypeSyntax.prototype.withCloseBracketToken = function (closeBracketToken) {
            return this.update(this.type, this.openBracketToken, closeBracketToken);
        };

        ArrayTypeSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ArrayTypeSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ArrayTypeSyntax = ArrayTypeSyntax;

    var GenericTypeSyntax = (function (_super) {
        __extends(GenericTypeSyntax, _super);
        function GenericTypeSyntax(name, typeArgumentList, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.name = name;
            this.typeArgumentList = typeArgumentList;
        }
        GenericTypeSyntax.prototype.accept = function (visitor) {
            return visitor.visitGenericType(this);
        };

        GenericTypeSyntax.prototype.kind = function () {
            return 126 /* GenericType */;
        };

        GenericTypeSyntax.prototype.childCount = function () {
            return 2;
        };

        GenericTypeSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.name;
                case 1:
                    return this.typeArgumentList;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        GenericTypeSyntax.prototype.isType = function () {
            return true;
        };

        GenericTypeSyntax.prototype.update = function (name, typeArgumentList) {
            if (this.name === name && this.typeArgumentList === typeArgumentList) {
                return this;
            }

            return new GenericTypeSyntax(name, typeArgumentList, this.parsedInStrictMode());
        };

        GenericTypeSyntax.create1 = function (name) {
            return new GenericTypeSyntax(name, TypeArgumentListSyntax.create1(), false);
        };

        GenericTypeSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        GenericTypeSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        GenericTypeSyntax.prototype.withName = function (name) {
            return this.update(name, this.typeArgumentList);
        };

        GenericTypeSyntax.prototype.withTypeArgumentList = function (typeArgumentList) {
            return this.update(this.name, typeArgumentList);
        };

        GenericTypeSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return GenericTypeSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.GenericTypeSyntax = GenericTypeSyntax;

    var TypeQuerySyntax = (function (_super) {
        __extends(TypeQuerySyntax, _super);
        function TypeQuerySyntax(typeOfKeyword, name, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.typeOfKeyword = typeOfKeyword;
            this.name = name;
        }
        TypeQuerySyntax.prototype.accept = function (visitor) {
            return visitor.visitTypeQuery(this);
        };

        TypeQuerySyntax.prototype.kind = function () {
            return 127 /* TypeQuery */;
        };

        TypeQuerySyntax.prototype.childCount = function () {
            return 2;
        };

        TypeQuerySyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.typeOfKeyword;
                case 1:
                    return this.name;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TypeQuerySyntax.prototype.isType = function () {
            return true;
        };

        TypeQuerySyntax.prototype.update = function (typeOfKeyword, name) {
            if (this.typeOfKeyword === typeOfKeyword && this.name === name) {
                return this;
            }

            return new TypeQuerySyntax(typeOfKeyword, name, this.parsedInStrictMode());
        };

        TypeQuerySyntax.create1 = function (name) {
            return new TypeQuerySyntax(TypeScript.Syntax.token(39 /* TypeOfKeyword */), name, false);
        };

        TypeQuerySyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TypeQuerySyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TypeQuerySyntax.prototype.withTypeOfKeyword = function (typeOfKeyword) {
            return this.update(typeOfKeyword, this.name);
        };

        TypeQuerySyntax.prototype.withName = function (name) {
            return this.update(this.typeOfKeyword, name);
        };

        TypeQuerySyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return TypeQuerySyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TypeQuerySyntax = TypeQuerySyntax;

    var TypeAnnotationSyntax = (function (_super) {
        __extends(TypeAnnotationSyntax, _super);
        function TypeAnnotationSyntax(colonToken, type, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.colonToken = colonToken;
            this.type = type;
        }
        TypeAnnotationSyntax.prototype.accept = function (visitor) {
            return visitor.visitTypeAnnotation(this);
        };

        TypeAnnotationSyntax.prototype.kind = function () {
            return 244 /* TypeAnnotation */;
        };

        TypeAnnotationSyntax.prototype.childCount = function () {
            return 2;
        };

        TypeAnnotationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.colonToken;
                case 1:
                    return this.type;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TypeAnnotationSyntax.prototype.update = function (colonToken, type) {
            if (this.colonToken === colonToken && this.type === type) {
                return this;
            }

            return new TypeAnnotationSyntax(colonToken, type, this.parsedInStrictMode());
        };

        TypeAnnotationSyntax.create1 = function (type) {
            return new TypeAnnotationSyntax(TypeScript.Syntax.token(106 /* ColonToken */), type, false);
        };

        TypeAnnotationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TypeAnnotationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TypeAnnotationSyntax.prototype.withColonToken = function (colonToken) {
            return this.update(colonToken, this.type);
        };

        TypeAnnotationSyntax.prototype.withType = function (type) {
            return this.update(this.colonToken, type);
        };

        TypeAnnotationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return TypeAnnotationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TypeAnnotationSyntax = TypeAnnotationSyntax;

    var BlockSyntax = (function (_super) {
        __extends(BlockSyntax, _super);
        function BlockSyntax(openBraceToken, statements, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openBraceToken = openBraceToken;
            this.statements = statements;
            this.closeBraceToken = closeBraceToken;
        }
        BlockSyntax.prototype.accept = function (visitor) {
            return visitor.visitBlock(this);
        };

        BlockSyntax.prototype.kind = function () {
            return 146 /* Block */;
        };

        BlockSyntax.prototype.childCount = function () {
            return 3;
        };

        BlockSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openBraceToken;
                case 1:
                    return this.statements;
                case 2:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        BlockSyntax.prototype.isStatement = function () {
            return true;
        };

        BlockSyntax.prototype.isModuleElement = function () {
            return true;
        };

        BlockSyntax.prototype.update = function (openBraceToken, statements, closeBraceToken) {
            if (this.openBraceToken === openBraceToken && this.statements === statements && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new BlockSyntax(openBraceToken, statements, closeBraceToken, this.parsedInStrictMode());
        };

        BlockSyntax.create = function (openBraceToken, closeBraceToken) {
            return new BlockSyntax(openBraceToken, TypeScript.Syntax.emptyList, closeBraceToken, false);
        };

        BlockSyntax.create1 = function () {
            return new BlockSyntax(TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptyList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        BlockSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        BlockSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        BlockSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(openBraceToken, this.statements, this.closeBraceToken);
        };

        BlockSyntax.prototype.withStatements = function (statements) {
            return this.update(this.openBraceToken, statements, this.closeBraceToken);
        };

        BlockSyntax.prototype.withStatement = function (statement) {
            return this.withStatements(TypeScript.Syntax.list([statement]));
        };

        BlockSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.openBraceToken, this.statements, closeBraceToken);
        };

        BlockSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.statements.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return BlockSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.BlockSyntax = BlockSyntax;

    var ParameterSyntax = (function (_super) {
        __extends(ParameterSyntax, _super);
        function ParameterSyntax(dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.dotDotDotToken = dotDotDotToken;
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.questionToken = questionToken;
            this.typeAnnotation = typeAnnotation;
            this.equalsValueClause = equalsValueClause;
        }
        ParameterSyntax.prototype.accept = function (visitor) {
            return visitor.visitParameter(this);
        };

        ParameterSyntax.prototype.kind = function () {
            return 242 /* Parameter */;
        };

        ParameterSyntax.prototype.childCount = function () {
            return 6;
        };

        ParameterSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.dotDotDotToken;
                case 1:
                    return this.modifiers;
                case 2:
                    return this.identifier;
                case 3:
                    return this.questionToken;
                case 4:
                    return this.typeAnnotation;
                case 5:
                    return this.equalsValueClause;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ParameterSyntax.prototype.update = function (dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause) {
            if (this.dotDotDotToken === dotDotDotToken && this.modifiers === modifiers && this.identifier === identifier && this.questionToken === questionToken && this.typeAnnotation === typeAnnotation && this.equalsValueClause === equalsValueClause) {
                return this;
            }

            return new ParameterSyntax(dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause, this.parsedInStrictMode());
        };

        ParameterSyntax.create = function (identifier) {
            return new ParameterSyntax(null, TypeScript.Syntax.emptyList, identifier, null, null, null, false);
        };

        ParameterSyntax.create1 = function (identifier) {
            return new ParameterSyntax(null, TypeScript.Syntax.emptyList, identifier, null, null, null, false);
        };

        ParameterSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ParameterSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ParameterSyntax.prototype.withDotDotDotToken = function (dotDotDotToken) {
            return this.update(dotDotDotToken, this.modifiers, this.identifier, this.questionToken, this.typeAnnotation, this.equalsValueClause);
        };

        ParameterSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(this.dotDotDotToken, modifiers, this.identifier, this.questionToken, this.typeAnnotation, this.equalsValueClause);
        };

        ParameterSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        ParameterSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.dotDotDotToken, this.modifiers, identifier, this.questionToken, this.typeAnnotation, this.equalsValueClause);
        };

        ParameterSyntax.prototype.withQuestionToken = function (questionToken) {
            return this.update(this.dotDotDotToken, this.modifiers, this.identifier, questionToken, this.typeAnnotation, this.equalsValueClause);
        };

        ParameterSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.dotDotDotToken, this.modifiers, this.identifier, this.questionToken, typeAnnotation, this.equalsValueClause);
        };

        ParameterSyntax.prototype.withEqualsValueClause = function (equalsValueClause) {
            return this.update(this.dotDotDotToken, this.modifiers, this.identifier, this.questionToken, this.typeAnnotation, equalsValueClause);
        };

        ParameterSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.dotDotDotToken !== null) {
                return true;
            }
            if (this.modifiers.isTypeScriptSpecific()) {
                return true;
            }
            if (this.questionToken !== null) {
                return true;
            }
            if (this.typeAnnotation !== null) {
                return true;
            }
            if (this.equalsValueClause !== null) {
                return true;
            }
            return false;
        };
        return ParameterSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ParameterSyntax = ParameterSyntax;

    var MemberAccessExpressionSyntax = (function (_super) {
        __extends(MemberAccessExpressionSyntax, _super);
        function MemberAccessExpressionSyntax(expression, dotToken, name, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.expression = expression;
            this.dotToken = dotToken;
            this.name = name;
        }
        MemberAccessExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitMemberAccessExpression(this);
        };

        MemberAccessExpressionSyntax.prototype.kind = function () {
            return 212 /* MemberAccessExpression */;
        };

        MemberAccessExpressionSyntax.prototype.childCount = function () {
            return 3;
        };

        MemberAccessExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.expression;
                case 1:
                    return this.dotToken;
                case 2:
                    return this.name;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        MemberAccessExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        MemberAccessExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        MemberAccessExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        MemberAccessExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        MemberAccessExpressionSyntax.prototype.update = function (expression, dotToken, name) {
            if (this.expression === expression && this.dotToken === dotToken && this.name === name) {
                return this;
            }

            return new MemberAccessExpressionSyntax(expression, dotToken, name, this.parsedInStrictMode());
        };

        MemberAccessExpressionSyntax.create1 = function (expression, name) {
            return new MemberAccessExpressionSyntax(expression, TypeScript.Syntax.token(76 /* DotToken */), name, false);
        };

        MemberAccessExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        MemberAccessExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        MemberAccessExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(expression, this.dotToken, this.name);
        };

        MemberAccessExpressionSyntax.prototype.withDotToken = function (dotToken) {
            return this.update(this.expression, dotToken, this.name);
        };

        MemberAccessExpressionSyntax.prototype.withName = function (name) {
            return this.update(this.expression, this.dotToken, name);
        };

        MemberAccessExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return MemberAccessExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.MemberAccessExpressionSyntax = MemberAccessExpressionSyntax;

    var PostfixUnaryExpressionSyntax = (function (_super) {
        __extends(PostfixUnaryExpressionSyntax, _super);
        function PostfixUnaryExpressionSyntax(kind, operand, operatorToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.operand = operand;
            this.operatorToken = operatorToken;

            this._kind = kind;
        }
        PostfixUnaryExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitPostfixUnaryExpression(this);
        };

        PostfixUnaryExpressionSyntax.prototype.childCount = function () {
            return 2;
        };

        PostfixUnaryExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.operand;
                case 1:
                    return this.operatorToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        PostfixUnaryExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        PostfixUnaryExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        PostfixUnaryExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        PostfixUnaryExpressionSyntax.prototype.kind = function () {
            return this._kind;
        };

        PostfixUnaryExpressionSyntax.prototype.update = function (kind, operand, operatorToken) {
            if (this._kind === kind && this.operand === operand && this.operatorToken === operatorToken) {
                return this;
            }

            return new PostfixUnaryExpressionSyntax(kind, operand, operatorToken, this.parsedInStrictMode());
        };

        PostfixUnaryExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        PostfixUnaryExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        PostfixUnaryExpressionSyntax.prototype.withKind = function (kind) {
            return this.update(kind, this.operand, this.operatorToken);
        };

        PostfixUnaryExpressionSyntax.prototype.withOperand = function (operand) {
            return this.update(this._kind, operand, this.operatorToken);
        };

        PostfixUnaryExpressionSyntax.prototype.withOperatorToken = function (operatorToken) {
            return this.update(this._kind, this.operand, operatorToken);
        };

        PostfixUnaryExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.operand.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return PostfixUnaryExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.PostfixUnaryExpressionSyntax = PostfixUnaryExpressionSyntax;

    var ElementAccessExpressionSyntax = (function (_super) {
        __extends(ElementAccessExpressionSyntax, _super);
        function ElementAccessExpressionSyntax(expression, openBracketToken, argumentExpression, closeBracketToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.expression = expression;
            this.openBracketToken = openBracketToken;
            this.argumentExpression = argumentExpression;
            this.closeBracketToken = closeBracketToken;
        }
        ElementAccessExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitElementAccessExpression(this);
        };

        ElementAccessExpressionSyntax.prototype.kind = function () {
            return 221 /* ElementAccessExpression */;
        };

        ElementAccessExpressionSyntax.prototype.childCount = function () {
            return 4;
        };

        ElementAccessExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.expression;
                case 1:
                    return this.openBracketToken;
                case 2:
                    return this.argumentExpression;
                case 3:
                    return this.closeBracketToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ElementAccessExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        ElementAccessExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        ElementAccessExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        ElementAccessExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ElementAccessExpressionSyntax.prototype.update = function (expression, openBracketToken, argumentExpression, closeBracketToken) {
            if (this.expression === expression && this.openBracketToken === openBracketToken && this.argumentExpression === argumentExpression && this.closeBracketToken === closeBracketToken) {
                return this;
            }

            return new ElementAccessExpressionSyntax(expression, openBracketToken, argumentExpression, closeBracketToken, this.parsedInStrictMode());
        };

        ElementAccessExpressionSyntax.create1 = function (expression, argumentExpression) {
            return new ElementAccessExpressionSyntax(expression, TypeScript.Syntax.token(74 /* OpenBracketToken */), argumentExpression, TypeScript.Syntax.token(75 /* CloseBracketToken */), false);
        };

        ElementAccessExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ElementAccessExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ElementAccessExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(expression, this.openBracketToken, this.argumentExpression, this.closeBracketToken);
        };

        ElementAccessExpressionSyntax.prototype.withOpenBracketToken = function (openBracketToken) {
            return this.update(this.expression, openBracketToken, this.argumentExpression, this.closeBracketToken);
        };

        ElementAccessExpressionSyntax.prototype.withArgumentExpression = function (argumentExpression) {
            return this.update(this.expression, this.openBracketToken, argumentExpression, this.closeBracketToken);
        };

        ElementAccessExpressionSyntax.prototype.withCloseBracketToken = function (closeBracketToken) {
            return this.update(this.expression, this.openBracketToken, this.argumentExpression, closeBracketToken);
        };

        ElementAccessExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            if (this.argumentExpression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ElementAccessExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ElementAccessExpressionSyntax = ElementAccessExpressionSyntax;

    var InvocationExpressionSyntax = (function (_super) {
        __extends(InvocationExpressionSyntax, _super);
        function InvocationExpressionSyntax(expression, argumentList, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.expression = expression;
            this.argumentList = argumentList;
        }
        InvocationExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitInvocationExpression(this);
        };

        InvocationExpressionSyntax.prototype.kind = function () {
            return 213 /* InvocationExpression */;
        };

        InvocationExpressionSyntax.prototype.childCount = function () {
            return 2;
        };

        InvocationExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.expression;
                case 1:
                    return this.argumentList;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        InvocationExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        InvocationExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        InvocationExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        InvocationExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        InvocationExpressionSyntax.prototype.update = function (expression, argumentList) {
            if (this.expression === expression && this.argumentList === argumentList) {
                return this;
            }

            return new InvocationExpressionSyntax(expression, argumentList, this.parsedInStrictMode());
        };

        InvocationExpressionSyntax.create1 = function (expression) {
            return new InvocationExpressionSyntax(expression, ArgumentListSyntax.create1(), false);
        };

        InvocationExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        InvocationExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        InvocationExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(expression, this.argumentList);
        };

        InvocationExpressionSyntax.prototype.withArgumentList = function (argumentList) {
            return this.update(this.expression, argumentList);
        };

        InvocationExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            if (this.argumentList.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return InvocationExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.InvocationExpressionSyntax = InvocationExpressionSyntax;

    var ArgumentListSyntax = (function (_super) {
        __extends(ArgumentListSyntax, _super);
        function ArgumentListSyntax(typeArgumentList, openParenToken, _arguments, closeParenToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.typeArgumentList = typeArgumentList;
            this.openParenToken = openParenToken;
            this.closeParenToken = closeParenToken;

            this.arguments = _arguments;
        }
        ArgumentListSyntax.prototype.accept = function (visitor) {
            return visitor.visitArgumentList(this);
        };

        ArgumentListSyntax.prototype.kind = function () {
            return 226 /* ArgumentList */;
        };

        ArgumentListSyntax.prototype.childCount = function () {
            return 4;
        };

        ArgumentListSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.typeArgumentList;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.arguments;
                case 3:
                    return this.closeParenToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ArgumentListSyntax.prototype.update = function (typeArgumentList, openParenToken, _arguments, closeParenToken) {
            if (this.typeArgumentList === typeArgumentList && this.openParenToken === openParenToken && this.arguments === _arguments && this.closeParenToken === closeParenToken) {
                return this;
            }

            return new ArgumentListSyntax(typeArgumentList, openParenToken, _arguments, closeParenToken, this.parsedInStrictMode());
        };

        ArgumentListSyntax.create = function (openParenToken, closeParenToken) {
            return new ArgumentListSyntax(null, openParenToken, TypeScript.Syntax.emptySeparatedList, closeParenToken, false);
        };

        ArgumentListSyntax.create1 = function () {
            return new ArgumentListSyntax(null, TypeScript.Syntax.token(72 /* OpenParenToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(73 /* CloseParenToken */), false);
        };

        ArgumentListSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ArgumentListSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ArgumentListSyntax.prototype.withTypeArgumentList = function (typeArgumentList) {
            return this.update(typeArgumentList, this.openParenToken, this.arguments, this.closeParenToken);
        };

        ArgumentListSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.typeArgumentList, openParenToken, this.arguments, this.closeParenToken);
        };

        ArgumentListSyntax.prototype.withArguments = function (_arguments) {
            return this.update(this.typeArgumentList, this.openParenToken, _arguments, this.closeParenToken);
        };

        ArgumentListSyntax.prototype.withArgument = function (_argument) {
            return this.withArguments(TypeScript.Syntax.separatedList([_argument]));
        };

        ArgumentListSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.typeArgumentList, this.openParenToken, this.arguments, closeParenToken);
        };

        ArgumentListSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.typeArgumentList !== null && this.typeArgumentList.isTypeScriptSpecific()) {
                return true;
            }
            if (this.arguments.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ArgumentListSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ArgumentListSyntax = ArgumentListSyntax;

    var BinaryExpressionSyntax = (function (_super) {
        __extends(BinaryExpressionSyntax, _super);
        function BinaryExpressionSyntax(kind, left, operatorToken, right, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.left = left;
            this.operatorToken = operatorToken;
            this.right = right;

            this._kind = kind;
        }
        BinaryExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitBinaryExpression(this);
        };

        BinaryExpressionSyntax.prototype.childCount = function () {
            return 3;
        };

        BinaryExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.left;
                case 1:
                    return this.operatorToken;
                case 2:
                    return this.right;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        BinaryExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        BinaryExpressionSyntax.prototype.kind = function () {
            return this._kind;
        };

        BinaryExpressionSyntax.prototype.update = function (kind, left, operatorToken, right) {
            if (this._kind === kind && this.left === left && this.operatorToken === operatorToken && this.right === right) {
                return this;
            }

            return new BinaryExpressionSyntax(kind, left, operatorToken, right, this.parsedInStrictMode());
        };

        BinaryExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        BinaryExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        BinaryExpressionSyntax.prototype.withKind = function (kind) {
            return this.update(kind, this.left, this.operatorToken, this.right);
        };

        BinaryExpressionSyntax.prototype.withLeft = function (left) {
            return this.update(this._kind, left, this.operatorToken, this.right);
        };

        BinaryExpressionSyntax.prototype.withOperatorToken = function (operatorToken) {
            return this.update(this._kind, this.left, operatorToken, this.right);
        };

        BinaryExpressionSyntax.prototype.withRight = function (right) {
            return this.update(this._kind, this.left, this.operatorToken, right);
        };

        BinaryExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.left.isTypeScriptSpecific()) {
                return true;
            }
            if (this.right.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return BinaryExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.BinaryExpressionSyntax = BinaryExpressionSyntax;

    var ConditionalExpressionSyntax = (function (_super) {
        __extends(ConditionalExpressionSyntax, _super);
        function ConditionalExpressionSyntax(condition, questionToken, whenTrue, colonToken, whenFalse, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.condition = condition;
            this.questionToken = questionToken;
            this.whenTrue = whenTrue;
            this.colonToken = colonToken;
            this.whenFalse = whenFalse;
        }
        ConditionalExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitConditionalExpression(this);
        };

        ConditionalExpressionSyntax.prototype.kind = function () {
            return 186 /* ConditionalExpression */;
        };

        ConditionalExpressionSyntax.prototype.childCount = function () {
            return 5;
        };

        ConditionalExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.condition;
                case 1:
                    return this.questionToken;
                case 2:
                    return this.whenTrue;
                case 3:
                    return this.colonToken;
                case 4:
                    return this.whenFalse;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ConditionalExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ConditionalExpressionSyntax.prototype.update = function (condition, questionToken, whenTrue, colonToken, whenFalse) {
            if (this.condition === condition && this.questionToken === questionToken && this.whenTrue === whenTrue && this.colonToken === colonToken && this.whenFalse === whenFalse) {
                return this;
            }

            return new ConditionalExpressionSyntax(condition, questionToken, whenTrue, colonToken, whenFalse, this.parsedInStrictMode());
        };

        ConditionalExpressionSyntax.create1 = function (condition, whenTrue, whenFalse) {
            return new ConditionalExpressionSyntax(condition, TypeScript.Syntax.token(105 /* QuestionToken */), whenTrue, TypeScript.Syntax.token(106 /* ColonToken */), whenFalse, false);
        };

        ConditionalExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ConditionalExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ConditionalExpressionSyntax.prototype.withCondition = function (condition) {
            return this.update(condition, this.questionToken, this.whenTrue, this.colonToken, this.whenFalse);
        };

        ConditionalExpressionSyntax.prototype.withQuestionToken = function (questionToken) {
            return this.update(this.condition, questionToken, this.whenTrue, this.colonToken, this.whenFalse);
        };

        ConditionalExpressionSyntax.prototype.withWhenTrue = function (whenTrue) {
            return this.update(this.condition, this.questionToken, whenTrue, this.colonToken, this.whenFalse);
        };

        ConditionalExpressionSyntax.prototype.withColonToken = function (colonToken) {
            return this.update(this.condition, this.questionToken, this.whenTrue, colonToken, this.whenFalse);
        };

        ConditionalExpressionSyntax.prototype.withWhenFalse = function (whenFalse) {
            return this.update(this.condition, this.questionToken, this.whenTrue, this.colonToken, whenFalse);
        };

        ConditionalExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.condition.isTypeScriptSpecific()) {
                return true;
            }
            if (this.whenTrue.isTypeScriptSpecific()) {
                return true;
            }
            if (this.whenFalse.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ConditionalExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ConditionalExpressionSyntax = ConditionalExpressionSyntax;

    var ConstructSignatureSyntax = (function (_super) {
        __extends(ConstructSignatureSyntax, _super);
        function ConstructSignatureSyntax(newKeyword, callSignature, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.newKeyword = newKeyword;
            this.callSignature = callSignature;
        }
        ConstructSignatureSyntax.prototype.accept = function (visitor) {
            return visitor.visitConstructSignature(this);
        };

        ConstructSignatureSyntax.prototype.kind = function () {
            return 143 /* ConstructSignature */;
        };

        ConstructSignatureSyntax.prototype.childCount = function () {
            return 2;
        };

        ConstructSignatureSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.newKeyword;
                case 1:
                    return this.callSignature;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ConstructSignatureSyntax.prototype.isTypeMember = function () {
            return true;
        };

        ConstructSignatureSyntax.prototype.update = function (newKeyword, callSignature) {
            if (this.newKeyword === newKeyword && this.callSignature === callSignature) {
                return this;
            }

            return new ConstructSignatureSyntax(newKeyword, callSignature, this.parsedInStrictMode());
        };

        ConstructSignatureSyntax.create1 = function () {
            return new ConstructSignatureSyntax(TypeScript.Syntax.token(31 /* NewKeyword */), CallSignatureSyntax.create1(), false);
        };

        ConstructSignatureSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ConstructSignatureSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ConstructSignatureSyntax.prototype.withNewKeyword = function (newKeyword) {
            return this.update(newKeyword, this.callSignature);
        };

        ConstructSignatureSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.newKeyword, callSignature);
        };

        ConstructSignatureSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ConstructSignatureSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ConstructSignatureSyntax = ConstructSignatureSyntax;

    var MethodSignatureSyntax = (function (_super) {
        __extends(MethodSignatureSyntax, _super);
        function MethodSignatureSyntax(propertyName, questionToken, callSignature, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.propertyName = propertyName;
            this.questionToken = questionToken;
            this.callSignature = callSignature;
        }
        MethodSignatureSyntax.prototype.accept = function (visitor) {
            return visitor.visitMethodSignature(this);
        };

        MethodSignatureSyntax.prototype.kind = function () {
            return 145 /* MethodSignature */;
        };

        MethodSignatureSyntax.prototype.childCount = function () {
            return 3;
        };

        MethodSignatureSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.propertyName;
                case 1:
                    return this.questionToken;
                case 2:
                    return this.callSignature;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        MethodSignatureSyntax.prototype.isTypeMember = function () {
            return true;
        };

        MethodSignatureSyntax.prototype.update = function (propertyName, questionToken, callSignature) {
            if (this.propertyName === propertyName && this.questionToken === questionToken && this.callSignature === callSignature) {
                return this;
            }

            return new MethodSignatureSyntax(propertyName, questionToken, callSignature, this.parsedInStrictMode());
        };

        MethodSignatureSyntax.create = function (propertyName, callSignature) {
            return new MethodSignatureSyntax(propertyName, null, callSignature, false);
        };

        MethodSignatureSyntax.create1 = function (propertyName) {
            return new MethodSignatureSyntax(propertyName, null, CallSignatureSyntax.create1(), false);
        };

        MethodSignatureSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        MethodSignatureSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        MethodSignatureSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(propertyName, this.questionToken, this.callSignature);
        };

        MethodSignatureSyntax.prototype.withQuestionToken = function (questionToken) {
            return this.update(this.propertyName, questionToken, this.callSignature);
        };

        MethodSignatureSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.propertyName, this.questionToken, callSignature);
        };

        MethodSignatureSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.callSignature.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return MethodSignatureSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.MethodSignatureSyntax = MethodSignatureSyntax;

    var IndexSignatureSyntax = (function (_super) {
        __extends(IndexSignatureSyntax, _super);
        function IndexSignatureSyntax(openBracketToken, parameter, closeBracketToken, typeAnnotation, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openBracketToken = openBracketToken;
            this.parameter = parameter;
            this.closeBracketToken = closeBracketToken;
            this.typeAnnotation = typeAnnotation;
        }
        IndexSignatureSyntax.prototype.accept = function (visitor) {
            return visitor.visitIndexSignature(this);
        };

        IndexSignatureSyntax.prototype.kind = function () {
            return 144 /* IndexSignature */;
        };

        IndexSignatureSyntax.prototype.childCount = function () {
            return 4;
        };

        IndexSignatureSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openBracketToken;
                case 1:
                    return this.parameter;
                case 2:
                    return this.closeBracketToken;
                case 3:
                    return this.typeAnnotation;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        IndexSignatureSyntax.prototype.isTypeMember = function () {
            return true;
        };

        IndexSignatureSyntax.prototype.update = function (openBracketToken, parameter, closeBracketToken, typeAnnotation) {
            if (this.openBracketToken === openBracketToken && this.parameter === parameter && this.closeBracketToken === closeBracketToken && this.typeAnnotation === typeAnnotation) {
                return this;
            }

            return new IndexSignatureSyntax(openBracketToken, parameter, closeBracketToken, typeAnnotation, this.parsedInStrictMode());
        };

        IndexSignatureSyntax.create = function (openBracketToken, parameter, closeBracketToken) {
            return new IndexSignatureSyntax(openBracketToken, parameter, closeBracketToken, null, false);
        };

        IndexSignatureSyntax.create1 = function (parameter) {
            return new IndexSignatureSyntax(TypeScript.Syntax.token(74 /* OpenBracketToken */), parameter, TypeScript.Syntax.token(75 /* CloseBracketToken */), null, false);
        };

        IndexSignatureSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        IndexSignatureSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        IndexSignatureSyntax.prototype.withOpenBracketToken = function (openBracketToken) {
            return this.update(openBracketToken, this.parameter, this.closeBracketToken, this.typeAnnotation);
        };

        IndexSignatureSyntax.prototype.withParameter = function (parameter) {
            return this.update(this.openBracketToken, parameter, this.closeBracketToken, this.typeAnnotation);
        };

        IndexSignatureSyntax.prototype.withCloseBracketToken = function (closeBracketToken) {
            return this.update(this.openBracketToken, this.parameter, closeBracketToken, this.typeAnnotation);
        };

        IndexSignatureSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.openBracketToken, this.parameter, this.closeBracketToken, typeAnnotation);
        };

        IndexSignatureSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return IndexSignatureSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.IndexSignatureSyntax = IndexSignatureSyntax;

    var PropertySignatureSyntax = (function (_super) {
        __extends(PropertySignatureSyntax, _super);
        function PropertySignatureSyntax(propertyName, questionToken, typeAnnotation, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.propertyName = propertyName;
            this.questionToken = questionToken;
            this.typeAnnotation = typeAnnotation;
        }
        PropertySignatureSyntax.prototype.accept = function (visitor) {
            return visitor.visitPropertySignature(this);
        };

        PropertySignatureSyntax.prototype.kind = function () {
            return 141 /* PropertySignature */;
        };

        PropertySignatureSyntax.prototype.childCount = function () {
            return 3;
        };

        PropertySignatureSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.propertyName;
                case 1:
                    return this.questionToken;
                case 2:
                    return this.typeAnnotation;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        PropertySignatureSyntax.prototype.isTypeMember = function () {
            return true;
        };

        PropertySignatureSyntax.prototype.update = function (propertyName, questionToken, typeAnnotation) {
            if (this.propertyName === propertyName && this.questionToken === questionToken && this.typeAnnotation === typeAnnotation) {
                return this;
            }

            return new PropertySignatureSyntax(propertyName, questionToken, typeAnnotation, this.parsedInStrictMode());
        };

        PropertySignatureSyntax.create = function (propertyName) {
            return new PropertySignatureSyntax(propertyName, null, null, false);
        };

        PropertySignatureSyntax.create1 = function (propertyName) {
            return new PropertySignatureSyntax(propertyName, null, null, false);
        };

        PropertySignatureSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        PropertySignatureSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        PropertySignatureSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(propertyName, this.questionToken, this.typeAnnotation);
        };

        PropertySignatureSyntax.prototype.withQuestionToken = function (questionToken) {
            return this.update(this.propertyName, questionToken, this.typeAnnotation);
        };

        PropertySignatureSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.propertyName, this.questionToken, typeAnnotation);
        };

        PropertySignatureSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return PropertySignatureSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.PropertySignatureSyntax = PropertySignatureSyntax;

    var CallSignatureSyntax = (function (_super) {
        __extends(CallSignatureSyntax, _super);
        function CallSignatureSyntax(typeParameterList, parameterList, typeAnnotation, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.typeParameterList = typeParameterList;
            this.parameterList = parameterList;
            this.typeAnnotation = typeAnnotation;
        }
        CallSignatureSyntax.prototype.accept = function (visitor) {
            return visitor.visitCallSignature(this);
        };

        CallSignatureSyntax.prototype.kind = function () {
            return 142 /* CallSignature */;
        };

        CallSignatureSyntax.prototype.childCount = function () {
            return 3;
        };

        CallSignatureSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.typeParameterList;
                case 1:
                    return this.parameterList;
                case 2:
                    return this.typeAnnotation;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        CallSignatureSyntax.prototype.isTypeMember = function () {
            return true;
        };

        CallSignatureSyntax.prototype.update = function (typeParameterList, parameterList, typeAnnotation) {
            if (this.typeParameterList === typeParameterList && this.parameterList === parameterList && this.typeAnnotation === typeAnnotation) {
                return this;
            }

            return new CallSignatureSyntax(typeParameterList, parameterList, typeAnnotation, this.parsedInStrictMode());
        };

        CallSignatureSyntax.create = function (parameterList) {
            return new CallSignatureSyntax(null, parameterList, null, false);
        };

        CallSignatureSyntax.create1 = function () {
            return new CallSignatureSyntax(null, ParameterListSyntax.create1(), null, false);
        };

        CallSignatureSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        CallSignatureSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        CallSignatureSyntax.prototype.withTypeParameterList = function (typeParameterList) {
            return this.update(typeParameterList, this.parameterList, this.typeAnnotation);
        };

        CallSignatureSyntax.prototype.withParameterList = function (parameterList) {
            return this.update(this.typeParameterList, parameterList, this.typeAnnotation);
        };

        CallSignatureSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.typeParameterList, this.parameterList, typeAnnotation);
        };

        CallSignatureSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.typeParameterList !== null) {
                return true;
            }
            if (this.parameterList.isTypeScriptSpecific()) {
                return true;
            }
            if (this.typeAnnotation !== null) {
                return true;
            }
            return false;
        };
        return CallSignatureSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.CallSignatureSyntax = CallSignatureSyntax;

    var ParameterListSyntax = (function (_super) {
        __extends(ParameterListSyntax, _super);
        function ParameterListSyntax(openParenToken, parameters, closeParenToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openParenToken = openParenToken;
            this.parameters = parameters;
            this.closeParenToken = closeParenToken;
        }
        ParameterListSyntax.prototype.accept = function (visitor) {
            return visitor.visitParameterList(this);
        };

        ParameterListSyntax.prototype.kind = function () {
            return 227 /* ParameterList */;
        };

        ParameterListSyntax.prototype.childCount = function () {
            return 3;
        };

        ParameterListSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openParenToken;
                case 1:
                    return this.parameters;
                case 2:
                    return this.closeParenToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ParameterListSyntax.prototype.update = function (openParenToken, parameters, closeParenToken) {
            if (this.openParenToken === openParenToken && this.parameters === parameters && this.closeParenToken === closeParenToken) {
                return this;
            }

            return new ParameterListSyntax(openParenToken, parameters, closeParenToken, this.parsedInStrictMode());
        };

        ParameterListSyntax.create = function (openParenToken, closeParenToken) {
            return new ParameterListSyntax(openParenToken, TypeScript.Syntax.emptySeparatedList, closeParenToken, false);
        };

        ParameterListSyntax.create1 = function () {
            return new ParameterListSyntax(TypeScript.Syntax.token(72 /* OpenParenToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(73 /* CloseParenToken */), false);
        };

        ParameterListSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ParameterListSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ParameterListSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(openParenToken, this.parameters, this.closeParenToken);
        };

        ParameterListSyntax.prototype.withParameters = function (parameters) {
            return this.update(this.openParenToken, parameters, this.closeParenToken);
        };

        ParameterListSyntax.prototype.withParameter = function (parameter) {
            return this.withParameters(TypeScript.Syntax.separatedList([parameter]));
        };

        ParameterListSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.openParenToken, this.parameters, closeParenToken);
        };

        ParameterListSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.parameters.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ParameterListSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ParameterListSyntax = ParameterListSyntax;

    var TypeParameterListSyntax = (function (_super) {
        __extends(TypeParameterListSyntax, _super);
        function TypeParameterListSyntax(lessThanToken, typeParameters, greaterThanToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.lessThanToken = lessThanToken;
            this.typeParameters = typeParameters;
            this.greaterThanToken = greaterThanToken;
        }
        TypeParameterListSyntax.prototype.accept = function (visitor) {
            return visitor.visitTypeParameterList(this);
        };

        TypeParameterListSyntax.prototype.kind = function () {
            return 229 /* TypeParameterList */;
        };

        TypeParameterListSyntax.prototype.childCount = function () {
            return 3;
        };

        TypeParameterListSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.lessThanToken;
                case 1:
                    return this.typeParameters;
                case 2:
                    return this.greaterThanToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TypeParameterListSyntax.prototype.update = function (lessThanToken, typeParameters, greaterThanToken) {
            if (this.lessThanToken === lessThanToken && this.typeParameters === typeParameters && this.greaterThanToken === greaterThanToken) {
                return this;
            }

            return new TypeParameterListSyntax(lessThanToken, typeParameters, greaterThanToken, this.parsedInStrictMode());
        };

        TypeParameterListSyntax.create = function (lessThanToken, greaterThanToken) {
            return new TypeParameterListSyntax(lessThanToken, TypeScript.Syntax.emptySeparatedList, greaterThanToken, false);
        };

        TypeParameterListSyntax.create1 = function () {
            return new TypeParameterListSyntax(TypeScript.Syntax.token(80 /* LessThanToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(81 /* GreaterThanToken */), false);
        };

        TypeParameterListSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TypeParameterListSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TypeParameterListSyntax.prototype.withLessThanToken = function (lessThanToken) {
            return this.update(lessThanToken, this.typeParameters, this.greaterThanToken);
        };

        TypeParameterListSyntax.prototype.withTypeParameters = function (typeParameters) {
            return this.update(this.lessThanToken, typeParameters, this.greaterThanToken);
        };

        TypeParameterListSyntax.prototype.withTypeParameter = function (typeParameter) {
            return this.withTypeParameters(TypeScript.Syntax.separatedList([typeParameter]));
        };

        TypeParameterListSyntax.prototype.withGreaterThanToken = function (greaterThanToken) {
            return this.update(this.lessThanToken, this.typeParameters, greaterThanToken);
        };

        TypeParameterListSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return TypeParameterListSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TypeParameterListSyntax = TypeParameterListSyntax;

    var TypeParameterSyntax = (function (_super) {
        __extends(TypeParameterSyntax, _super);
        function TypeParameterSyntax(identifier, constraint, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.identifier = identifier;
            this.constraint = constraint;
        }
        TypeParameterSyntax.prototype.accept = function (visitor) {
            return visitor.visitTypeParameter(this);
        };

        TypeParameterSyntax.prototype.kind = function () {
            return 238 /* TypeParameter */;
        };

        TypeParameterSyntax.prototype.childCount = function () {
            return 2;
        };

        TypeParameterSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.identifier;
                case 1:
                    return this.constraint;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TypeParameterSyntax.prototype.update = function (identifier, constraint) {
            if (this.identifier === identifier && this.constraint === constraint) {
                return this;
            }

            return new TypeParameterSyntax(identifier, constraint, this.parsedInStrictMode());
        };

        TypeParameterSyntax.create = function (identifier) {
            return new TypeParameterSyntax(identifier, null, false);
        };

        TypeParameterSyntax.create1 = function (identifier) {
            return new TypeParameterSyntax(identifier, null, false);
        };

        TypeParameterSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TypeParameterSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TypeParameterSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(identifier, this.constraint);
        };

        TypeParameterSyntax.prototype.withConstraint = function (constraint) {
            return this.update(this.identifier, constraint);
        };

        TypeParameterSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return TypeParameterSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TypeParameterSyntax = TypeParameterSyntax;

    var ConstraintSyntax = (function (_super) {
        __extends(ConstraintSyntax, _super);
        function ConstraintSyntax(extendsKeyword, type, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.extendsKeyword = extendsKeyword;
            this.type = type;
        }
        ConstraintSyntax.prototype.accept = function (visitor) {
            return visitor.visitConstraint(this);
        };

        ConstraintSyntax.prototype.kind = function () {
            return 239 /* Constraint */;
        };

        ConstraintSyntax.prototype.childCount = function () {
            return 2;
        };

        ConstraintSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.extendsKeyword;
                case 1:
                    return this.type;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ConstraintSyntax.prototype.update = function (extendsKeyword, type) {
            if (this.extendsKeyword === extendsKeyword && this.type === type) {
                return this;
            }

            return new ConstraintSyntax(extendsKeyword, type, this.parsedInStrictMode());
        };

        ConstraintSyntax.create1 = function (type) {
            return new ConstraintSyntax(TypeScript.Syntax.token(48 /* ExtendsKeyword */), type, false);
        };

        ConstraintSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ConstraintSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ConstraintSyntax.prototype.withExtendsKeyword = function (extendsKeyword) {
            return this.update(extendsKeyword, this.type);
        };

        ConstraintSyntax.prototype.withType = function (type) {
            return this.update(this.extendsKeyword, type);
        };

        ConstraintSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ConstraintSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ConstraintSyntax = ConstraintSyntax;

    var ElseClauseSyntax = (function (_super) {
        __extends(ElseClauseSyntax, _super);
        function ElseClauseSyntax(elseKeyword, statement, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.elseKeyword = elseKeyword;
            this.statement = statement;
        }
        ElseClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitElseClause(this);
        };

        ElseClauseSyntax.prototype.kind = function () {
            return 235 /* ElseClause */;
        };

        ElseClauseSyntax.prototype.childCount = function () {
            return 2;
        };

        ElseClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.elseKeyword;
                case 1:
                    return this.statement;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ElseClauseSyntax.prototype.update = function (elseKeyword, statement) {
            if (this.elseKeyword === elseKeyword && this.statement === statement) {
                return this;
            }

            return new ElseClauseSyntax(elseKeyword, statement, this.parsedInStrictMode());
        };

        ElseClauseSyntax.create1 = function (statement) {
            return new ElseClauseSyntax(TypeScript.Syntax.token(23 /* ElseKeyword */), statement, false);
        };

        ElseClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ElseClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ElseClauseSyntax.prototype.withElseKeyword = function (elseKeyword) {
            return this.update(elseKeyword, this.statement);
        };

        ElseClauseSyntax.prototype.withStatement = function (statement) {
            return this.update(this.elseKeyword, statement);
        };

        ElseClauseSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ElseClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ElseClauseSyntax = ElseClauseSyntax;

    var IfStatementSyntax = (function (_super) {
        __extends(IfStatementSyntax, _super);
        function IfStatementSyntax(ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.ifKeyword = ifKeyword;
            this.openParenToken = openParenToken;
            this.condition = condition;
            this.closeParenToken = closeParenToken;
            this.statement = statement;
            this.elseClause = elseClause;
        }
        IfStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitIfStatement(this);
        };

        IfStatementSyntax.prototype.kind = function () {
            return 147 /* IfStatement */;
        };

        IfStatementSyntax.prototype.childCount = function () {
            return 6;
        };

        IfStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.ifKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.condition;
                case 3:
                    return this.closeParenToken;
                case 4:
                    return this.statement;
                case 5:
                    return this.elseClause;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        IfStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        IfStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        IfStatementSyntax.prototype.update = function (ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause) {
            if (this.ifKeyword === ifKeyword && this.openParenToken === openParenToken && this.condition === condition && this.closeParenToken === closeParenToken && this.statement === statement && this.elseClause === elseClause) {
                return this;
            }

            return new IfStatementSyntax(ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause, this.parsedInStrictMode());
        };

        IfStatementSyntax.create = function (ifKeyword, openParenToken, condition, closeParenToken, statement) {
            return new IfStatementSyntax(ifKeyword, openParenToken, condition, closeParenToken, statement, null, false);
        };

        IfStatementSyntax.create1 = function (condition, statement) {
            return new IfStatementSyntax(TypeScript.Syntax.token(28 /* IfKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), condition, TypeScript.Syntax.token(73 /* CloseParenToken */), statement, null, false);
        };

        IfStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        IfStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        IfStatementSyntax.prototype.withIfKeyword = function (ifKeyword) {
            return this.update(ifKeyword, this.openParenToken, this.condition, this.closeParenToken, this.statement, this.elseClause);
        };

        IfStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.ifKeyword, openParenToken, this.condition, this.closeParenToken, this.statement, this.elseClause);
        };

        IfStatementSyntax.prototype.withCondition = function (condition) {
            return this.update(this.ifKeyword, this.openParenToken, condition, this.closeParenToken, this.statement, this.elseClause);
        };

        IfStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.ifKeyword, this.openParenToken, this.condition, closeParenToken, this.statement, this.elseClause);
        };

        IfStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.ifKeyword, this.openParenToken, this.condition, this.closeParenToken, statement, this.elseClause);
        };

        IfStatementSyntax.prototype.withElseClause = function (elseClause) {
            return this.update(this.ifKeyword, this.openParenToken, this.condition, this.closeParenToken, this.statement, elseClause);
        };

        IfStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.condition.isTypeScriptSpecific()) {
                return true;
            }
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            if (this.elseClause !== null && this.elseClause.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return IfStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.IfStatementSyntax = IfStatementSyntax;

    var ExpressionStatementSyntax = (function (_super) {
        __extends(ExpressionStatementSyntax, _super);
        function ExpressionStatementSyntax(expression, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.expression = expression;
            this.semicolonToken = semicolonToken;
        }
        ExpressionStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitExpressionStatement(this);
        };

        ExpressionStatementSyntax.prototype.kind = function () {
            return 149 /* ExpressionStatement */;
        };

        ExpressionStatementSyntax.prototype.childCount = function () {
            return 2;
        };

        ExpressionStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.expression;
                case 1:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ExpressionStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        ExpressionStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ExpressionStatementSyntax.prototype.update = function (expression, semicolonToken) {
            if (this.expression === expression && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ExpressionStatementSyntax(expression, semicolonToken, this.parsedInStrictMode());
        };

        ExpressionStatementSyntax.create1 = function (expression) {
            return new ExpressionStatementSyntax(expression, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        ExpressionStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ExpressionStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ExpressionStatementSyntax.prototype.withExpression = function (expression) {
            return this.update(expression, this.semicolonToken);
        };

        ExpressionStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.expression, semicolonToken);
        };

        ExpressionStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ExpressionStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ExpressionStatementSyntax = ExpressionStatementSyntax;

    var ConstructorDeclarationSyntax = (function (_super) {
        __extends(ConstructorDeclarationSyntax, _super);
        function ConstructorDeclarationSyntax(modifiers, constructorKeyword, callSignature, block, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.constructorKeyword = constructorKeyword;
            this.callSignature = callSignature;
            this.block = block;
            this.semicolonToken = semicolonToken;
        }
        ConstructorDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitConstructorDeclaration(this);
        };

        ConstructorDeclarationSyntax.prototype.kind = function () {
            return 137 /* ConstructorDeclaration */;
        };

        ConstructorDeclarationSyntax.prototype.childCount = function () {
            return 5;
        };

        ConstructorDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.constructorKeyword;
                case 2:
                    return this.callSignature;
                case 3:
                    return this.block;
                case 4:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ConstructorDeclarationSyntax.prototype.isClassElement = function () {
            return true;
        };

        ConstructorDeclarationSyntax.prototype.update = function (modifiers, constructorKeyword, callSignature, block, semicolonToken) {
            if (this.modifiers === modifiers && this.constructorKeyword === constructorKeyword && this.callSignature === callSignature && this.block === block && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ConstructorDeclarationSyntax(modifiers, constructorKeyword, callSignature, block, semicolonToken, this.parsedInStrictMode());
        };

        ConstructorDeclarationSyntax.create = function (constructorKeyword, callSignature) {
            return new ConstructorDeclarationSyntax(TypeScript.Syntax.emptyList, constructorKeyword, callSignature, null, null, false);
        };

        ConstructorDeclarationSyntax.create1 = function () {
            return new ConstructorDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(62 /* ConstructorKeyword */), CallSignatureSyntax.create1(), null, null, false);
        };

        ConstructorDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ConstructorDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ConstructorDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.constructorKeyword, this.callSignature, this.block, this.semicolonToken);
        };

        ConstructorDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        ConstructorDeclarationSyntax.prototype.withConstructorKeyword = function (constructorKeyword) {
            return this.update(this.modifiers, constructorKeyword, this.callSignature, this.block, this.semicolonToken);
        };

        ConstructorDeclarationSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.modifiers, this.constructorKeyword, callSignature, this.block, this.semicolonToken);
        };

        ConstructorDeclarationSyntax.prototype.withBlock = function (block) {
            return this.update(this.modifiers, this.constructorKeyword, this.callSignature, block, this.semicolonToken);
        };

        ConstructorDeclarationSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.constructorKeyword, this.callSignature, this.block, semicolonToken);
        };

        ConstructorDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return ConstructorDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ConstructorDeclarationSyntax = ConstructorDeclarationSyntax;

    var MemberFunctionDeclarationSyntax = (function (_super) {
        __extends(MemberFunctionDeclarationSyntax, _super);
        function MemberFunctionDeclarationSyntax(modifiers, propertyName, callSignature, block, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.propertyName = propertyName;
            this.callSignature = callSignature;
            this.block = block;
            this.semicolonToken = semicolonToken;
        }
        MemberFunctionDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitMemberFunctionDeclaration(this);
        };

        MemberFunctionDeclarationSyntax.prototype.kind = function () {
            return 135 /* MemberFunctionDeclaration */;
        };

        MemberFunctionDeclarationSyntax.prototype.childCount = function () {
            return 5;
        };

        MemberFunctionDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.propertyName;
                case 2:
                    return this.callSignature;
                case 3:
                    return this.block;
                case 4:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        MemberFunctionDeclarationSyntax.prototype.isMemberDeclaration = function () {
            return true;
        };

        MemberFunctionDeclarationSyntax.prototype.isClassElement = function () {
            return true;
        };

        MemberFunctionDeclarationSyntax.prototype.update = function (modifiers, propertyName, callSignature, block, semicolonToken) {
            if (this.modifiers === modifiers && this.propertyName === propertyName && this.callSignature === callSignature && this.block === block && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new MemberFunctionDeclarationSyntax(modifiers, propertyName, callSignature, block, semicolonToken, this.parsedInStrictMode());
        };

        MemberFunctionDeclarationSyntax.create = function (propertyName, callSignature) {
            return new MemberFunctionDeclarationSyntax(TypeScript.Syntax.emptyList, propertyName, callSignature, null, null, false);
        };

        MemberFunctionDeclarationSyntax.create1 = function (propertyName) {
            return new MemberFunctionDeclarationSyntax(TypeScript.Syntax.emptyList, propertyName, CallSignatureSyntax.create1(), null, null, false);
        };

        MemberFunctionDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        MemberFunctionDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        MemberFunctionDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.propertyName, this.callSignature, this.block, this.semicolonToken);
        };

        MemberFunctionDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        MemberFunctionDeclarationSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(this.modifiers, propertyName, this.callSignature, this.block, this.semicolonToken);
        };

        MemberFunctionDeclarationSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.modifiers, this.propertyName, callSignature, this.block, this.semicolonToken);
        };

        MemberFunctionDeclarationSyntax.prototype.withBlock = function (block) {
            return this.update(this.modifiers, this.propertyName, this.callSignature, block, this.semicolonToken);
        };

        MemberFunctionDeclarationSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.propertyName, this.callSignature, this.block, semicolonToken);
        };

        MemberFunctionDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return MemberFunctionDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.MemberFunctionDeclarationSyntax = MemberFunctionDeclarationSyntax;

    var GetAccessorSyntax = (function (_super) {
        __extends(GetAccessorSyntax, _super);
        function GetAccessorSyntax(modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.getKeyword = getKeyword;
            this.propertyName = propertyName;
            this.parameterList = parameterList;
            this.typeAnnotation = typeAnnotation;
            this.block = block;
        }
        GetAccessorSyntax.prototype.accept = function (visitor) {
            return visitor.visitGetAccessor(this);
        };

        GetAccessorSyntax.prototype.kind = function () {
            return 139 /* GetAccessor */;
        };

        GetAccessorSyntax.prototype.childCount = function () {
            return 6;
        };

        GetAccessorSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.getKeyword;
                case 2:
                    return this.propertyName;
                case 3:
                    return this.parameterList;
                case 4:
                    return this.typeAnnotation;
                case 5:
                    return this.block;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        GetAccessorSyntax.prototype.isMemberDeclaration = function () {
            return true;
        };

        GetAccessorSyntax.prototype.isPropertyAssignment = function () {
            return true;
        };

        GetAccessorSyntax.prototype.isClassElement = function () {
            return true;
        };

        GetAccessorSyntax.prototype.update = function (modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block) {
            if (this.modifiers === modifiers && this.getKeyword === getKeyword && this.propertyName === propertyName && this.parameterList === parameterList && this.typeAnnotation === typeAnnotation && this.block === block) {
                return this;
            }

            return new GetAccessorSyntax(modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block, this.parsedInStrictMode());
        };

        GetAccessorSyntax.create = function (getKeyword, propertyName, parameterList, block) {
            return new GetAccessorSyntax(TypeScript.Syntax.emptyList, getKeyword, propertyName, parameterList, null, block, false);
        };

        GetAccessorSyntax.create1 = function (propertyName) {
            return new GetAccessorSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(64 /* GetKeyword */), propertyName, ParameterListSyntax.create1(), null, BlockSyntax.create1(), false);
        };

        GetAccessorSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        GetAccessorSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        GetAccessorSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.getKeyword, this.propertyName, this.parameterList, this.typeAnnotation, this.block);
        };

        GetAccessorSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        GetAccessorSyntax.prototype.withGetKeyword = function (getKeyword) {
            return this.update(this.modifiers, getKeyword, this.propertyName, this.parameterList, this.typeAnnotation, this.block);
        };

        GetAccessorSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(this.modifiers, this.getKeyword, propertyName, this.parameterList, this.typeAnnotation, this.block);
        };

        GetAccessorSyntax.prototype.withParameterList = function (parameterList) {
            return this.update(this.modifiers, this.getKeyword, this.propertyName, parameterList, this.typeAnnotation, this.block);
        };

        GetAccessorSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.modifiers, this.getKeyword, this.propertyName, this.parameterList, typeAnnotation, this.block);
        };

        GetAccessorSyntax.prototype.withBlock = function (block) {
            return this.update(this.modifiers, this.getKeyword, this.propertyName, this.parameterList, this.typeAnnotation, block);
        };

        GetAccessorSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.modifiers.childCount() > 0) {
                return true;
            }
            if (this.parameterList.isTypeScriptSpecific()) {
                return true;
            }
            if (this.typeAnnotation !== null) {
                return true;
            }
            if (this.block.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return GetAccessorSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.GetAccessorSyntax = GetAccessorSyntax;

    var SetAccessorSyntax = (function (_super) {
        __extends(SetAccessorSyntax, _super);
        function SetAccessorSyntax(modifiers, setKeyword, propertyName, parameterList, block, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.setKeyword = setKeyword;
            this.propertyName = propertyName;
            this.parameterList = parameterList;
            this.block = block;
        }
        SetAccessorSyntax.prototype.accept = function (visitor) {
            return visitor.visitSetAccessor(this);
        };

        SetAccessorSyntax.prototype.kind = function () {
            return 140 /* SetAccessor */;
        };

        SetAccessorSyntax.prototype.childCount = function () {
            return 5;
        };

        SetAccessorSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.setKeyword;
                case 2:
                    return this.propertyName;
                case 3:
                    return this.parameterList;
                case 4:
                    return this.block;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        SetAccessorSyntax.prototype.isMemberDeclaration = function () {
            return true;
        };

        SetAccessorSyntax.prototype.isPropertyAssignment = function () {
            return true;
        };

        SetAccessorSyntax.prototype.isClassElement = function () {
            return true;
        };

        SetAccessorSyntax.prototype.update = function (modifiers, setKeyword, propertyName, parameterList, block) {
            if (this.modifiers === modifiers && this.setKeyword === setKeyword && this.propertyName === propertyName && this.parameterList === parameterList && this.block === block) {
                return this;
            }

            return new SetAccessorSyntax(modifiers, setKeyword, propertyName, parameterList, block, this.parsedInStrictMode());
        };

        SetAccessorSyntax.create = function (setKeyword, propertyName, parameterList, block) {
            return new SetAccessorSyntax(TypeScript.Syntax.emptyList, setKeyword, propertyName, parameterList, block, false);
        };

        SetAccessorSyntax.create1 = function (propertyName) {
            return new SetAccessorSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(68 /* SetKeyword */), propertyName, ParameterListSyntax.create1(), BlockSyntax.create1(), false);
        };

        SetAccessorSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        SetAccessorSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        SetAccessorSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.setKeyword, this.propertyName, this.parameterList, this.block);
        };

        SetAccessorSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        SetAccessorSyntax.prototype.withSetKeyword = function (setKeyword) {
            return this.update(this.modifiers, setKeyword, this.propertyName, this.parameterList, this.block);
        };

        SetAccessorSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(this.modifiers, this.setKeyword, propertyName, this.parameterList, this.block);
        };

        SetAccessorSyntax.prototype.withParameterList = function (parameterList) {
            return this.update(this.modifiers, this.setKeyword, this.propertyName, parameterList, this.block);
        };

        SetAccessorSyntax.prototype.withBlock = function (block) {
            return this.update(this.modifiers, this.setKeyword, this.propertyName, this.parameterList, block);
        };

        SetAccessorSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return SetAccessorSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.SetAccessorSyntax = SetAccessorSyntax;

    var MemberVariableDeclarationSyntax = (function (_super) {
        __extends(MemberVariableDeclarationSyntax, _super);
        function MemberVariableDeclarationSyntax(modifiers, variableDeclarator, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.variableDeclarator = variableDeclarator;
            this.semicolonToken = semicolonToken;
        }
        MemberVariableDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitMemberVariableDeclaration(this);
        };

        MemberVariableDeclarationSyntax.prototype.kind = function () {
            return 136 /* MemberVariableDeclaration */;
        };

        MemberVariableDeclarationSyntax.prototype.childCount = function () {
            return 3;
        };

        MemberVariableDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.variableDeclarator;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        MemberVariableDeclarationSyntax.prototype.isMemberDeclaration = function () {
            return true;
        };

        MemberVariableDeclarationSyntax.prototype.isClassElement = function () {
            return true;
        };

        MemberVariableDeclarationSyntax.prototype.update = function (modifiers, variableDeclarator, semicolonToken) {
            if (this.modifiers === modifiers && this.variableDeclarator === variableDeclarator && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new MemberVariableDeclarationSyntax(modifiers, variableDeclarator, semicolonToken, this.parsedInStrictMode());
        };

        MemberVariableDeclarationSyntax.create = function (variableDeclarator, semicolonToken) {
            return new MemberVariableDeclarationSyntax(TypeScript.Syntax.emptyList, variableDeclarator, semicolonToken, false);
        };

        MemberVariableDeclarationSyntax.create1 = function (variableDeclarator) {
            return new MemberVariableDeclarationSyntax(TypeScript.Syntax.emptyList, variableDeclarator, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        MemberVariableDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        MemberVariableDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        MemberVariableDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.variableDeclarator, this.semicolonToken);
        };

        MemberVariableDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        MemberVariableDeclarationSyntax.prototype.withVariableDeclarator = function (variableDeclarator) {
            return this.update(this.modifiers, variableDeclarator, this.semicolonToken);
        };

        MemberVariableDeclarationSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.variableDeclarator, semicolonToken);
        };

        MemberVariableDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return MemberVariableDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.MemberVariableDeclarationSyntax = MemberVariableDeclarationSyntax;

    var IndexMemberDeclarationSyntax = (function (_super) {
        __extends(IndexMemberDeclarationSyntax, _super);
        function IndexMemberDeclarationSyntax(modifiers, indexSignature, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.indexSignature = indexSignature;
            this.semicolonToken = semicolonToken;
        }
        IndexMemberDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitIndexMemberDeclaration(this);
        };

        IndexMemberDeclarationSyntax.prototype.kind = function () {
            return 138 /* IndexMemberDeclaration */;
        };

        IndexMemberDeclarationSyntax.prototype.childCount = function () {
            return 3;
        };

        IndexMemberDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.indexSignature;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        IndexMemberDeclarationSyntax.prototype.isClassElement = function () {
            return true;
        };

        IndexMemberDeclarationSyntax.prototype.update = function (modifiers, indexSignature, semicolonToken) {
            if (this.modifiers === modifiers && this.indexSignature === indexSignature && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new IndexMemberDeclarationSyntax(modifiers, indexSignature, semicolonToken, this.parsedInStrictMode());
        };

        IndexMemberDeclarationSyntax.create = function (indexSignature, semicolonToken) {
            return new IndexMemberDeclarationSyntax(TypeScript.Syntax.emptyList, indexSignature, semicolonToken, false);
        };

        IndexMemberDeclarationSyntax.create1 = function (indexSignature) {
            return new IndexMemberDeclarationSyntax(TypeScript.Syntax.emptyList, indexSignature, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        IndexMemberDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        IndexMemberDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        IndexMemberDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.indexSignature, this.semicolonToken);
        };

        IndexMemberDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        IndexMemberDeclarationSyntax.prototype.withIndexSignature = function (indexSignature) {
            return this.update(this.modifiers, indexSignature, this.semicolonToken);
        };

        IndexMemberDeclarationSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.modifiers, this.indexSignature, semicolonToken);
        };

        IndexMemberDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return IndexMemberDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.IndexMemberDeclarationSyntax = IndexMemberDeclarationSyntax;

    var ThrowStatementSyntax = (function (_super) {
        __extends(ThrowStatementSyntax, _super);
        function ThrowStatementSyntax(throwKeyword, expression, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.throwKeyword = throwKeyword;
            this.expression = expression;
            this.semicolonToken = semicolonToken;
        }
        ThrowStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitThrowStatement(this);
        };

        ThrowStatementSyntax.prototype.kind = function () {
            return 157 /* ThrowStatement */;
        };

        ThrowStatementSyntax.prototype.childCount = function () {
            return 3;
        };

        ThrowStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.throwKeyword;
                case 1:
                    return this.expression;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ThrowStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        ThrowStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ThrowStatementSyntax.prototype.update = function (throwKeyword, expression, semicolonToken) {
            if (this.throwKeyword === throwKeyword && this.expression === expression && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ThrowStatementSyntax(throwKeyword, expression, semicolonToken, this.parsedInStrictMode());
        };

        ThrowStatementSyntax.create1 = function (expression) {
            return new ThrowStatementSyntax(TypeScript.Syntax.token(36 /* ThrowKeyword */), expression, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        ThrowStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ThrowStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ThrowStatementSyntax.prototype.withThrowKeyword = function (throwKeyword) {
            return this.update(throwKeyword, this.expression, this.semicolonToken);
        };

        ThrowStatementSyntax.prototype.withExpression = function (expression) {
            return this.update(this.throwKeyword, expression, this.semicolonToken);
        };

        ThrowStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.throwKeyword, this.expression, semicolonToken);
        };

        ThrowStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ThrowStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ThrowStatementSyntax = ThrowStatementSyntax;

    var ReturnStatementSyntax = (function (_super) {
        __extends(ReturnStatementSyntax, _super);
        function ReturnStatementSyntax(returnKeyword, expression, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.returnKeyword = returnKeyword;
            this.expression = expression;
            this.semicolonToken = semicolonToken;
        }
        ReturnStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitReturnStatement(this);
        };

        ReturnStatementSyntax.prototype.kind = function () {
            return 150 /* ReturnStatement */;
        };

        ReturnStatementSyntax.prototype.childCount = function () {
            return 3;
        };

        ReturnStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.returnKeyword;
                case 1:
                    return this.expression;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ReturnStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        ReturnStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ReturnStatementSyntax.prototype.update = function (returnKeyword, expression, semicolonToken) {
            if (this.returnKeyword === returnKeyword && this.expression === expression && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ReturnStatementSyntax(returnKeyword, expression, semicolonToken, this.parsedInStrictMode());
        };

        ReturnStatementSyntax.create = function (returnKeyword, semicolonToken) {
            return new ReturnStatementSyntax(returnKeyword, null, semicolonToken, false);
        };

        ReturnStatementSyntax.create1 = function () {
            return new ReturnStatementSyntax(TypeScript.Syntax.token(33 /* ReturnKeyword */), null, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        ReturnStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ReturnStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ReturnStatementSyntax.prototype.withReturnKeyword = function (returnKeyword) {
            return this.update(returnKeyword, this.expression, this.semicolonToken);
        };

        ReturnStatementSyntax.prototype.withExpression = function (expression) {
            return this.update(this.returnKeyword, expression, this.semicolonToken);
        };

        ReturnStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.returnKeyword, this.expression, semicolonToken);
        };

        ReturnStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression !== null && this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ReturnStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ReturnStatementSyntax = ReturnStatementSyntax;

    var ObjectCreationExpressionSyntax = (function (_super) {
        __extends(ObjectCreationExpressionSyntax, _super);
        function ObjectCreationExpressionSyntax(newKeyword, expression, argumentList, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.newKeyword = newKeyword;
            this.expression = expression;
            this.argumentList = argumentList;
        }
        ObjectCreationExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitObjectCreationExpression(this);
        };

        ObjectCreationExpressionSyntax.prototype.kind = function () {
            return 216 /* ObjectCreationExpression */;
        };

        ObjectCreationExpressionSyntax.prototype.childCount = function () {
            return 3;
        };

        ObjectCreationExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.newKeyword;
                case 1:
                    return this.expression;
                case 2:
                    return this.argumentList;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ObjectCreationExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        ObjectCreationExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        ObjectCreationExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        ObjectCreationExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ObjectCreationExpressionSyntax.prototype.update = function (newKeyword, expression, argumentList) {
            if (this.newKeyword === newKeyword && this.expression === expression && this.argumentList === argumentList) {
                return this;
            }

            return new ObjectCreationExpressionSyntax(newKeyword, expression, argumentList, this.parsedInStrictMode());
        };

        ObjectCreationExpressionSyntax.create = function (newKeyword, expression) {
            return new ObjectCreationExpressionSyntax(newKeyword, expression, null, false);
        };

        ObjectCreationExpressionSyntax.create1 = function (expression) {
            return new ObjectCreationExpressionSyntax(TypeScript.Syntax.token(31 /* NewKeyword */), expression, null, false);
        };

        ObjectCreationExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ObjectCreationExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ObjectCreationExpressionSyntax.prototype.withNewKeyword = function (newKeyword) {
            return this.update(newKeyword, this.expression, this.argumentList);
        };

        ObjectCreationExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.newKeyword, expression, this.argumentList);
        };

        ObjectCreationExpressionSyntax.prototype.withArgumentList = function (argumentList) {
            return this.update(this.newKeyword, this.expression, argumentList);
        };

        ObjectCreationExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            if (this.argumentList !== null && this.argumentList.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ObjectCreationExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ObjectCreationExpressionSyntax = ObjectCreationExpressionSyntax;

    var SwitchStatementSyntax = (function (_super) {
        __extends(SwitchStatementSyntax, _super);
        function SwitchStatementSyntax(switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.switchKeyword = switchKeyword;
            this.openParenToken = openParenToken;
            this.expression = expression;
            this.closeParenToken = closeParenToken;
            this.openBraceToken = openBraceToken;
            this.switchClauses = switchClauses;
            this.closeBraceToken = closeBraceToken;
        }
        SwitchStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitSwitchStatement(this);
        };

        SwitchStatementSyntax.prototype.kind = function () {
            return 151 /* SwitchStatement */;
        };

        SwitchStatementSyntax.prototype.childCount = function () {
            return 7;
        };

        SwitchStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.switchKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.expression;
                case 3:
                    return this.closeParenToken;
                case 4:
                    return this.openBraceToken;
                case 5:
                    return this.switchClauses;
                case 6:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        SwitchStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        SwitchStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        SwitchStatementSyntax.prototype.update = function (switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken) {
            if (this.switchKeyword === switchKeyword && this.openParenToken === openParenToken && this.expression === expression && this.closeParenToken === closeParenToken && this.openBraceToken === openBraceToken && this.switchClauses === switchClauses && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new SwitchStatementSyntax(switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken, this.parsedInStrictMode());
        };

        SwitchStatementSyntax.create = function (switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, closeBraceToken) {
            return new SwitchStatementSyntax(switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, TypeScript.Syntax.emptyList, closeBraceToken, false);
        };

        SwitchStatementSyntax.create1 = function (expression) {
            return new SwitchStatementSyntax(TypeScript.Syntax.token(34 /* SwitchKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), expression, TypeScript.Syntax.token(73 /* CloseParenToken */), TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptyList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        SwitchStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        SwitchStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        SwitchStatementSyntax.prototype.withSwitchKeyword = function (switchKeyword) {
            return this.update(switchKeyword, this.openParenToken, this.expression, this.closeParenToken, this.openBraceToken, this.switchClauses, this.closeBraceToken);
        };

        SwitchStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.switchKeyword, openParenToken, this.expression, this.closeParenToken, this.openBraceToken, this.switchClauses, this.closeBraceToken);
        };

        SwitchStatementSyntax.prototype.withExpression = function (expression) {
            return this.update(this.switchKeyword, this.openParenToken, expression, this.closeParenToken, this.openBraceToken, this.switchClauses, this.closeBraceToken);
        };

        SwitchStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.switchKeyword, this.openParenToken, this.expression, closeParenToken, this.openBraceToken, this.switchClauses, this.closeBraceToken);
        };

        SwitchStatementSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(this.switchKeyword, this.openParenToken, this.expression, this.closeParenToken, openBraceToken, this.switchClauses, this.closeBraceToken);
        };

        SwitchStatementSyntax.prototype.withSwitchClauses = function (switchClauses) {
            return this.update(this.switchKeyword, this.openParenToken, this.expression, this.closeParenToken, this.openBraceToken, switchClauses, this.closeBraceToken);
        };

        SwitchStatementSyntax.prototype.withSwitchClause = function (switchClause) {
            return this.withSwitchClauses(TypeScript.Syntax.list([switchClause]));
        };

        SwitchStatementSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.switchKeyword, this.openParenToken, this.expression, this.closeParenToken, this.openBraceToken, this.switchClauses, closeBraceToken);
        };

        SwitchStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            if (this.switchClauses.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return SwitchStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.SwitchStatementSyntax = SwitchStatementSyntax;

    var CaseSwitchClauseSyntax = (function (_super) {
        __extends(CaseSwitchClauseSyntax, _super);
        function CaseSwitchClauseSyntax(caseKeyword, expression, colonToken, statements, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.caseKeyword = caseKeyword;
            this.expression = expression;
            this.colonToken = colonToken;
            this.statements = statements;
        }
        CaseSwitchClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitCaseSwitchClause(this);
        };

        CaseSwitchClauseSyntax.prototype.kind = function () {
            return 233 /* CaseSwitchClause */;
        };

        CaseSwitchClauseSyntax.prototype.childCount = function () {
            return 4;
        };

        CaseSwitchClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.caseKeyword;
                case 1:
                    return this.expression;
                case 2:
                    return this.colonToken;
                case 3:
                    return this.statements;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        CaseSwitchClauseSyntax.prototype.isSwitchClause = function () {
            return true;
        };

        CaseSwitchClauseSyntax.prototype.update = function (caseKeyword, expression, colonToken, statements) {
            if (this.caseKeyword === caseKeyword && this.expression === expression && this.colonToken === colonToken && this.statements === statements) {
                return this;
            }

            return new CaseSwitchClauseSyntax(caseKeyword, expression, colonToken, statements, this.parsedInStrictMode());
        };

        CaseSwitchClauseSyntax.create = function (caseKeyword, expression, colonToken) {
            return new CaseSwitchClauseSyntax(caseKeyword, expression, colonToken, TypeScript.Syntax.emptyList, false);
        };

        CaseSwitchClauseSyntax.create1 = function (expression) {
            return new CaseSwitchClauseSyntax(TypeScript.Syntax.token(16 /* CaseKeyword */), expression, TypeScript.Syntax.token(106 /* ColonToken */), TypeScript.Syntax.emptyList, false);
        };

        CaseSwitchClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        CaseSwitchClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        CaseSwitchClauseSyntax.prototype.withCaseKeyword = function (caseKeyword) {
            return this.update(caseKeyword, this.expression, this.colonToken, this.statements);
        };

        CaseSwitchClauseSyntax.prototype.withExpression = function (expression) {
            return this.update(this.caseKeyword, expression, this.colonToken, this.statements);
        };

        CaseSwitchClauseSyntax.prototype.withColonToken = function (colonToken) {
            return this.update(this.caseKeyword, this.expression, colonToken, this.statements);
        };

        CaseSwitchClauseSyntax.prototype.withStatements = function (statements) {
            return this.update(this.caseKeyword, this.expression, this.colonToken, statements);
        };

        CaseSwitchClauseSyntax.prototype.withStatement = function (statement) {
            return this.withStatements(TypeScript.Syntax.list([statement]));
        };

        CaseSwitchClauseSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            if (this.statements.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return CaseSwitchClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.CaseSwitchClauseSyntax = CaseSwitchClauseSyntax;

    var DefaultSwitchClauseSyntax = (function (_super) {
        __extends(DefaultSwitchClauseSyntax, _super);
        function DefaultSwitchClauseSyntax(defaultKeyword, colonToken, statements, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.defaultKeyword = defaultKeyword;
            this.colonToken = colonToken;
            this.statements = statements;
        }
        DefaultSwitchClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitDefaultSwitchClause(this);
        };

        DefaultSwitchClauseSyntax.prototype.kind = function () {
            return 234 /* DefaultSwitchClause */;
        };

        DefaultSwitchClauseSyntax.prototype.childCount = function () {
            return 3;
        };

        DefaultSwitchClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.defaultKeyword;
                case 1:
                    return this.colonToken;
                case 2:
                    return this.statements;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        DefaultSwitchClauseSyntax.prototype.isSwitchClause = function () {
            return true;
        };

        DefaultSwitchClauseSyntax.prototype.update = function (defaultKeyword, colonToken, statements) {
            if (this.defaultKeyword === defaultKeyword && this.colonToken === colonToken && this.statements === statements) {
                return this;
            }

            return new DefaultSwitchClauseSyntax(defaultKeyword, colonToken, statements, this.parsedInStrictMode());
        };

        DefaultSwitchClauseSyntax.create = function (defaultKeyword, colonToken) {
            return new DefaultSwitchClauseSyntax(defaultKeyword, colonToken, TypeScript.Syntax.emptyList, false);
        };

        DefaultSwitchClauseSyntax.create1 = function () {
            return new DefaultSwitchClauseSyntax(TypeScript.Syntax.token(20 /* DefaultKeyword */), TypeScript.Syntax.token(106 /* ColonToken */), TypeScript.Syntax.emptyList, false);
        };

        DefaultSwitchClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        DefaultSwitchClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        DefaultSwitchClauseSyntax.prototype.withDefaultKeyword = function (defaultKeyword) {
            return this.update(defaultKeyword, this.colonToken, this.statements);
        };

        DefaultSwitchClauseSyntax.prototype.withColonToken = function (colonToken) {
            return this.update(this.defaultKeyword, colonToken, this.statements);
        };

        DefaultSwitchClauseSyntax.prototype.withStatements = function (statements) {
            return this.update(this.defaultKeyword, this.colonToken, statements);
        };

        DefaultSwitchClauseSyntax.prototype.withStatement = function (statement) {
            return this.withStatements(TypeScript.Syntax.list([statement]));
        };

        DefaultSwitchClauseSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.statements.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return DefaultSwitchClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.DefaultSwitchClauseSyntax = DefaultSwitchClauseSyntax;

    var BreakStatementSyntax = (function (_super) {
        __extends(BreakStatementSyntax, _super);
        function BreakStatementSyntax(breakKeyword, identifier, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.breakKeyword = breakKeyword;
            this.identifier = identifier;
            this.semicolonToken = semicolonToken;
        }
        BreakStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitBreakStatement(this);
        };

        BreakStatementSyntax.prototype.kind = function () {
            return 152 /* BreakStatement */;
        };

        BreakStatementSyntax.prototype.childCount = function () {
            return 3;
        };

        BreakStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.breakKeyword;
                case 1:
                    return this.identifier;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        BreakStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        BreakStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        BreakStatementSyntax.prototype.update = function (breakKeyword, identifier, semicolonToken) {
            if (this.breakKeyword === breakKeyword && this.identifier === identifier && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new BreakStatementSyntax(breakKeyword, identifier, semicolonToken, this.parsedInStrictMode());
        };

        BreakStatementSyntax.create = function (breakKeyword, semicolonToken) {
            return new BreakStatementSyntax(breakKeyword, null, semicolonToken, false);
        };

        BreakStatementSyntax.create1 = function () {
            return new BreakStatementSyntax(TypeScript.Syntax.token(15 /* BreakKeyword */), null, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        BreakStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        BreakStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        BreakStatementSyntax.prototype.withBreakKeyword = function (breakKeyword) {
            return this.update(breakKeyword, this.identifier, this.semicolonToken);
        };

        BreakStatementSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.breakKeyword, identifier, this.semicolonToken);
        };

        BreakStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.breakKeyword, this.identifier, semicolonToken);
        };

        BreakStatementSyntax.prototype.isTypeScriptSpecific = function () {
            return false;
        };
        return BreakStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.BreakStatementSyntax = BreakStatementSyntax;

    var ContinueStatementSyntax = (function (_super) {
        __extends(ContinueStatementSyntax, _super);
        function ContinueStatementSyntax(continueKeyword, identifier, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.continueKeyword = continueKeyword;
            this.identifier = identifier;
            this.semicolonToken = semicolonToken;
        }
        ContinueStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitContinueStatement(this);
        };

        ContinueStatementSyntax.prototype.kind = function () {
            return 153 /* ContinueStatement */;
        };

        ContinueStatementSyntax.prototype.childCount = function () {
            return 3;
        };

        ContinueStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.continueKeyword;
                case 1:
                    return this.identifier;
                case 2:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ContinueStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        ContinueStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ContinueStatementSyntax.prototype.update = function (continueKeyword, identifier, semicolonToken) {
            if (this.continueKeyword === continueKeyword && this.identifier === identifier && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new ContinueStatementSyntax(continueKeyword, identifier, semicolonToken, this.parsedInStrictMode());
        };

        ContinueStatementSyntax.create = function (continueKeyword, semicolonToken) {
            return new ContinueStatementSyntax(continueKeyword, null, semicolonToken, false);
        };

        ContinueStatementSyntax.create1 = function () {
            return new ContinueStatementSyntax(TypeScript.Syntax.token(18 /* ContinueKeyword */), null, TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        ContinueStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ContinueStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ContinueStatementSyntax.prototype.withContinueKeyword = function (continueKeyword) {
            return this.update(continueKeyword, this.identifier, this.semicolonToken);
        };

        ContinueStatementSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.continueKeyword, identifier, this.semicolonToken);
        };

        ContinueStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.continueKeyword, this.identifier, semicolonToken);
        };

        ContinueStatementSyntax.prototype.isTypeScriptSpecific = function () {
            return false;
        };
        return ContinueStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ContinueStatementSyntax = ContinueStatementSyntax;

    var ForStatementSyntax = (function (_super) {
        __extends(ForStatementSyntax, _super);
        function ForStatementSyntax(forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.forKeyword = forKeyword;
            this.openParenToken = openParenToken;
            this.variableDeclaration = variableDeclaration;
            this.initializer = initializer;
            this.firstSemicolonToken = firstSemicolonToken;
            this.condition = condition;
            this.secondSemicolonToken = secondSemicolonToken;
            this.incrementor = incrementor;
            this.closeParenToken = closeParenToken;
            this.statement = statement;
        }
        ForStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitForStatement(this);
        };

        ForStatementSyntax.prototype.kind = function () {
            return 154 /* ForStatement */;
        };

        ForStatementSyntax.prototype.childCount = function () {
            return 10;
        };

        ForStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.forKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.variableDeclaration;
                case 3:
                    return this.initializer;
                case 4:
                    return this.firstSemicolonToken;
                case 5:
                    return this.condition;
                case 6:
                    return this.secondSemicolonToken;
                case 7:
                    return this.incrementor;
                case 8:
                    return this.closeParenToken;
                case 9:
                    return this.statement;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ForStatementSyntax.prototype.isIterationStatement = function () {
            return true;
        };

        ForStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        ForStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ForStatementSyntax.prototype.update = function (forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement) {
            if (this.forKeyword === forKeyword && this.openParenToken === openParenToken && this.variableDeclaration === variableDeclaration && this.initializer === initializer && this.firstSemicolonToken === firstSemicolonToken && this.condition === condition && this.secondSemicolonToken === secondSemicolonToken && this.incrementor === incrementor && this.closeParenToken === closeParenToken && this.statement === statement) {
                return this;
            }

            return new ForStatementSyntax(forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement, this.parsedInStrictMode());
        };

        ForStatementSyntax.create = function (forKeyword, openParenToken, firstSemicolonToken, secondSemicolonToken, closeParenToken, statement) {
            return new ForStatementSyntax(forKeyword, openParenToken, null, null, firstSemicolonToken, null, secondSemicolonToken, null, closeParenToken, statement, false);
        };

        ForStatementSyntax.create1 = function (statement) {
            return new ForStatementSyntax(TypeScript.Syntax.token(26 /* ForKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), null, null, TypeScript.Syntax.token(78 /* SemicolonToken */), null, TypeScript.Syntax.token(78 /* SemicolonToken */), null, TypeScript.Syntax.token(73 /* CloseParenToken */), statement, false);
        };

        ForStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ForStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ForStatementSyntax.prototype.withForKeyword = function (forKeyword) {
            return this.update(forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.forKeyword, openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withVariableDeclaration = function (variableDeclaration) {
            return this.update(this.forKeyword, this.openParenToken, variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withInitializer = function (initializer) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withFirstSemicolonToken = function (firstSemicolonToken) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withCondition = function (condition) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withSecondSemicolonToken = function (secondSemicolonToken) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, secondSemicolonToken, this.incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withIncrementor = function (incrementor) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, incrementor, this.closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, closeParenToken, this.statement);
        };

        ForStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.initializer, this.firstSemicolonToken, this.condition, this.secondSemicolonToken, this.incrementor, this.closeParenToken, statement);
        };

        ForStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.variableDeclaration !== null && this.variableDeclaration.isTypeScriptSpecific()) {
                return true;
            }
            if (this.initializer !== null && this.initializer.isTypeScriptSpecific()) {
                return true;
            }
            if (this.condition !== null && this.condition.isTypeScriptSpecific()) {
                return true;
            }
            if (this.incrementor !== null && this.incrementor.isTypeScriptSpecific()) {
                return true;
            }
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ForStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ForStatementSyntax = ForStatementSyntax;

    var ForInStatementSyntax = (function (_super) {
        __extends(ForInStatementSyntax, _super);
        function ForInStatementSyntax(forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.forKeyword = forKeyword;
            this.openParenToken = openParenToken;
            this.variableDeclaration = variableDeclaration;
            this.left = left;
            this.inKeyword = inKeyword;
            this.expression = expression;
            this.closeParenToken = closeParenToken;
            this.statement = statement;
        }
        ForInStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitForInStatement(this);
        };

        ForInStatementSyntax.prototype.kind = function () {
            return 155 /* ForInStatement */;
        };

        ForInStatementSyntax.prototype.childCount = function () {
            return 8;
        };

        ForInStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.forKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.variableDeclaration;
                case 3:
                    return this.left;
                case 4:
                    return this.inKeyword;
                case 5:
                    return this.expression;
                case 6:
                    return this.closeParenToken;
                case 7:
                    return this.statement;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ForInStatementSyntax.prototype.isIterationStatement = function () {
            return true;
        };

        ForInStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        ForInStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        ForInStatementSyntax.prototype.update = function (forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement) {
            if (this.forKeyword === forKeyword && this.openParenToken === openParenToken && this.variableDeclaration === variableDeclaration && this.left === left && this.inKeyword === inKeyword && this.expression === expression && this.closeParenToken === closeParenToken && this.statement === statement) {
                return this;
            }

            return new ForInStatementSyntax(forKeyword, openParenToken, variableDeclaration, left, inKeyword, expression, closeParenToken, statement, this.parsedInStrictMode());
        };

        ForInStatementSyntax.create = function (forKeyword, openParenToken, inKeyword, expression, closeParenToken, statement) {
            return new ForInStatementSyntax(forKeyword, openParenToken, null, null, inKeyword, expression, closeParenToken, statement, false);
        };

        ForInStatementSyntax.create1 = function (expression, statement) {
            return new ForInStatementSyntax(TypeScript.Syntax.token(26 /* ForKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), null, null, TypeScript.Syntax.token(29 /* InKeyword */), expression, TypeScript.Syntax.token(73 /* CloseParenToken */), statement, false);
        };

        ForInStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ForInStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ForInStatementSyntax.prototype.withForKeyword = function (forKeyword) {
            return this.update(forKeyword, this.openParenToken, this.variableDeclaration, this.left, this.inKeyword, this.expression, this.closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.forKeyword, openParenToken, this.variableDeclaration, this.left, this.inKeyword, this.expression, this.closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withVariableDeclaration = function (variableDeclaration) {
            return this.update(this.forKeyword, this.openParenToken, variableDeclaration, this.left, this.inKeyword, this.expression, this.closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withLeft = function (left) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, left, this.inKeyword, this.expression, this.closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withInKeyword = function (inKeyword) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.left, inKeyword, this.expression, this.closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withExpression = function (expression) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.left, this.inKeyword, expression, this.closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.left, this.inKeyword, this.expression, closeParenToken, this.statement);
        };

        ForInStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.forKeyword, this.openParenToken, this.variableDeclaration, this.left, this.inKeyword, this.expression, this.closeParenToken, statement);
        };

        ForInStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.variableDeclaration !== null && this.variableDeclaration.isTypeScriptSpecific()) {
                return true;
            }
            if (this.left !== null && this.left.isTypeScriptSpecific()) {
                return true;
            }
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ForInStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ForInStatementSyntax = ForInStatementSyntax;

    var WhileStatementSyntax = (function (_super) {
        __extends(WhileStatementSyntax, _super);
        function WhileStatementSyntax(whileKeyword, openParenToken, condition, closeParenToken, statement, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.whileKeyword = whileKeyword;
            this.openParenToken = openParenToken;
            this.condition = condition;
            this.closeParenToken = closeParenToken;
            this.statement = statement;
        }
        WhileStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitWhileStatement(this);
        };

        WhileStatementSyntax.prototype.kind = function () {
            return 158 /* WhileStatement */;
        };

        WhileStatementSyntax.prototype.childCount = function () {
            return 5;
        };

        WhileStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.whileKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.condition;
                case 3:
                    return this.closeParenToken;
                case 4:
                    return this.statement;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        WhileStatementSyntax.prototype.isIterationStatement = function () {
            return true;
        };

        WhileStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        WhileStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        WhileStatementSyntax.prototype.update = function (whileKeyword, openParenToken, condition, closeParenToken, statement) {
            if (this.whileKeyword === whileKeyword && this.openParenToken === openParenToken && this.condition === condition && this.closeParenToken === closeParenToken && this.statement === statement) {
                return this;
            }

            return new WhileStatementSyntax(whileKeyword, openParenToken, condition, closeParenToken, statement, this.parsedInStrictMode());
        };

        WhileStatementSyntax.create1 = function (condition, statement) {
            return new WhileStatementSyntax(TypeScript.Syntax.token(42 /* WhileKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), condition, TypeScript.Syntax.token(73 /* CloseParenToken */), statement, false);
        };

        WhileStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        WhileStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        WhileStatementSyntax.prototype.withWhileKeyword = function (whileKeyword) {
            return this.update(whileKeyword, this.openParenToken, this.condition, this.closeParenToken, this.statement);
        };

        WhileStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.whileKeyword, openParenToken, this.condition, this.closeParenToken, this.statement);
        };

        WhileStatementSyntax.prototype.withCondition = function (condition) {
            return this.update(this.whileKeyword, this.openParenToken, condition, this.closeParenToken, this.statement);
        };

        WhileStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.whileKeyword, this.openParenToken, this.condition, closeParenToken, this.statement);
        };

        WhileStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.whileKeyword, this.openParenToken, this.condition, this.closeParenToken, statement);
        };

        WhileStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.condition.isTypeScriptSpecific()) {
                return true;
            }
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return WhileStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.WhileStatementSyntax = WhileStatementSyntax;

    var WithStatementSyntax = (function (_super) {
        __extends(WithStatementSyntax, _super);
        function WithStatementSyntax(withKeyword, openParenToken, condition, closeParenToken, statement, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.withKeyword = withKeyword;
            this.openParenToken = openParenToken;
            this.condition = condition;
            this.closeParenToken = closeParenToken;
            this.statement = statement;
        }
        WithStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitWithStatement(this);
        };

        WithStatementSyntax.prototype.kind = function () {
            return 163 /* WithStatement */;
        };

        WithStatementSyntax.prototype.childCount = function () {
            return 5;
        };

        WithStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.withKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.condition;
                case 3:
                    return this.closeParenToken;
                case 4:
                    return this.statement;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        WithStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        WithStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        WithStatementSyntax.prototype.update = function (withKeyword, openParenToken, condition, closeParenToken, statement) {
            if (this.withKeyword === withKeyword && this.openParenToken === openParenToken && this.condition === condition && this.closeParenToken === closeParenToken && this.statement === statement) {
                return this;
            }

            return new WithStatementSyntax(withKeyword, openParenToken, condition, closeParenToken, statement, this.parsedInStrictMode());
        };

        WithStatementSyntax.create1 = function (condition, statement) {
            return new WithStatementSyntax(TypeScript.Syntax.token(43 /* WithKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), condition, TypeScript.Syntax.token(73 /* CloseParenToken */), statement, false);
        };

        WithStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        WithStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        WithStatementSyntax.prototype.withWithKeyword = function (withKeyword) {
            return this.update(withKeyword, this.openParenToken, this.condition, this.closeParenToken, this.statement);
        };

        WithStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.withKeyword, openParenToken, this.condition, this.closeParenToken, this.statement);
        };

        WithStatementSyntax.prototype.withCondition = function (condition) {
            return this.update(this.withKeyword, this.openParenToken, condition, this.closeParenToken, this.statement);
        };

        WithStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.withKeyword, this.openParenToken, this.condition, closeParenToken, this.statement);
        };

        WithStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.withKeyword, this.openParenToken, this.condition, this.closeParenToken, statement);
        };

        WithStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.condition.isTypeScriptSpecific()) {
                return true;
            }
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return WithStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.WithStatementSyntax = WithStatementSyntax;

    var EnumDeclarationSyntax = (function (_super) {
        __extends(EnumDeclarationSyntax, _super);
        function EnumDeclarationSyntax(modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.modifiers = modifiers;
            this.enumKeyword = enumKeyword;
            this.identifier = identifier;
            this.openBraceToken = openBraceToken;
            this.enumElements = enumElements;
            this.closeBraceToken = closeBraceToken;
        }
        EnumDeclarationSyntax.prototype.accept = function (visitor) {
            return visitor.visitEnumDeclaration(this);
        };

        EnumDeclarationSyntax.prototype.kind = function () {
            return 132 /* EnumDeclaration */;
        };

        EnumDeclarationSyntax.prototype.childCount = function () {
            return 6;
        };

        EnumDeclarationSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.modifiers;
                case 1:
                    return this.enumKeyword;
                case 2:
                    return this.identifier;
                case 3:
                    return this.openBraceToken;
                case 4:
                    return this.enumElements;
                case 5:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        EnumDeclarationSyntax.prototype.isModuleElement = function () {
            return true;
        };

        EnumDeclarationSyntax.prototype.update = function (modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken) {
            if (this.modifiers === modifiers && this.enumKeyword === enumKeyword && this.identifier === identifier && this.openBraceToken === openBraceToken && this.enumElements === enumElements && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new EnumDeclarationSyntax(modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken, this.parsedInStrictMode());
        };

        EnumDeclarationSyntax.create = function (enumKeyword, identifier, openBraceToken, closeBraceToken) {
            return new EnumDeclarationSyntax(TypeScript.Syntax.emptyList, enumKeyword, identifier, openBraceToken, TypeScript.Syntax.emptySeparatedList, closeBraceToken, false);
        };

        EnumDeclarationSyntax.create1 = function (identifier) {
            return new EnumDeclarationSyntax(TypeScript.Syntax.emptyList, TypeScript.Syntax.token(46 /* EnumKeyword */), identifier, TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        EnumDeclarationSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        EnumDeclarationSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        EnumDeclarationSyntax.prototype.withModifiers = function (modifiers) {
            return this.update(modifiers, this.enumKeyword, this.identifier, this.openBraceToken, this.enumElements, this.closeBraceToken);
        };

        EnumDeclarationSyntax.prototype.withModifier = function (modifier) {
            return this.withModifiers(TypeScript.Syntax.list([modifier]));
        };

        EnumDeclarationSyntax.prototype.withEnumKeyword = function (enumKeyword) {
            return this.update(this.modifiers, enumKeyword, this.identifier, this.openBraceToken, this.enumElements, this.closeBraceToken);
        };

        EnumDeclarationSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.modifiers, this.enumKeyword, identifier, this.openBraceToken, this.enumElements, this.closeBraceToken);
        };

        EnumDeclarationSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(this.modifiers, this.enumKeyword, this.identifier, openBraceToken, this.enumElements, this.closeBraceToken);
        };

        EnumDeclarationSyntax.prototype.withEnumElements = function (enumElements) {
            return this.update(this.modifiers, this.enumKeyword, this.identifier, this.openBraceToken, enumElements, this.closeBraceToken);
        };

        EnumDeclarationSyntax.prototype.withEnumElement = function (enumElement) {
            return this.withEnumElements(TypeScript.Syntax.separatedList([enumElement]));
        };

        EnumDeclarationSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.modifiers, this.enumKeyword, this.identifier, this.openBraceToken, this.enumElements, closeBraceToken);
        };

        EnumDeclarationSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return EnumDeclarationSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.EnumDeclarationSyntax = EnumDeclarationSyntax;

    var EnumElementSyntax = (function (_super) {
        __extends(EnumElementSyntax, _super);
        function EnumElementSyntax(propertyName, equalsValueClause, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.propertyName = propertyName;
            this.equalsValueClause = equalsValueClause;
        }
        EnumElementSyntax.prototype.accept = function (visitor) {
            return visitor.visitEnumElement(this);
        };

        EnumElementSyntax.prototype.kind = function () {
            return 243 /* EnumElement */;
        };

        EnumElementSyntax.prototype.childCount = function () {
            return 2;
        };

        EnumElementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.propertyName;
                case 1:
                    return this.equalsValueClause;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        EnumElementSyntax.prototype.update = function (propertyName, equalsValueClause) {
            if (this.propertyName === propertyName && this.equalsValueClause === equalsValueClause) {
                return this;
            }

            return new EnumElementSyntax(propertyName, equalsValueClause, this.parsedInStrictMode());
        };

        EnumElementSyntax.create = function (propertyName) {
            return new EnumElementSyntax(propertyName, null, false);
        };

        EnumElementSyntax.create1 = function (propertyName) {
            return new EnumElementSyntax(propertyName, null, false);
        };

        EnumElementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        EnumElementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        EnumElementSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(propertyName, this.equalsValueClause);
        };

        EnumElementSyntax.prototype.withEqualsValueClause = function (equalsValueClause) {
            return this.update(this.propertyName, equalsValueClause);
        };

        EnumElementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.equalsValueClause !== null && this.equalsValueClause.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return EnumElementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.EnumElementSyntax = EnumElementSyntax;

    var CastExpressionSyntax = (function (_super) {
        __extends(CastExpressionSyntax, _super);
        function CastExpressionSyntax(lessThanToken, type, greaterThanToken, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.lessThanToken = lessThanToken;
            this.type = type;
            this.greaterThanToken = greaterThanToken;
            this.expression = expression;
        }
        CastExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitCastExpression(this);
        };

        CastExpressionSyntax.prototype.kind = function () {
            return 220 /* CastExpression */;
        };

        CastExpressionSyntax.prototype.childCount = function () {
            return 4;
        };

        CastExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.lessThanToken;
                case 1:
                    return this.type;
                case 2:
                    return this.greaterThanToken;
                case 3:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        CastExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        CastExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        CastExpressionSyntax.prototype.update = function (lessThanToken, type, greaterThanToken, expression) {
            if (this.lessThanToken === lessThanToken && this.type === type && this.greaterThanToken === greaterThanToken && this.expression === expression) {
                return this;
            }

            return new CastExpressionSyntax(lessThanToken, type, greaterThanToken, expression, this.parsedInStrictMode());
        };

        CastExpressionSyntax.create1 = function (type, expression) {
            return new CastExpressionSyntax(TypeScript.Syntax.token(80 /* LessThanToken */), type, TypeScript.Syntax.token(81 /* GreaterThanToken */), expression, false);
        };

        CastExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        CastExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        CastExpressionSyntax.prototype.withLessThanToken = function (lessThanToken) {
            return this.update(lessThanToken, this.type, this.greaterThanToken, this.expression);
        };

        CastExpressionSyntax.prototype.withType = function (type) {
            return this.update(this.lessThanToken, type, this.greaterThanToken, this.expression);
        };

        CastExpressionSyntax.prototype.withGreaterThanToken = function (greaterThanToken) {
            return this.update(this.lessThanToken, this.type, greaterThanToken, this.expression);
        };

        CastExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.lessThanToken, this.type, this.greaterThanToken, expression);
        };

        CastExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            return true;
        };
        return CastExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.CastExpressionSyntax = CastExpressionSyntax;

    var ObjectLiteralExpressionSyntax = (function (_super) {
        __extends(ObjectLiteralExpressionSyntax, _super);
        function ObjectLiteralExpressionSyntax(openBraceToken, propertyAssignments, closeBraceToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.openBraceToken = openBraceToken;
            this.propertyAssignments = propertyAssignments;
            this.closeBraceToken = closeBraceToken;
        }
        ObjectLiteralExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitObjectLiteralExpression(this);
        };

        ObjectLiteralExpressionSyntax.prototype.kind = function () {
            return 215 /* ObjectLiteralExpression */;
        };

        ObjectLiteralExpressionSyntax.prototype.childCount = function () {
            return 3;
        };

        ObjectLiteralExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.openBraceToken;
                case 1:
                    return this.propertyAssignments;
                case 2:
                    return this.closeBraceToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        ObjectLiteralExpressionSyntax.prototype.isPrimaryExpression = function () {
            return true;
        };

        ObjectLiteralExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        ObjectLiteralExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        ObjectLiteralExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        ObjectLiteralExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        ObjectLiteralExpressionSyntax.prototype.update = function (openBraceToken, propertyAssignments, closeBraceToken) {
            if (this.openBraceToken === openBraceToken && this.propertyAssignments === propertyAssignments && this.closeBraceToken === closeBraceToken) {
                return this;
            }

            return new ObjectLiteralExpressionSyntax(openBraceToken, propertyAssignments, closeBraceToken, this.parsedInStrictMode());
        };

        ObjectLiteralExpressionSyntax.create = function (openBraceToken, closeBraceToken) {
            return new ObjectLiteralExpressionSyntax(openBraceToken, TypeScript.Syntax.emptySeparatedList, closeBraceToken, false);
        };

        ObjectLiteralExpressionSyntax.create1 = function () {
            return new ObjectLiteralExpressionSyntax(TypeScript.Syntax.token(70 /* OpenBraceToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.token(71 /* CloseBraceToken */), false);
        };

        ObjectLiteralExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        ObjectLiteralExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        ObjectLiteralExpressionSyntax.prototype.withOpenBraceToken = function (openBraceToken) {
            return this.update(openBraceToken, this.propertyAssignments, this.closeBraceToken);
        };

        ObjectLiteralExpressionSyntax.prototype.withPropertyAssignments = function (propertyAssignments) {
            return this.update(this.openBraceToken, propertyAssignments, this.closeBraceToken);
        };

        ObjectLiteralExpressionSyntax.prototype.withPropertyAssignment = function (propertyAssignment) {
            return this.withPropertyAssignments(TypeScript.Syntax.separatedList([propertyAssignment]));
        };

        ObjectLiteralExpressionSyntax.prototype.withCloseBraceToken = function (closeBraceToken) {
            return this.update(this.openBraceToken, this.propertyAssignments, closeBraceToken);
        };

        ObjectLiteralExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.propertyAssignments.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return ObjectLiteralExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.ObjectLiteralExpressionSyntax = ObjectLiteralExpressionSyntax;

    var SimplePropertyAssignmentSyntax = (function (_super) {
        __extends(SimplePropertyAssignmentSyntax, _super);
        function SimplePropertyAssignmentSyntax(propertyName, colonToken, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.propertyName = propertyName;
            this.colonToken = colonToken;
            this.expression = expression;
        }
        SimplePropertyAssignmentSyntax.prototype.accept = function (visitor) {
            return visitor.visitSimplePropertyAssignment(this);
        };

        SimplePropertyAssignmentSyntax.prototype.kind = function () {
            return 240 /* SimplePropertyAssignment */;
        };

        SimplePropertyAssignmentSyntax.prototype.childCount = function () {
            return 3;
        };

        SimplePropertyAssignmentSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.propertyName;
                case 1:
                    return this.colonToken;
                case 2:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        SimplePropertyAssignmentSyntax.prototype.isPropertyAssignment = function () {
            return true;
        };

        SimplePropertyAssignmentSyntax.prototype.update = function (propertyName, colonToken, expression) {
            if (this.propertyName === propertyName && this.colonToken === colonToken && this.expression === expression) {
                return this;
            }

            return new SimplePropertyAssignmentSyntax(propertyName, colonToken, expression, this.parsedInStrictMode());
        };

        SimplePropertyAssignmentSyntax.create1 = function (propertyName, expression) {
            return new SimplePropertyAssignmentSyntax(propertyName, TypeScript.Syntax.token(106 /* ColonToken */), expression, false);
        };

        SimplePropertyAssignmentSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        SimplePropertyAssignmentSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        SimplePropertyAssignmentSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(propertyName, this.colonToken, this.expression);
        };

        SimplePropertyAssignmentSyntax.prototype.withColonToken = function (colonToken) {
            return this.update(this.propertyName, colonToken, this.expression);
        };

        SimplePropertyAssignmentSyntax.prototype.withExpression = function (expression) {
            return this.update(this.propertyName, this.colonToken, expression);
        };

        SimplePropertyAssignmentSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return SimplePropertyAssignmentSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.SimplePropertyAssignmentSyntax = SimplePropertyAssignmentSyntax;

    var FunctionPropertyAssignmentSyntax = (function (_super) {
        __extends(FunctionPropertyAssignmentSyntax, _super);
        function FunctionPropertyAssignmentSyntax(propertyName, callSignature, block, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.propertyName = propertyName;
            this.callSignature = callSignature;
            this.block = block;
        }
        FunctionPropertyAssignmentSyntax.prototype.accept = function (visitor) {
            return visitor.visitFunctionPropertyAssignment(this);
        };

        FunctionPropertyAssignmentSyntax.prototype.kind = function () {
            return 241 /* FunctionPropertyAssignment */;
        };

        FunctionPropertyAssignmentSyntax.prototype.childCount = function () {
            return 3;
        };

        FunctionPropertyAssignmentSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.propertyName;
                case 1:
                    return this.callSignature;
                case 2:
                    return this.block;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        FunctionPropertyAssignmentSyntax.prototype.isPropertyAssignment = function () {
            return true;
        };

        FunctionPropertyAssignmentSyntax.prototype.update = function (propertyName, callSignature, block) {
            if (this.propertyName === propertyName && this.callSignature === callSignature && this.block === block) {
                return this;
            }

            return new FunctionPropertyAssignmentSyntax(propertyName, callSignature, block, this.parsedInStrictMode());
        };

        FunctionPropertyAssignmentSyntax.create1 = function (propertyName) {
            return new FunctionPropertyAssignmentSyntax(propertyName, CallSignatureSyntax.create1(), BlockSyntax.create1(), false);
        };

        FunctionPropertyAssignmentSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        FunctionPropertyAssignmentSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        FunctionPropertyAssignmentSyntax.prototype.withPropertyName = function (propertyName) {
            return this.update(propertyName, this.callSignature, this.block);
        };

        FunctionPropertyAssignmentSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.propertyName, callSignature, this.block);
        };

        FunctionPropertyAssignmentSyntax.prototype.withBlock = function (block) {
            return this.update(this.propertyName, this.callSignature, block);
        };

        FunctionPropertyAssignmentSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.callSignature.isTypeScriptSpecific()) {
                return true;
            }
            if (this.block.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return FunctionPropertyAssignmentSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.FunctionPropertyAssignmentSyntax = FunctionPropertyAssignmentSyntax;

    var FunctionExpressionSyntax = (function (_super) {
        __extends(FunctionExpressionSyntax, _super);
        function FunctionExpressionSyntax(functionKeyword, identifier, callSignature, block, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.functionKeyword = functionKeyword;
            this.identifier = identifier;
            this.callSignature = callSignature;
            this.block = block;
        }
        FunctionExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitFunctionExpression(this);
        };

        FunctionExpressionSyntax.prototype.kind = function () {
            return 222 /* FunctionExpression */;
        };

        FunctionExpressionSyntax.prototype.childCount = function () {
            return 4;
        };

        FunctionExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.functionKeyword;
                case 1:
                    return this.identifier;
                case 2:
                    return this.callSignature;
                case 3:
                    return this.block;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        FunctionExpressionSyntax.prototype.isPrimaryExpression = function () {
            return true;
        };

        FunctionExpressionSyntax.prototype.isMemberExpression = function () {
            return true;
        };

        FunctionExpressionSyntax.prototype.isPostfixExpression = function () {
            return true;
        };

        FunctionExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        FunctionExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        FunctionExpressionSyntax.prototype.update = function (functionKeyword, identifier, callSignature, block) {
            if (this.functionKeyword === functionKeyword && this.identifier === identifier && this.callSignature === callSignature && this.block === block) {
                return this;
            }

            return new FunctionExpressionSyntax(functionKeyword, identifier, callSignature, block, this.parsedInStrictMode());
        };

        FunctionExpressionSyntax.create = function (functionKeyword, callSignature, block) {
            return new FunctionExpressionSyntax(functionKeyword, null, callSignature, block, false);
        };

        FunctionExpressionSyntax.create1 = function () {
            return new FunctionExpressionSyntax(TypeScript.Syntax.token(27 /* FunctionKeyword */), null, CallSignatureSyntax.create1(), BlockSyntax.create1(), false);
        };

        FunctionExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        FunctionExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        FunctionExpressionSyntax.prototype.withFunctionKeyword = function (functionKeyword) {
            return this.update(functionKeyword, this.identifier, this.callSignature, this.block);
        };

        FunctionExpressionSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.functionKeyword, identifier, this.callSignature, this.block);
        };

        FunctionExpressionSyntax.prototype.withCallSignature = function (callSignature) {
            return this.update(this.functionKeyword, this.identifier, callSignature, this.block);
        };

        FunctionExpressionSyntax.prototype.withBlock = function (block) {
            return this.update(this.functionKeyword, this.identifier, this.callSignature, block);
        };

        FunctionExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.callSignature.isTypeScriptSpecific()) {
                return true;
            }
            if (this.block.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return FunctionExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.FunctionExpressionSyntax = FunctionExpressionSyntax;

    var EmptyStatementSyntax = (function (_super) {
        __extends(EmptyStatementSyntax, _super);
        function EmptyStatementSyntax(semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.semicolonToken = semicolonToken;
        }
        EmptyStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitEmptyStatement(this);
        };

        EmptyStatementSyntax.prototype.kind = function () {
            return 156 /* EmptyStatement */;
        };

        EmptyStatementSyntax.prototype.childCount = function () {
            return 1;
        };

        EmptyStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        EmptyStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        EmptyStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        EmptyStatementSyntax.prototype.update = function (semicolonToken) {
            if (this.semicolonToken === semicolonToken) {
                return this;
            }

            return new EmptyStatementSyntax(semicolonToken, this.parsedInStrictMode());
        };

        EmptyStatementSyntax.create1 = function () {
            return new EmptyStatementSyntax(TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        EmptyStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        EmptyStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        EmptyStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(semicolonToken);
        };

        EmptyStatementSyntax.prototype.isTypeScriptSpecific = function () {
            return false;
        };
        return EmptyStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.EmptyStatementSyntax = EmptyStatementSyntax;

    var TryStatementSyntax = (function (_super) {
        __extends(TryStatementSyntax, _super);
        function TryStatementSyntax(tryKeyword, block, catchClause, finallyClause, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.tryKeyword = tryKeyword;
            this.block = block;
            this.catchClause = catchClause;
            this.finallyClause = finallyClause;
        }
        TryStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitTryStatement(this);
        };

        TryStatementSyntax.prototype.kind = function () {
            return 159 /* TryStatement */;
        };

        TryStatementSyntax.prototype.childCount = function () {
            return 4;
        };

        TryStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.tryKeyword;
                case 1:
                    return this.block;
                case 2:
                    return this.catchClause;
                case 3:
                    return this.finallyClause;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TryStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        TryStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        TryStatementSyntax.prototype.update = function (tryKeyword, block, catchClause, finallyClause) {
            if (this.tryKeyword === tryKeyword && this.block === block && this.catchClause === catchClause && this.finallyClause === finallyClause) {
                return this;
            }

            return new TryStatementSyntax(tryKeyword, block, catchClause, finallyClause, this.parsedInStrictMode());
        };

        TryStatementSyntax.create = function (tryKeyword, block) {
            return new TryStatementSyntax(tryKeyword, block, null, null, false);
        };

        TryStatementSyntax.create1 = function () {
            return new TryStatementSyntax(TypeScript.Syntax.token(38 /* TryKeyword */), BlockSyntax.create1(), null, null, false);
        };

        TryStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TryStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TryStatementSyntax.prototype.withTryKeyword = function (tryKeyword) {
            return this.update(tryKeyword, this.block, this.catchClause, this.finallyClause);
        };

        TryStatementSyntax.prototype.withBlock = function (block) {
            return this.update(this.tryKeyword, block, this.catchClause, this.finallyClause);
        };

        TryStatementSyntax.prototype.withCatchClause = function (catchClause) {
            return this.update(this.tryKeyword, this.block, catchClause, this.finallyClause);
        };

        TryStatementSyntax.prototype.withFinallyClause = function (finallyClause) {
            return this.update(this.tryKeyword, this.block, this.catchClause, finallyClause);
        };

        TryStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.block.isTypeScriptSpecific()) {
                return true;
            }
            if (this.catchClause !== null && this.catchClause.isTypeScriptSpecific()) {
                return true;
            }
            if (this.finallyClause !== null && this.finallyClause.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return TryStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TryStatementSyntax = TryStatementSyntax;

    var CatchClauseSyntax = (function (_super) {
        __extends(CatchClauseSyntax, _super);
        function CatchClauseSyntax(catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.catchKeyword = catchKeyword;
            this.openParenToken = openParenToken;
            this.identifier = identifier;
            this.typeAnnotation = typeAnnotation;
            this.closeParenToken = closeParenToken;
            this.block = block;
        }
        CatchClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitCatchClause(this);
        };

        CatchClauseSyntax.prototype.kind = function () {
            return 236 /* CatchClause */;
        };

        CatchClauseSyntax.prototype.childCount = function () {
            return 6;
        };

        CatchClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.catchKeyword;
                case 1:
                    return this.openParenToken;
                case 2:
                    return this.identifier;
                case 3:
                    return this.typeAnnotation;
                case 4:
                    return this.closeParenToken;
                case 5:
                    return this.block;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        CatchClauseSyntax.prototype.update = function (catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block) {
            if (this.catchKeyword === catchKeyword && this.openParenToken === openParenToken && this.identifier === identifier && this.typeAnnotation === typeAnnotation && this.closeParenToken === closeParenToken && this.block === block) {
                return this;
            }

            return new CatchClauseSyntax(catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block, this.parsedInStrictMode());
        };

        CatchClauseSyntax.create = function (catchKeyword, openParenToken, identifier, closeParenToken, block) {
            return new CatchClauseSyntax(catchKeyword, openParenToken, identifier, null, closeParenToken, block, false);
        };

        CatchClauseSyntax.create1 = function (identifier) {
            return new CatchClauseSyntax(TypeScript.Syntax.token(17 /* CatchKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), identifier, null, TypeScript.Syntax.token(73 /* CloseParenToken */), BlockSyntax.create1(), false);
        };

        CatchClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        CatchClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        CatchClauseSyntax.prototype.withCatchKeyword = function (catchKeyword) {
            return this.update(catchKeyword, this.openParenToken, this.identifier, this.typeAnnotation, this.closeParenToken, this.block);
        };

        CatchClauseSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.catchKeyword, openParenToken, this.identifier, this.typeAnnotation, this.closeParenToken, this.block);
        };

        CatchClauseSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(this.catchKeyword, this.openParenToken, identifier, this.typeAnnotation, this.closeParenToken, this.block);
        };

        CatchClauseSyntax.prototype.withTypeAnnotation = function (typeAnnotation) {
            return this.update(this.catchKeyword, this.openParenToken, this.identifier, typeAnnotation, this.closeParenToken, this.block);
        };

        CatchClauseSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.catchKeyword, this.openParenToken, this.identifier, this.typeAnnotation, closeParenToken, this.block);
        };

        CatchClauseSyntax.prototype.withBlock = function (block) {
            return this.update(this.catchKeyword, this.openParenToken, this.identifier, this.typeAnnotation, this.closeParenToken, block);
        };

        CatchClauseSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.typeAnnotation !== null && this.typeAnnotation.isTypeScriptSpecific()) {
                return true;
            }
            if (this.block.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return CatchClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.CatchClauseSyntax = CatchClauseSyntax;

    var FinallyClauseSyntax = (function (_super) {
        __extends(FinallyClauseSyntax, _super);
        function FinallyClauseSyntax(finallyKeyword, block, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.finallyKeyword = finallyKeyword;
            this.block = block;
        }
        FinallyClauseSyntax.prototype.accept = function (visitor) {
            return visitor.visitFinallyClause(this);
        };

        FinallyClauseSyntax.prototype.kind = function () {
            return 237 /* FinallyClause */;
        };

        FinallyClauseSyntax.prototype.childCount = function () {
            return 2;
        };

        FinallyClauseSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.finallyKeyword;
                case 1:
                    return this.block;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        FinallyClauseSyntax.prototype.update = function (finallyKeyword, block) {
            if (this.finallyKeyword === finallyKeyword && this.block === block) {
                return this;
            }

            return new FinallyClauseSyntax(finallyKeyword, block, this.parsedInStrictMode());
        };

        FinallyClauseSyntax.create1 = function () {
            return new FinallyClauseSyntax(TypeScript.Syntax.token(25 /* FinallyKeyword */), BlockSyntax.create1(), false);
        };

        FinallyClauseSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        FinallyClauseSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        FinallyClauseSyntax.prototype.withFinallyKeyword = function (finallyKeyword) {
            return this.update(finallyKeyword, this.block);
        };

        FinallyClauseSyntax.prototype.withBlock = function (block) {
            return this.update(this.finallyKeyword, block);
        };

        FinallyClauseSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.block.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return FinallyClauseSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.FinallyClauseSyntax = FinallyClauseSyntax;

    var LabeledStatementSyntax = (function (_super) {
        __extends(LabeledStatementSyntax, _super);
        function LabeledStatementSyntax(identifier, colonToken, statement, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.identifier = identifier;
            this.colonToken = colonToken;
            this.statement = statement;
        }
        LabeledStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitLabeledStatement(this);
        };

        LabeledStatementSyntax.prototype.kind = function () {
            return 160 /* LabeledStatement */;
        };

        LabeledStatementSyntax.prototype.childCount = function () {
            return 3;
        };

        LabeledStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.identifier;
                case 1:
                    return this.colonToken;
                case 2:
                    return this.statement;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        LabeledStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        LabeledStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        LabeledStatementSyntax.prototype.update = function (identifier, colonToken, statement) {
            if (this.identifier === identifier && this.colonToken === colonToken && this.statement === statement) {
                return this;
            }

            return new LabeledStatementSyntax(identifier, colonToken, statement, this.parsedInStrictMode());
        };

        LabeledStatementSyntax.create1 = function (identifier, statement) {
            return new LabeledStatementSyntax(identifier, TypeScript.Syntax.token(106 /* ColonToken */), statement, false);
        };

        LabeledStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        LabeledStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        LabeledStatementSyntax.prototype.withIdentifier = function (identifier) {
            return this.update(identifier, this.colonToken, this.statement);
        };

        LabeledStatementSyntax.prototype.withColonToken = function (colonToken) {
            return this.update(this.identifier, colonToken, this.statement);
        };

        LabeledStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.identifier, this.colonToken, statement);
        };

        LabeledStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return LabeledStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.LabeledStatementSyntax = LabeledStatementSyntax;

    var DoStatementSyntax = (function (_super) {
        __extends(DoStatementSyntax, _super);
        function DoStatementSyntax(doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.doKeyword = doKeyword;
            this.statement = statement;
            this.whileKeyword = whileKeyword;
            this.openParenToken = openParenToken;
            this.condition = condition;
            this.closeParenToken = closeParenToken;
            this.semicolonToken = semicolonToken;
        }
        DoStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitDoStatement(this);
        };

        DoStatementSyntax.prototype.kind = function () {
            return 161 /* DoStatement */;
        };

        DoStatementSyntax.prototype.childCount = function () {
            return 7;
        };

        DoStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.doKeyword;
                case 1:
                    return this.statement;
                case 2:
                    return this.whileKeyword;
                case 3:
                    return this.openParenToken;
                case 4:
                    return this.condition;
                case 5:
                    return this.closeParenToken;
                case 6:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        DoStatementSyntax.prototype.isIterationStatement = function () {
            return true;
        };

        DoStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        DoStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        DoStatementSyntax.prototype.update = function (doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken) {
            if (this.doKeyword === doKeyword && this.statement === statement && this.whileKeyword === whileKeyword && this.openParenToken === openParenToken && this.condition === condition && this.closeParenToken === closeParenToken && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new DoStatementSyntax(doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken, this.parsedInStrictMode());
        };

        DoStatementSyntax.create1 = function (statement, condition) {
            return new DoStatementSyntax(TypeScript.Syntax.token(22 /* DoKeyword */), statement, TypeScript.Syntax.token(42 /* WhileKeyword */), TypeScript.Syntax.token(72 /* OpenParenToken */), condition, TypeScript.Syntax.token(73 /* CloseParenToken */), TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        DoStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        DoStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        DoStatementSyntax.prototype.withDoKeyword = function (doKeyword) {
            return this.update(doKeyword, this.statement, this.whileKeyword, this.openParenToken, this.condition, this.closeParenToken, this.semicolonToken);
        };

        DoStatementSyntax.prototype.withStatement = function (statement) {
            return this.update(this.doKeyword, statement, this.whileKeyword, this.openParenToken, this.condition, this.closeParenToken, this.semicolonToken);
        };

        DoStatementSyntax.prototype.withWhileKeyword = function (whileKeyword) {
            return this.update(this.doKeyword, this.statement, whileKeyword, this.openParenToken, this.condition, this.closeParenToken, this.semicolonToken);
        };

        DoStatementSyntax.prototype.withOpenParenToken = function (openParenToken) {
            return this.update(this.doKeyword, this.statement, this.whileKeyword, openParenToken, this.condition, this.closeParenToken, this.semicolonToken);
        };

        DoStatementSyntax.prototype.withCondition = function (condition) {
            return this.update(this.doKeyword, this.statement, this.whileKeyword, this.openParenToken, condition, this.closeParenToken, this.semicolonToken);
        };

        DoStatementSyntax.prototype.withCloseParenToken = function (closeParenToken) {
            return this.update(this.doKeyword, this.statement, this.whileKeyword, this.openParenToken, this.condition, closeParenToken, this.semicolonToken);
        };

        DoStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.doKeyword, this.statement, this.whileKeyword, this.openParenToken, this.condition, this.closeParenToken, semicolonToken);
        };

        DoStatementSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.statement.isTypeScriptSpecific()) {
                return true;
            }
            if (this.condition.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return DoStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.DoStatementSyntax = DoStatementSyntax;

    var TypeOfExpressionSyntax = (function (_super) {
        __extends(TypeOfExpressionSyntax, _super);
        function TypeOfExpressionSyntax(typeOfKeyword, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.typeOfKeyword = typeOfKeyword;
            this.expression = expression;
        }
        TypeOfExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitTypeOfExpression(this);
        };

        TypeOfExpressionSyntax.prototype.kind = function () {
            return 171 /* TypeOfExpression */;
        };

        TypeOfExpressionSyntax.prototype.childCount = function () {
            return 2;
        };

        TypeOfExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.typeOfKeyword;
                case 1:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        TypeOfExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        TypeOfExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        TypeOfExpressionSyntax.prototype.update = function (typeOfKeyword, expression) {
            if (this.typeOfKeyword === typeOfKeyword && this.expression === expression) {
                return this;
            }

            return new TypeOfExpressionSyntax(typeOfKeyword, expression, this.parsedInStrictMode());
        };

        TypeOfExpressionSyntax.create1 = function (expression) {
            return new TypeOfExpressionSyntax(TypeScript.Syntax.token(39 /* TypeOfKeyword */), expression, false);
        };

        TypeOfExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        TypeOfExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        TypeOfExpressionSyntax.prototype.withTypeOfKeyword = function (typeOfKeyword) {
            return this.update(typeOfKeyword, this.expression);
        };

        TypeOfExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.typeOfKeyword, expression);
        };

        TypeOfExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return TypeOfExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.TypeOfExpressionSyntax = TypeOfExpressionSyntax;

    var DeleteExpressionSyntax = (function (_super) {
        __extends(DeleteExpressionSyntax, _super);
        function DeleteExpressionSyntax(deleteKeyword, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.deleteKeyword = deleteKeyword;
            this.expression = expression;
        }
        DeleteExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitDeleteExpression(this);
        };

        DeleteExpressionSyntax.prototype.kind = function () {
            return 170 /* DeleteExpression */;
        };

        DeleteExpressionSyntax.prototype.childCount = function () {
            return 2;
        };

        DeleteExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.deleteKeyword;
                case 1:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        DeleteExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        DeleteExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        DeleteExpressionSyntax.prototype.update = function (deleteKeyword, expression) {
            if (this.deleteKeyword === deleteKeyword && this.expression === expression) {
                return this;
            }

            return new DeleteExpressionSyntax(deleteKeyword, expression, this.parsedInStrictMode());
        };

        DeleteExpressionSyntax.create1 = function (expression) {
            return new DeleteExpressionSyntax(TypeScript.Syntax.token(21 /* DeleteKeyword */), expression, false);
        };

        DeleteExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        DeleteExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        DeleteExpressionSyntax.prototype.withDeleteKeyword = function (deleteKeyword) {
            return this.update(deleteKeyword, this.expression);
        };

        DeleteExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.deleteKeyword, expression);
        };

        DeleteExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return DeleteExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.DeleteExpressionSyntax = DeleteExpressionSyntax;

    var VoidExpressionSyntax = (function (_super) {
        __extends(VoidExpressionSyntax, _super);
        function VoidExpressionSyntax(voidKeyword, expression, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.voidKeyword = voidKeyword;
            this.expression = expression;
        }
        VoidExpressionSyntax.prototype.accept = function (visitor) {
            return visitor.visitVoidExpression(this);
        };

        VoidExpressionSyntax.prototype.kind = function () {
            return 172 /* VoidExpression */;
        };

        VoidExpressionSyntax.prototype.childCount = function () {
            return 2;
        };

        VoidExpressionSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.voidKeyword;
                case 1:
                    return this.expression;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        VoidExpressionSyntax.prototype.isUnaryExpression = function () {
            return true;
        };

        VoidExpressionSyntax.prototype.isExpression = function () {
            return true;
        };

        VoidExpressionSyntax.prototype.update = function (voidKeyword, expression) {
            if (this.voidKeyword === voidKeyword && this.expression === expression) {
                return this;
            }

            return new VoidExpressionSyntax(voidKeyword, expression, this.parsedInStrictMode());
        };

        VoidExpressionSyntax.create1 = function (expression) {
            return new VoidExpressionSyntax(TypeScript.Syntax.token(41 /* VoidKeyword */), expression, false);
        };

        VoidExpressionSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        VoidExpressionSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        VoidExpressionSyntax.prototype.withVoidKeyword = function (voidKeyword) {
            return this.update(voidKeyword, this.expression);
        };

        VoidExpressionSyntax.prototype.withExpression = function (expression) {
            return this.update(this.voidKeyword, expression);
        };

        VoidExpressionSyntax.prototype.isTypeScriptSpecific = function () {
            if (this.expression.isTypeScriptSpecific()) {
                return true;
            }
            return false;
        };
        return VoidExpressionSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.VoidExpressionSyntax = VoidExpressionSyntax;

    var DebuggerStatementSyntax = (function (_super) {
        __extends(DebuggerStatementSyntax, _super);
        function DebuggerStatementSyntax(debuggerKeyword, semicolonToken, parsedInStrictMode) {
            _super.call(this, parsedInStrictMode);
            this.debuggerKeyword = debuggerKeyword;
            this.semicolonToken = semicolonToken;
        }
        DebuggerStatementSyntax.prototype.accept = function (visitor) {
            return visitor.visitDebuggerStatement(this);
        };

        DebuggerStatementSyntax.prototype.kind = function () {
            return 162 /* DebuggerStatement */;
        };

        DebuggerStatementSyntax.prototype.childCount = function () {
            return 2;
        };

        DebuggerStatementSyntax.prototype.childAt = function (slot) {
            switch (slot) {
                case 0:
                    return this.debuggerKeyword;
                case 1:
                    return this.semicolonToken;
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        DebuggerStatementSyntax.prototype.isStatement = function () {
            return true;
        };

        DebuggerStatementSyntax.prototype.isModuleElement = function () {
            return true;
        };

        DebuggerStatementSyntax.prototype.update = function (debuggerKeyword, semicolonToken) {
            if (this.debuggerKeyword === debuggerKeyword && this.semicolonToken === semicolonToken) {
                return this;
            }

            return new DebuggerStatementSyntax(debuggerKeyword, semicolonToken, this.parsedInStrictMode());
        };

        DebuggerStatementSyntax.create1 = function () {
            return new DebuggerStatementSyntax(TypeScript.Syntax.token(19 /* DebuggerKeyword */), TypeScript.Syntax.token(78 /* SemicolonToken */), false);
        };

        DebuggerStatementSyntax.prototype.withLeadingTrivia = function (trivia) {
            return _super.prototype.withLeadingTrivia.call(this, trivia);
        };

        DebuggerStatementSyntax.prototype.withTrailingTrivia = function (trivia) {
            return _super.prototype.withTrailingTrivia.call(this, trivia);
        };

        DebuggerStatementSyntax.prototype.withDebuggerKeyword = function (debuggerKeyword) {
            return this.update(debuggerKeyword, this.semicolonToken);
        };

        DebuggerStatementSyntax.prototype.withSemicolonToken = function (semicolonToken) {
            return this.update(this.debuggerKeyword, semicolonToken);
        };

        DebuggerStatementSyntax.prototype.isTypeScriptSpecific = function () {
            return false;
        };
        return DebuggerStatementSyntax;
    })(TypeScript.SyntaxNode);
    TypeScript.DebuggerStatementSyntax = DebuggerStatementSyntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxRewriter = (function () {
        function SyntaxRewriter() {
        }
        SyntaxRewriter.prototype.visitToken = function (token) {
            return token;
        };

        SyntaxRewriter.prototype.visitNode = function (node) {
            return node.accept(this);
        };

        SyntaxRewriter.prototype.visitNodeOrToken = function (node) {
            return node.isToken() ? this.visitToken(node) : this.visitNode(node);
        };

        SyntaxRewriter.prototype.visitList = function (list) {
            var newItems = null;

            for (var i = 0, n = list.childCount(); i < n; i++) {
                var item = list.childAt(i);
                var newItem = this.visitNodeOrToken(item);

                if (item !== newItem && newItems === null) {
                    newItems = [];
                    for (var j = 0; j < i; j++) {
                        newItems.push(list.childAt(j));
                    }
                }

                if (newItems) {
                    newItems.push(newItem);
                }
            }

            return newItems === null ? list : TypeScript.Syntax.list(newItems);
        };

        SyntaxRewriter.prototype.visitSeparatedList = function (list) {
            var newItems = null;

            for (var i = 0, n = list.childCount(); i < n; i++) {
                var item = list.childAt(i);
                var newItem = item.isToken() ? this.visitToken(item) : this.visitNode(item);

                if (item !== newItem && newItems === null) {
                    newItems = [];
                    for (var j = 0; j < i; j++) {
                        newItems.push(list.childAt(j));
                    }
                }

                if (newItems) {
                    newItems.push(newItem);
                }
            }

            return newItems === null ? list : TypeScript.Syntax.separatedList(newItems);
        };

        SyntaxRewriter.prototype.visitSourceUnit = function (node) {
            return node.update(this.visitList(node.moduleElements), this.visitToken(node.endOfFileToken));
        };

        SyntaxRewriter.prototype.visitExternalModuleReference = function (node) {
            return node.update(this.visitToken(node.requireKeyword), this.visitToken(node.openParenToken), this.visitToken(node.stringLiteral), this.visitToken(node.closeParenToken));
        };

        SyntaxRewriter.prototype.visitModuleNameModuleReference = function (node) {
            return node.update(this.visitNodeOrToken(node.moduleName));
        };

        SyntaxRewriter.prototype.visitImportDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.importKeyword), this.visitToken(node.identifier), this.visitToken(node.equalsToken), this.visitNodeOrToken(node.moduleReference), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitExportAssignment = function (node) {
            return node.update(this.visitToken(node.exportKeyword), this.visitToken(node.equalsToken), this.visitToken(node.identifier), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitClassDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.classKeyword), this.visitToken(node.identifier), node.typeParameterList === null ? null : this.visitNode(node.typeParameterList), this.visitList(node.heritageClauses), this.visitToken(node.openBraceToken), this.visitList(node.classElements), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitInterfaceDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.interfaceKeyword), this.visitToken(node.identifier), node.typeParameterList === null ? null : this.visitNode(node.typeParameterList), this.visitList(node.heritageClauses), this.visitNode(node.body));
        };

        SyntaxRewriter.prototype.visitHeritageClause = function (node) {
            return node.update(node.kind(), this.visitToken(node.extendsOrImplementsKeyword), this.visitSeparatedList(node.typeNames));
        };

        SyntaxRewriter.prototype.visitModuleDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.moduleKeyword), node.name === null ? null : this.visitNodeOrToken(node.name), node.stringLiteral === null ? null : this.visitToken(node.stringLiteral), this.visitToken(node.openBraceToken), this.visitList(node.moduleElements), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitFunctionDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.functionKeyword), this.visitToken(node.identifier), this.visitNode(node.callSignature), node.block === null ? null : this.visitNode(node.block), node.semicolonToken === null ? null : this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitVariableStatement = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitNode(node.variableDeclaration), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitVariableDeclaration = function (node) {
            return node.update(this.visitToken(node.varKeyword), this.visitSeparatedList(node.variableDeclarators));
        };

        SyntaxRewriter.prototype.visitVariableDeclarator = function (node) {
            return node.update(this.visitToken(node.propertyName), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation), node.equalsValueClause === null ? null : this.visitNode(node.equalsValueClause));
        };

        SyntaxRewriter.prototype.visitEqualsValueClause = function (node) {
            return node.update(this.visitToken(node.equalsToken), this.visitNodeOrToken(node.value));
        };

        SyntaxRewriter.prototype.visitPrefixUnaryExpression = function (node) {
            return node.update(node.kind(), this.visitToken(node.operatorToken), this.visitNodeOrToken(node.operand));
        };

        SyntaxRewriter.prototype.visitArrayLiteralExpression = function (node) {
            return node.update(this.visitToken(node.openBracketToken), this.visitSeparatedList(node.expressions), this.visitToken(node.closeBracketToken));
        };

        SyntaxRewriter.prototype.visitOmittedExpression = function (node) {
            return node;
        };

        SyntaxRewriter.prototype.visitParenthesizedExpression = function (node) {
            return node.update(this.visitToken(node.openParenToken), this.visitNodeOrToken(node.expression), this.visitToken(node.closeParenToken));
        };

        SyntaxRewriter.prototype.visitSimpleArrowFunctionExpression = function (node) {
            return node.update(this.visitToken(node.identifier), this.visitToken(node.equalsGreaterThanToken), node.block === null ? null : this.visitNode(node.block), node.expression === null ? null : this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitParenthesizedArrowFunctionExpression = function (node) {
            return node.update(this.visitNode(node.callSignature), this.visitToken(node.equalsGreaterThanToken), node.block === null ? null : this.visitNode(node.block), node.expression === null ? null : this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitQualifiedName = function (node) {
            return node.update(this.visitNodeOrToken(node.left), this.visitToken(node.dotToken), this.visitToken(node.right));
        };

        SyntaxRewriter.prototype.visitTypeArgumentList = function (node) {
            return node.update(this.visitToken(node.lessThanToken), this.visitSeparatedList(node.typeArguments), this.visitToken(node.greaterThanToken));
        };

        SyntaxRewriter.prototype.visitConstructorType = function (node) {
            return node.update(this.visitToken(node.newKeyword), node.typeParameterList === null ? null : this.visitNode(node.typeParameterList), this.visitNode(node.parameterList), this.visitToken(node.equalsGreaterThanToken), this.visitNodeOrToken(node.type));
        };

        SyntaxRewriter.prototype.visitFunctionType = function (node) {
            return node.update(node.typeParameterList === null ? null : this.visitNode(node.typeParameterList), this.visitNode(node.parameterList), this.visitToken(node.equalsGreaterThanToken), this.visitNodeOrToken(node.type));
        };

        SyntaxRewriter.prototype.visitObjectType = function (node) {
            return node.update(this.visitToken(node.openBraceToken), this.visitSeparatedList(node.typeMembers), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitArrayType = function (node) {
            return node.update(this.visitNodeOrToken(node.type), this.visitToken(node.openBracketToken), this.visitToken(node.closeBracketToken));
        };

        SyntaxRewriter.prototype.visitGenericType = function (node) {
            return node.update(this.visitNodeOrToken(node.name), this.visitNode(node.typeArgumentList));
        };

        SyntaxRewriter.prototype.visitTypeQuery = function (node) {
            return node.update(this.visitToken(node.typeOfKeyword), this.visitNodeOrToken(node.name));
        };

        SyntaxRewriter.prototype.visitTypeAnnotation = function (node) {
            return node.update(this.visitToken(node.colonToken), this.visitNodeOrToken(node.type));
        };

        SyntaxRewriter.prototype.visitBlock = function (node) {
            return node.update(this.visitToken(node.openBraceToken), this.visitList(node.statements), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitParameter = function (node) {
            return node.update(node.dotDotDotToken === null ? null : this.visitToken(node.dotDotDotToken), this.visitList(node.modifiers), this.visitToken(node.identifier), node.questionToken === null ? null : this.visitToken(node.questionToken), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation), node.equalsValueClause === null ? null : this.visitNode(node.equalsValueClause));
        };

        SyntaxRewriter.prototype.visitMemberAccessExpression = function (node) {
            return node.update(this.visitNodeOrToken(node.expression), this.visitToken(node.dotToken), this.visitToken(node.name));
        };

        SyntaxRewriter.prototype.visitPostfixUnaryExpression = function (node) {
            return node.update(node.kind(), this.visitNodeOrToken(node.operand), this.visitToken(node.operatorToken));
        };

        SyntaxRewriter.prototype.visitElementAccessExpression = function (node) {
            return node.update(this.visitNodeOrToken(node.expression), this.visitToken(node.openBracketToken), this.visitNodeOrToken(node.argumentExpression), this.visitToken(node.closeBracketToken));
        };

        SyntaxRewriter.prototype.visitInvocationExpression = function (node) {
            return node.update(this.visitNodeOrToken(node.expression), this.visitNode(node.argumentList));
        };

        SyntaxRewriter.prototype.visitArgumentList = function (node) {
            return node.update(node.typeArgumentList === null ? null : this.visitNode(node.typeArgumentList), this.visitToken(node.openParenToken), this.visitSeparatedList(node.arguments), this.visitToken(node.closeParenToken));
        };

        SyntaxRewriter.prototype.visitBinaryExpression = function (node) {
            return node.update(node.kind(), this.visitNodeOrToken(node.left), this.visitToken(node.operatorToken), this.visitNodeOrToken(node.right));
        };

        SyntaxRewriter.prototype.visitConditionalExpression = function (node) {
            return node.update(this.visitNodeOrToken(node.condition), this.visitToken(node.questionToken), this.visitNodeOrToken(node.whenTrue), this.visitToken(node.colonToken), this.visitNodeOrToken(node.whenFalse));
        };

        SyntaxRewriter.prototype.visitConstructSignature = function (node) {
            return node.update(this.visitToken(node.newKeyword), this.visitNode(node.callSignature));
        };

        SyntaxRewriter.prototype.visitMethodSignature = function (node) {
            return node.update(this.visitToken(node.propertyName), node.questionToken === null ? null : this.visitToken(node.questionToken), this.visitNode(node.callSignature));
        };

        SyntaxRewriter.prototype.visitIndexSignature = function (node) {
            return node.update(this.visitToken(node.openBracketToken), this.visitNode(node.parameter), this.visitToken(node.closeBracketToken), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation));
        };

        SyntaxRewriter.prototype.visitPropertySignature = function (node) {
            return node.update(this.visitToken(node.propertyName), node.questionToken === null ? null : this.visitToken(node.questionToken), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation));
        };

        SyntaxRewriter.prototype.visitCallSignature = function (node) {
            return node.update(node.typeParameterList === null ? null : this.visitNode(node.typeParameterList), this.visitNode(node.parameterList), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation));
        };

        SyntaxRewriter.prototype.visitParameterList = function (node) {
            return node.update(this.visitToken(node.openParenToken), this.visitSeparatedList(node.parameters), this.visitToken(node.closeParenToken));
        };

        SyntaxRewriter.prototype.visitTypeParameterList = function (node) {
            return node.update(this.visitToken(node.lessThanToken), this.visitSeparatedList(node.typeParameters), this.visitToken(node.greaterThanToken));
        };

        SyntaxRewriter.prototype.visitTypeParameter = function (node) {
            return node.update(this.visitToken(node.identifier), node.constraint === null ? null : this.visitNode(node.constraint));
        };

        SyntaxRewriter.prototype.visitConstraint = function (node) {
            return node.update(this.visitToken(node.extendsKeyword), this.visitNodeOrToken(node.type));
        };

        SyntaxRewriter.prototype.visitElseClause = function (node) {
            return node.update(this.visitToken(node.elseKeyword), this.visitNodeOrToken(node.statement));
        };

        SyntaxRewriter.prototype.visitIfStatement = function (node) {
            return node.update(this.visitToken(node.ifKeyword), this.visitToken(node.openParenToken), this.visitNodeOrToken(node.condition), this.visitToken(node.closeParenToken), this.visitNodeOrToken(node.statement), node.elseClause === null ? null : this.visitNode(node.elseClause));
        };

        SyntaxRewriter.prototype.visitExpressionStatement = function (node) {
            return node.update(this.visitNodeOrToken(node.expression), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitConstructorDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.constructorKeyword), this.visitNode(node.callSignature), node.block === null ? null : this.visitNode(node.block), node.semicolonToken === null ? null : this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitMemberFunctionDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.propertyName), this.visitNode(node.callSignature), node.block === null ? null : this.visitNode(node.block), node.semicolonToken === null ? null : this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitGetAccessor = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.getKeyword), this.visitToken(node.propertyName), this.visitNode(node.parameterList), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation), this.visitNode(node.block));
        };

        SyntaxRewriter.prototype.visitSetAccessor = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.setKeyword), this.visitToken(node.propertyName), this.visitNode(node.parameterList), this.visitNode(node.block));
        };

        SyntaxRewriter.prototype.visitMemberVariableDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitNode(node.variableDeclarator), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitIndexMemberDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitNode(node.indexSignature), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitThrowStatement = function (node) {
            return node.update(this.visitToken(node.throwKeyword), this.visitNodeOrToken(node.expression), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitReturnStatement = function (node) {
            return node.update(this.visitToken(node.returnKeyword), node.expression === null ? null : this.visitNodeOrToken(node.expression), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitObjectCreationExpression = function (node) {
            return node.update(this.visitToken(node.newKeyword), this.visitNodeOrToken(node.expression), node.argumentList === null ? null : this.visitNode(node.argumentList));
        };

        SyntaxRewriter.prototype.visitSwitchStatement = function (node) {
            return node.update(this.visitToken(node.switchKeyword), this.visitToken(node.openParenToken), this.visitNodeOrToken(node.expression), this.visitToken(node.closeParenToken), this.visitToken(node.openBraceToken), this.visitList(node.switchClauses), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitCaseSwitchClause = function (node) {
            return node.update(this.visitToken(node.caseKeyword), this.visitNodeOrToken(node.expression), this.visitToken(node.colonToken), this.visitList(node.statements));
        };

        SyntaxRewriter.prototype.visitDefaultSwitchClause = function (node) {
            return node.update(this.visitToken(node.defaultKeyword), this.visitToken(node.colonToken), this.visitList(node.statements));
        };

        SyntaxRewriter.prototype.visitBreakStatement = function (node) {
            return node.update(this.visitToken(node.breakKeyword), node.identifier === null ? null : this.visitToken(node.identifier), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitContinueStatement = function (node) {
            return node.update(this.visitToken(node.continueKeyword), node.identifier === null ? null : this.visitToken(node.identifier), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitForStatement = function (node) {
            return node.update(this.visitToken(node.forKeyword), this.visitToken(node.openParenToken), node.variableDeclaration === null ? null : this.visitNode(node.variableDeclaration), node.initializer === null ? null : this.visitNodeOrToken(node.initializer), this.visitToken(node.firstSemicolonToken), node.condition === null ? null : this.visitNodeOrToken(node.condition), this.visitToken(node.secondSemicolonToken), node.incrementor === null ? null : this.visitNodeOrToken(node.incrementor), this.visitToken(node.closeParenToken), this.visitNodeOrToken(node.statement));
        };

        SyntaxRewriter.prototype.visitForInStatement = function (node) {
            return node.update(this.visitToken(node.forKeyword), this.visitToken(node.openParenToken), node.variableDeclaration === null ? null : this.visitNode(node.variableDeclaration), node.left === null ? null : this.visitNodeOrToken(node.left), this.visitToken(node.inKeyword), this.visitNodeOrToken(node.expression), this.visitToken(node.closeParenToken), this.visitNodeOrToken(node.statement));
        };

        SyntaxRewriter.prototype.visitWhileStatement = function (node) {
            return node.update(this.visitToken(node.whileKeyword), this.visitToken(node.openParenToken), this.visitNodeOrToken(node.condition), this.visitToken(node.closeParenToken), this.visitNodeOrToken(node.statement));
        };

        SyntaxRewriter.prototype.visitWithStatement = function (node) {
            return node.update(this.visitToken(node.withKeyword), this.visitToken(node.openParenToken), this.visitNodeOrToken(node.condition), this.visitToken(node.closeParenToken), this.visitNodeOrToken(node.statement));
        };

        SyntaxRewriter.prototype.visitEnumDeclaration = function (node) {
            return node.update(this.visitList(node.modifiers), this.visitToken(node.enumKeyword), this.visitToken(node.identifier), this.visitToken(node.openBraceToken), this.visitSeparatedList(node.enumElements), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitEnumElement = function (node) {
            return node.update(this.visitToken(node.propertyName), node.equalsValueClause === null ? null : this.visitNode(node.equalsValueClause));
        };

        SyntaxRewriter.prototype.visitCastExpression = function (node) {
            return node.update(this.visitToken(node.lessThanToken), this.visitNodeOrToken(node.type), this.visitToken(node.greaterThanToken), this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitObjectLiteralExpression = function (node) {
            return node.update(this.visitToken(node.openBraceToken), this.visitSeparatedList(node.propertyAssignments), this.visitToken(node.closeBraceToken));
        };

        SyntaxRewriter.prototype.visitSimplePropertyAssignment = function (node) {
            return node.update(this.visitToken(node.propertyName), this.visitToken(node.colonToken), this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitFunctionPropertyAssignment = function (node) {
            return node.update(this.visitToken(node.propertyName), this.visitNode(node.callSignature), this.visitNode(node.block));
        };

        SyntaxRewriter.prototype.visitFunctionExpression = function (node) {
            return node.update(this.visitToken(node.functionKeyword), node.identifier === null ? null : this.visitToken(node.identifier), this.visitNode(node.callSignature), this.visitNode(node.block));
        };

        SyntaxRewriter.prototype.visitEmptyStatement = function (node) {
            return node.update(this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitTryStatement = function (node) {
            return node.update(this.visitToken(node.tryKeyword), this.visitNode(node.block), node.catchClause === null ? null : this.visitNode(node.catchClause), node.finallyClause === null ? null : this.visitNode(node.finallyClause));
        };

        SyntaxRewriter.prototype.visitCatchClause = function (node) {
            return node.update(this.visitToken(node.catchKeyword), this.visitToken(node.openParenToken), this.visitToken(node.identifier), node.typeAnnotation === null ? null : this.visitNode(node.typeAnnotation), this.visitToken(node.closeParenToken), this.visitNode(node.block));
        };

        SyntaxRewriter.prototype.visitFinallyClause = function (node) {
            return node.update(this.visitToken(node.finallyKeyword), this.visitNode(node.block));
        };

        SyntaxRewriter.prototype.visitLabeledStatement = function (node) {
            return node.update(this.visitToken(node.identifier), this.visitToken(node.colonToken), this.visitNodeOrToken(node.statement));
        };

        SyntaxRewriter.prototype.visitDoStatement = function (node) {
            return node.update(this.visitToken(node.doKeyword), this.visitNodeOrToken(node.statement), this.visitToken(node.whileKeyword), this.visitToken(node.openParenToken), this.visitNodeOrToken(node.condition), this.visitToken(node.closeParenToken), this.visitToken(node.semicolonToken));
        };

        SyntaxRewriter.prototype.visitTypeOfExpression = function (node) {
            return node.update(this.visitToken(node.typeOfKeyword), this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitDeleteExpression = function (node) {
            return node.update(this.visitToken(node.deleteKeyword), this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitVoidExpression = function (node) {
            return node.update(this.visitToken(node.voidKeyword), this.visitNodeOrToken(node.expression));
        };

        SyntaxRewriter.prototype.visitDebuggerStatement = function (node) {
            return node.update(this.visitToken(node.debuggerKeyword), this.visitToken(node.semicolonToken));
        };
        return SyntaxRewriter;
    })();
    TypeScript.SyntaxRewriter = SyntaxRewriter;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxDedenter = (function (_super) {
        __extends(SyntaxDedenter, _super);
        function SyntaxDedenter(dedentFirstToken, dedentationAmount, minimumIndent, options) {
            _super.call(this);
            this.dedentationAmount = dedentationAmount;
            this.minimumIndent = minimumIndent;
            this.options = options;
            this.lastTriviaWasNewLine = dedentFirstToken;
        }
        SyntaxDedenter.prototype.abort = function () {
            this.lastTriviaWasNewLine = false;
            this.dedentationAmount = 0;
        };

        SyntaxDedenter.prototype.isAborted = function () {
            return this.dedentationAmount === 0;
        };

        SyntaxDedenter.prototype.visitToken = function (token) {
            if (token.width() === 0) {
                return token;
            }

            var result = token;
            if (this.lastTriviaWasNewLine) {
                result = token.withLeadingTrivia(this.dedentTriviaList(token.leadingTrivia()));
            }

            if (this.isAborted()) {
                return token;
            }

            this.lastTriviaWasNewLine = token.hasTrailingNewLine();
            return result;
        };

        SyntaxDedenter.prototype.dedentTriviaList = function (triviaList) {
            var result = [];
            var dedentNextWhitespace = true;

            for (var i = 0, n = triviaList.count(); i < n && !this.isAborted(); i++) {
                var trivia = triviaList.syntaxTriviaAt(i);

                var dedentThisTrivia = dedentNextWhitespace;
                dedentNextWhitespace = false;

                if (dedentThisTrivia) {
                    if (trivia.kind() === 4 /* WhitespaceTrivia */) {
                        var hasFollowingNewLine = (i < triviaList.count() - 1) && triviaList.syntaxTriviaAt(i + 1).kind() === 5 /* NewLineTrivia */;
                        result.push(this.dedentWhitespace(trivia, hasFollowingNewLine));
                        continue;
                    } else if (trivia.kind() !== 5 /* NewLineTrivia */) {
                        this.abort();
                        break;
                    }
                }

                if (trivia.kind() === 6 /* MultiLineCommentTrivia */) {
                    result.push(this.dedentMultiLineComment(trivia));
                    continue;
                }

                result.push(trivia);
                if (trivia.kind() === 5 /* NewLineTrivia */) {
                    dedentNextWhitespace = true;
                }
            }

            if (dedentNextWhitespace) {
                this.abort();
            }

            if (this.isAborted()) {
                return triviaList;
            }

            return TypeScript.Syntax.triviaList(result);
        };

        SyntaxDedenter.prototype.dedentSegment = function (segment, hasFollowingNewLineTrivia) {
            var firstNonWhitespacePosition = TypeScript.Indentation.firstNonWhitespacePosition(segment);

            if (firstNonWhitespacePosition === segment.length) {
                if (hasFollowingNewLineTrivia) {
                    return "";
                }
            } else if (TypeScript.CharacterInfo.isLineTerminator(segment.charCodeAt(firstNonWhitespacePosition))) {
                return segment.substring(firstNonWhitespacePosition);
            }

            var firstNonWhitespaceColumn = TypeScript.Indentation.columnForPositionInString(segment, firstNonWhitespacePosition, this.options);

            var newFirstNonWhitespaceColumn = TypeScript.MathPrototype.min(firstNonWhitespaceColumn, TypeScript.MathPrototype.max(firstNonWhitespaceColumn - this.dedentationAmount, this.minimumIndent));

            if (newFirstNonWhitespaceColumn === firstNonWhitespaceColumn) {
                this.abort();
                return segment;
            }

            this.dedentationAmount = firstNonWhitespaceColumn - newFirstNonWhitespaceColumn;
            TypeScript.Debug.assert(this.dedentationAmount >= 0);

            var indentationString = TypeScript.Indentation.indentationString(newFirstNonWhitespaceColumn, this.options);

            return indentationString + segment.substring(firstNonWhitespacePosition);
        };

        SyntaxDedenter.prototype.dedentWhitespace = function (trivia, hasFollowingNewLineTrivia) {
            var newIndentation = this.dedentSegment(trivia.fullText(), hasFollowingNewLineTrivia);
            return TypeScript.Syntax.whitespace(newIndentation);
        };

        SyntaxDedenter.prototype.dedentMultiLineComment = function (trivia) {
            var segments = TypeScript.Syntax.splitMultiLineCommentTriviaIntoMultipleLines(trivia);
            if (segments.length === 1) {
                return trivia;
            }

            for (var i = 1; i < segments.length; i++) {
                var segment = segments[i];
                segments[i] = this.dedentSegment(segment, false);
            }

            var result = segments.join("");

            return TypeScript.Syntax.multiLineComment(result);
        };

        SyntaxDedenter.dedentNode = function (node, dedentFirstToken, dedentAmount, minimumIndent, options) {
            var dedenter = new SyntaxDedenter(dedentFirstToken, dedentAmount, minimumIndent, options);
            var result = node.accept(dedenter);

            if (dedenter.isAborted()) {
                return node;
            }

            return result;
        };
        return SyntaxDedenter;
    })(TypeScript.SyntaxRewriter);
    TypeScript.SyntaxDedenter = SyntaxDedenter;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxIndenter = (function (_super) {
        __extends(SyntaxIndenter, _super);
        function SyntaxIndenter(indentFirstToken, indentationAmount, options) {
            _super.call(this);
            this.indentationAmount = indentationAmount;
            this.options = options;
            this.lastTriviaWasNewLine = indentFirstToken;
            this.indentationTrivia = TypeScript.Indentation.indentationTrivia(this.indentationAmount, this.options);
        }
        SyntaxIndenter.prototype.visitToken = function (token) {
            if (token.width() === 0) {
                return token;
            }

            var result = token;
            if (this.lastTriviaWasNewLine) {
                result = token.withLeadingTrivia(this.indentTriviaList(token.leadingTrivia()));
            }

            this.lastTriviaWasNewLine = token.hasTrailingNewLine();
            return result;
        };

        SyntaxIndenter.prototype.indentTriviaList = function (triviaList) {
            var result = [];

            var indentNextTrivia = true;
            for (var i = 0, n = triviaList.count(); i < n; i++) {
                var trivia = triviaList.syntaxTriviaAt(i);

                var indentThisTrivia = indentNextTrivia;
                indentNextTrivia = false;

                switch (trivia.kind()) {
                    case 6 /* MultiLineCommentTrivia */:
                        this.indentMultiLineComment(trivia, indentThisTrivia, result);
                        continue;

                    case 7 /* SingleLineCommentTrivia */:
                    case 8 /* SkippedTokenTrivia */:
                        this.indentSingleLineOrSkippedText(trivia, indentThisTrivia, result);
                        continue;

                    case 4 /* WhitespaceTrivia */:
                        this.indentWhitespace(trivia, indentThisTrivia, result);
                        continue;

                    case 5 /* NewLineTrivia */:
                        result.push(trivia);
                        indentNextTrivia = true;
                        continue;

                    default:
                        throw TypeScript.Errors.invalidOperation();
                }
            }

            if (indentNextTrivia) {
                result.push(this.indentationTrivia);
            }

            return TypeScript.Syntax.triviaList(result);
        };

        SyntaxIndenter.prototype.indentSegment = function (segment) {
            var firstNonWhitespacePosition = TypeScript.Indentation.firstNonWhitespacePosition(segment);

            if (firstNonWhitespacePosition < segment.length && TypeScript.CharacterInfo.isLineTerminator(segment.charCodeAt(firstNonWhitespacePosition))) {
                return segment;
            }

            var firstNonWhitespaceColumn = TypeScript.Indentation.columnForPositionInString(segment, firstNonWhitespacePosition, this.options);

            var newFirstNonWhitespaceColumn = firstNonWhitespaceColumn + this.indentationAmount;

            var indentationString = TypeScript.Indentation.indentationString(newFirstNonWhitespaceColumn, this.options);

            return indentationString + segment.substring(firstNonWhitespacePosition);
        };

        SyntaxIndenter.prototype.indentWhitespace = function (trivia, indentThisTrivia, result) {
            if (!indentThisTrivia) {
                result.push(trivia);
                return;
            }

            var newIndentation = this.indentSegment(trivia.fullText());
            result.push(TypeScript.Syntax.whitespace(newIndentation));
        };

        SyntaxIndenter.prototype.indentSingleLineOrSkippedText = function (trivia, indentThisTrivia, result) {
            if (indentThisTrivia) {
                result.push(this.indentationTrivia);
            }

            result.push(trivia);
        };

        SyntaxIndenter.prototype.indentMultiLineComment = function (trivia, indentThisTrivia, result) {
            if (indentThisTrivia) {
                result.push(this.indentationTrivia);
            }

            var segments = TypeScript.Syntax.splitMultiLineCommentTriviaIntoMultipleLines(trivia);

            for (var i = 1; i < segments.length; i++) {
                segments[i] = this.indentSegment(segments[i]);
            }

            var newText = segments.join("");
            result.push(TypeScript.Syntax.multiLineComment(newText));
        };

        SyntaxIndenter.indentNode = function (node, indentFirstToken, indentAmount, options) {
            var indenter = new SyntaxIndenter(indentFirstToken, indentAmount, options);
            return node.accept(indenter);
        };

        SyntaxIndenter.indentNodes = function (nodes, indentFirstToken, indentAmount, options) {
            var indenter = new SyntaxIndenter(indentFirstToken, indentAmount, options);
            var result = TypeScript.ArrayUtilities.select(nodes, function (n) {
                return n.accept(indenter);
            });

            return result;
        };
        return SyntaxIndenter;
    })(TypeScript.SyntaxRewriter);
    TypeScript.SyntaxIndenter = SyntaxIndenter;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        var VariableWidthTokenWithNoTrivia = (function () {
            function VariableWidthTokenWithNoTrivia(fullText, kind) {
                this._fullText = fullText;
                this.tokenKind = kind;
            }
            VariableWidthTokenWithNoTrivia.prototype.clone = function () {
                return new VariableWidthTokenWithNoTrivia(this._fullText, this.tokenKind);
            };

            VariableWidthTokenWithNoTrivia.prototype.isNode = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.isToken = function () {
                return true;
            };
            VariableWidthTokenWithNoTrivia.prototype.isList = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            VariableWidthTokenWithNoTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            VariableWidthTokenWithNoTrivia.prototype.childCount = function () {
                return 0;
            };
            VariableWidthTokenWithNoTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            VariableWidthTokenWithNoTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            VariableWidthTokenWithNoTrivia.prototype.width = function () {
                return this.fullWidth() - this.leadingTriviaWidth() - this.trailingTriviaWidth();
            };

            VariableWidthTokenWithNoTrivia.prototype.text = function () {
                return this.fullText().substr(this.leadingTriviaWidth(), this.width());
            };
            VariableWidthTokenWithNoTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            VariableWidthTokenWithNoTrivia.prototype.value = function () {
                if (this._value === undefined) {
                    this._value = Syntax.value(this);
                }

                return this._value;
            };

            VariableWidthTokenWithNoTrivia.prototype.valueText = function () {
                if (this._valueText === undefined) {
                    this._valueText = Syntax.valueText(this);
                }

                return this._valueText;
            };

            VariableWidthTokenWithNoTrivia.prototype.hasLeadingTrivia = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.hasLeadingComment = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.hasLeadingNewLine = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.leadingTriviaWidth = function () {
                return 0;
            };
            VariableWidthTokenWithNoTrivia.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            VariableWidthTokenWithNoTrivia.prototype.hasTrailingTrivia = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.hasTrailingComment = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.hasTrailingNewLine = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.trailingTriviaWidth = function () {
                return 0;
            };
            VariableWidthTokenWithNoTrivia.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            VariableWidthTokenWithNoTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            VariableWidthTokenWithNoTrivia.prototype.firstToken = function () {
                return this;
            };
            VariableWidthTokenWithNoTrivia.prototype.lastToken = function () {
                return this;
            };
            VariableWidthTokenWithNoTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            VariableWidthTokenWithNoTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            VariableWidthTokenWithNoTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            VariableWidthTokenWithNoTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            VariableWidthTokenWithNoTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            VariableWidthTokenWithNoTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            VariableWidthTokenWithNoTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            VariableWidthTokenWithNoTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            VariableWidthTokenWithNoTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            VariableWidthTokenWithNoTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithNoTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithNoTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithNoTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return VariableWidthTokenWithNoTrivia;
        })();
        Syntax.VariableWidthTokenWithNoTrivia = VariableWidthTokenWithNoTrivia;

        var VariableWidthTokenWithLeadingTrivia = (function () {
            function VariableWidthTokenWithLeadingTrivia(fullText, kind, leadingTriviaInfo) {
                this._fullText = fullText;
                this.tokenKind = kind;
                this._leadingTriviaInfo = leadingTriviaInfo;
            }
            VariableWidthTokenWithLeadingTrivia.prototype.clone = function () {
                return new VariableWidthTokenWithLeadingTrivia(this._fullText, this.tokenKind, this._leadingTriviaInfo);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.isNode = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.isToken = function () {
                return true;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.isList = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            VariableWidthTokenWithLeadingTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            VariableWidthTokenWithLeadingTrivia.prototype.childCount = function () {
                return 0;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            VariableWidthTokenWithLeadingTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.width = function () {
                return this.fullWidth() - this.leadingTriviaWidth() - this.trailingTriviaWidth();
            };

            VariableWidthTokenWithLeadingTrivia.prototype.text = function () {
                return this.fullText().substr(this.leadingTriviaWidth(), this.width());
            };
            VariableWidthTokenWithLeadingTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            VariableWidthTokenWithLeadingTrivia.prototype.value = function () {
                if (this._value === undefined) {
                    this._value = Syntax.value(this);
                }

                return this._value;
            };

            VariableWidthTokenWithLeadingTrivia.prototype.valueText = function () {
                if (this._valueText === undefined) {
                    this._valueText = Syntax.valueText(this);
                }

                return this._valueText;
            };

            VariableWidthTokenWithLeadingTrivia.prototype.hasLeadingTrivia = function () {
                return true;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.hasLeadingComment = function () {
                return hasTriviaComment(this._leadingTriviaInfo);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.hasLeadingNewLine = function () {
                return hasTriviaNewLine(this._leadingTriviaInfo);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.leadingTriviaWidth = function () {
                return getTriviaWidth(this._leadingTriviaInfo);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.leadingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), 0, getTriviaWidth(this._leadingTriviaInfo), false);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.hasTrailingTrivia = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.hasTrailingComment = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.hasTrailingNewLine = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.trailingTriviaWidth = function () {
                return 0;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            VariableWidthTokenWithLeadingTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.firstToken = function () {
                return this;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.lastToken = function () {
                return this;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            VariableWidthTokenWithLeadingTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            VariableWidthTokenWithLeadingTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            VariableWidthTokenWithLeadingTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithLeadingTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithLeadingTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithLeadingTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return VariableWidthTokenWithLeadingTrivia;
        })();
        Syntax.VariableWidthTokenWithLeadingTrivia = VariableWidthTokenWithLeadingTrivia;

        var VariableWidthTokenWithTrailingTrivia = (function () {
            function VariableWidthTokenWithTrailingTrivia(fullText, kind, trailingTriviaInfo) {
                this._fullText = fullText;
                this.tokenKind = kind;
                this._trailingTriviaInfo = trailingTriviaInfo;
            }
            VariableWidthTokenWithTrailingTrivia.prototype.clone = function () {
                return new VariableWidthTokenWithTrailingTrivia(this._fullText, this.tokenKind, this._trailingTriviaInfo);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.isNode = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.isToken = function () {
                return true;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.isList = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            VariableWidthTokenWithTrailingTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            VariableWidthTokenWithTrailingTrivia.prototype.childCount = function () {
                return 0;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            VariableWidthTokenWithTrailingTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.width = function () {
                return this.fullWidth() - this.leadingTriviaWidth() - this.trailingTriviaWidth();
            };

            VariableWidthTokenWithTrailingTrivia.prototype.text = function () {
                return this.fullText().substr(this.leadingTriviaWidth(), this.width());
            };
            VariableWidthTokenWithTrailingTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            VariableWidthTokenWithTrailingTrivia.prototype.value = function () {
                if (this._value === undefined) {
                    this._value = Syntax.value(this);
                }

                return this._value;
            };

            VariableWidthTokenWithTrailingTrivia.prototype.valueText = function () {
                if (this._valueText === undefined) {
                    this._valueText = Syntax.valueText(this);
                }

                return this._valueText;
            };

            VariableWidthTokenWithTrailingTrivia.prototype.hasLeadingTrivia = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.hasLeadingComment = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.hasLeadingNewLine = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.leadingTriviaWidth = function () {
                return 0;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            VariableWidthTokenWithTrailingTrivia.prototype.hasTrailingTrivia = function () {
                return true;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.hasTrailingComment = function () {
                return hasTriviaComment(this._trailingTriviaInfo);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.hasTrailingNewLine = function () {
                return hasTriviaNewLine(this._trailingTriviaInfo);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.trailingTriviaWidth = function () {
                return getTriviaWidth(this._trailingTriviaInfo);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.trailingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), this.leadingTriviaWidth() + this.width(), getTriviaWidth(this._trailingTriviaInfo), true);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.firstToken = function () {
                return this;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.lastToken = function () {
                return this;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            VariableWidthTokenWithTrailingTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            VariableWidthTokenWithTrailingTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            VariableWidthTokenWithTrailingTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithTrailingTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithTrailingTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithTrailingTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return VariableWidthTokenWithTrailingTrivia;
        })();
        Syntax.VariableWidthTokenWithTrailingTrivia = VariableWidthTokenWithTrailingTrivia;

        var VariableWidthTokenWithLeadingAndTrailingTrivia = (function () {
            function VariableWidthTokenWithLeadingAndTrailingTrivia(fullText, kind, leadingTriviaInfo, trailingTriviaInfo) {
                this._fullText = fullText;
                this.tokenKind = kind;
                this._leadingTriviaInfo = leadingTriviaInfo;
                this._trailingTriviaInfo = trailingTriviaInfo;
            }
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.clone = function () {
                return new VariableWidthTokenWithLeadingAndTrailingTrivia(this._fullText, this.tokenKind, this._leadingTriviaInfo, this._trailingTriviaInfo);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isNode = function () {
                return false;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isToken = function () {
                return true;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isList = function () {
                return false;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.childCount = function () {
                return 0;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.width = function () {
                return this.fullWidth() - this.leadingTriviaWidth() - this.trailingTriviaWidth();
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.text = function () {
                return this.fullText().substr(this.leadingTriviaWidth(), this.width());
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.value = function () {
                if (this._value === undefined) {
                    this._value = Syntax.value(this);
                }

                return this._value;
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.valueText = function () {
                if (this._valueText === undefined) {
                    this._valueText = Syntax.valueText(this);
                }

                return this._valueText;
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingTrivia = function () {
                return true;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingComment = function () {
                return hasTriviaComment(this._leadingTriviaInfo);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingNewLine = function () {
                return hasTriviaNewLine(this._leadingTriviaInfo);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.leadingTriviaWidth = function () {
                return getTriviaWidth(this._leadingTriviaInfo);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.leadingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), 0, getTriviaWidth(this._leadingTriviaInfo), false);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingTrivia = function () {
                return true;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingComment = function () {
                return hasTriviaComment(this._trailingTriviaInfo);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingNewLine = function () {
                return hasTriviaNewLine(this._trailingTriviaInfo);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.trailingTriviaWidth = function () {
                return getTriviaWidth(this._trailingTriviaInfo);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.trailingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), this.leadingTriviaWidth() + this.width(), getTriviaWidth(this._trailingTriviaInfo), true);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.firstToken = function () {
                return this;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.lastToken = function () {
                return this;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            VariableWidthTokenWithLeadingAndTrailingTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return VariableWidthTokenWithLeadingAndTrailingTrivia;
        })();
        Syntax.VariableWidthTokenWithLeadingAndTrailingTrivia = VariableWidthTokenWithLeadingAndTrailingTrivia;

        var FixedWidthTokenWithNoTrivia = (function () {
            function FixedWidthTokenWithNoTrivia(kind) {
                this.tokenKind = kind;
            }
            FixedWidthTokenWithNoTrivia.prototype.clone = function () {
                return new FixedWidthTokenWithNoTrivia(this.tokenKind);
            };

            FixedWidthTokenWithNoTrivia.prototype.isNode = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.isToken = function () {
                return true;
            };
            FixedWidthTokenWithNoTrivia.prototype.isList = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            FixedWidthTokenWithNoTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            FixedWidthTokenWithNoTrivia.prototype.childCount = function () {
                return 0;
            };
            FixedWidthTokenWithNoTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            FixedWidthTokenWithNoTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            FixedWidthTokenWithNoTrivia.prototype.width = function () {
                return this.text().length;
            };

            FixedWidthTokenWithNoTrivia.prototype.text = function () {
                return TypeScript.SyntaxFacts.getText(this.tokenKind);
            };
            FixedWidthTokenWithNoTrivia.prototype.fullText = function () {
                return this.text();
            };

            FixedWidthTokenWithNoTrivia.prototype.value = function () {
                return Syntax.value(this);
            };
            FixedWidthTokenWithNoTrivia.prototype.valueText = function () {
                return Syntax.valueText(this);
            };
            FixedWidthTokenWithNoTrivia.prototype.hasLeadingTrivia = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.hasLeadingComment = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.hasLeadingNewLine = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.leadingTriviaWidth = function () {
                return 0;
            };
            FixedWidthTokenWithNoTrivia.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            FixedWidthTokenWithNoTrivia.prototype.hasTrailingTrivia = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.hasTrailingComment = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.hasTrailingNewLine = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.trailingTriviaWidth = function () {
                return 0;
            };
            FixedWidthTokenWithNoTrivia.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            FixedWidthTokenWithNoTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            FixedWidthTokenWithNoTrivia.prototype.firstToken = function () {
                return this;
            };
            FixedWidthTokenWithNoTrivia.prototype.lastToken = function () {
                return this;
            };
            FixedWidthTokenWithNoTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            FixedWidthTokenWithNoTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            FixedWidthTokenWithNoTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            FixedWidthTokenWithNoTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            FixedWidthTokenWithNoTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            FixedWidthTokenWithNoTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            FixedWidthTokenWithNoTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            FixedWidthTokenWithNoTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            FixedWidthTokenWithNoTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            FixedWidthTokenWithNoTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithNoTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithNoTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithNoTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return FixedWidthTokenWithNoTrivia;
        })();
        Syntax.FixedWidthTokenWithNoTrivia = FixedWidthTokenWithNoTrivia;

        var FixedWidthTokenWithLeadingTrivia = (function () {
            function FixedWidthTokenWithLeadingTrivia(fullText, kind, leadingTriviaInfo) {
                this._fullText = fullText;
                this.tokenKind = kind;
                this._leadingTriviaInfo = leadingTriviaInfo;
            }
            FixedWidthTokenWithLeadingTrivia.prototype.clone = function () {
                return new FixedWidthTokenWithLeadingTrivia(this._fullText, this.tokenKind, this._leadingTriviaInfo);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.isNode = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.isToken = function () {
                return true;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.isList = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            FixedWidthTokenWithLeadingTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            FixedWidthTokenWithLeadingTrivia.prototype.childCount = function () {
                return 0;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            FixedWidthTokenWithLeadingTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.width = function () {
                return this.text().length;
            };

            FixedWidthTokenWithLeadingTrivia.prototype.text = function () {
                return TypeScript.SyntaxFacts.getText(this.tokenKind);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            FixedWidthTokenWithLeadingTrivia.prototype.value = function () {
                return Syntax.value(this);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.valueText = function () {
                return Syntax.valueText(this);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasLeadingTrivia = function () {
                return true;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasLeadingComment = function () {
                return hasTriviaComment(this._leadingTriviaInfo);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasLeadingNewLine = function () {
                return hasTriviaNewLine(this._leadingTriviaInfo);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.leadingTriviaWidth = function () {
                return getTriviaWidth(this._leadingTriviaInfo);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.leadingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), 0, getTriviaWidth(this._leadingTriviaInfo), false);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.hasTrailingTrivia = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasTrailingComment = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasTrailingNewLine = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.trailingTriviaWidth = function () {
                return 0;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            FixedWidthTokenWithLeadingTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.firstToken = function () {
                return this;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.lastToken = function () {
                return this;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            FixedWidthTokenWithLeadingTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            FixedWidthTokenWithLeadingTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            FixedWidthTokenWithLeadingTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithLeadingTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithLeadingTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithLeadingTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return FixedWidthTokenWithLeadingTrivia;
        })();
        Syntax.FixedWidthTokenWithLeadingTrivia = FixedWidthTokenWithLeadingTrivia;

        var FixedWidthTokenWithTrailingTrivia = (function () {
            function FixedWidthTokenWithTrailingTrivia(fullText, kind, trailingTriviaInfo) {
                this._fullText = fullText;
                this.tokenKind = kind;
                this._trailingTriviaInfo = trailingTriviaInfo;
            }
            FixedWidthTokenWithTrailingTrivia.prototype.clone = function () {
                return new FixedWidthTokenWithTrailingTrivia(this._fullText, this.tokenKind, this._trailingTriviaInfo);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.isNode = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.isToken = function () {
                return true;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.isList = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            FixedWidthTokenWithTrailingTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            FixedWidthTokenWithTrailingTrivia.prototype.childCount = function () {
                return 0;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            FixedWidthTokenWithTrailingTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.width = function () {
                return this.text().length;
            };

            FixedWidthTokenWithTrailingTrivia.prototype.text = function () {
                return TypeScript.SyntaxFacts.getText(this.tokenKind);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            FixedWidthTokenWithTrailingTrivia.prototype.value = function () {
                return Syntax.value(this);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.valueText = function () {
                return Syntax.valueText(this);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasLeadingTrivia = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasLeadingComment = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasLeadingNewLine = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.leadingTriviaWidth = function () {
                return 0;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };

            FixedWidthTokenWithTrailingTrivia.prototype.hasTrailingTrivia = function () {
                return true;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasTrailingComment = function () {
                return hasTriviaComment(this._trailingTriviaInfo);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasTrailingNewLine = function () {
                return hasTriviaNewLine(this._trailingTriviaInfo);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.trailingTriviaWidth = function () {
                return getTriviaWidth(this._trailingTriviaInfo);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.trailingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), this.leadingTriviaWidth() + this.width(), getTriviaWidth(this._trailingTriviaInfo), true);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.firstToken = function () {
                return this;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.lastToken = function () {
                return this;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            FixedWidthTokenWithTrailingTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            FixedWidthTokenWithTrailingTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            FixedWidthTokenWithTrailingTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithTrailingTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithTrailingTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithTrailingTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return FixedWidthTokenWithTrailingTrivia;
        })();
        Syntax.FixedWidthTokenWithTrailingTrivia = FixedWidthTokenWithTrailingTrivia;

        var FixedWidthTokenWithLeadingAndTrailingTrivia = (function () {
            function FixedWidthTokenWithLeadingAndTrailingTrivia(fullText, kind, leadingTriviaInfo, trailingTriviaInfo) {
                this._fullText = fullText;
                this.tokenKind = kind;
                this._leadingTriviaInfo = leadingTriviaInfo;
                this._trailingTriviaInfo = trailingTriviaInfo;
            }
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.clone = function () {
                return new FixedWidthTokenWithLeadingAndTrailingTrivia(this._fullText, this.tokenKind, this._leadingTriviaInfo, this._trailingTriviaInfo);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isNode = function () {
                return false;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isToken = function () {
                return true;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isList = function () {
                return false;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isSeparatedList = function () {
                return false;
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.kind = function () {
                return this.tokenKind;
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.childCount = function () {
                return 0;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange('index');
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.width = function () {
                return this.text().length;
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.text = function () {
                return TypeScript.SyntaxFacts.getText(this.tokenKind);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.fullText = function () {
                return this._fullText;
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.value = function () {
                return Syntax.value(this);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.valueText = function () {
                return Syntax.valueText(this);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingTrivia = function () {
                return true;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingComment = function () {
                return hasTriviaComment(this._leadingTriviaInfo);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingNewLine = function () {
                return hasTriviaNewLine(this._leadingTriviaInfo);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.leadingTriviaWidth = function () {
                return getTriviaWidth(this._leadingTriviaInfo);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.leadingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), 0, getTriviaWidth(this._leadingTriviaInfo), false);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingTrivia = function () {
                return true;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingComment = function () {
                return hasTriviaComment(this._trailingTriviaInfo);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingNewLine = function () {
                return hasTriviaNewLine(this._trailingTriviaInfo);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.trailingTriviaWidth = function () {
                return getTriviaWidth(this._trailingTriviaInfo);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.trailingTrivia = function () {
                return TypeScript.Scanner.scanTrivia(TypeScript.SimpleText.fromString(this._fullText), this.leadingTriviaWidth() + this.width(), getTriviaWidth(this._trailingTriviaInfo), true);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.hasSkippedToken = function () {
                return false;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.toJSON = function (key) {
                return Syntax.tokenToJSON(this);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.firstToken = function () {
                return this;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.lastToken = function () {
                return this;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isTypeScriptSpecific = function () {
                return false;
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isIncrementallyUnusable = function () {
                return this.fullWidth() === 0 || TypeScript.SyntaxFacts.isAnyDivideOrRegularExpressionToken(this.tokenKind);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.realize = function () {
                return Syntax.realizeToken(this);
            };
            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.collectTextElements = function (elements) {
                collectTokenTextElements(this, elements);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isExpression = function () {
                return Syntax.isExpression(this);
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            FixedWidthTokenWithLeadingAndTrailingTrivia.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return FixedWidthTokenWithLeadingAndTrailingTrivia;
        })();
        Syntax.FixedWidthTokenWithLeadingAndTrailingTrivia = FixedWidthTokenWithLeadingAndTrailingTrivia;

        function collectTokenTextElements(token, elements) {
            token.leadingTrivia().collectTextElements(elements);
            elements.push(token.text());
            token.trailingTrivia().collectTextElements(elements);
        }

        function getTriviaWidth(value) {
            return value >>> 2 /* TriviaFullWidthShift */;
        }

        function hasTriviaComment(value) {
            return (value & 2 /* TriviaCommentMask */) !== 0;
        }

        function hasTriviaNewLine(value) {
            return (value & 1 /* TriviaNewLineMask */) !== 0;
        }
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        function isExpression(token) {
            switch (token.tokenKind) {
                case 11 /* IdentifierName */:
                case 12 /* RegularExpressionLiteral */:
                case 13 /* NumericLiteral */:
                case 14 /* StringLiteral */:
                case 24 /* FalseKeyword */:
                case 32 /* NullKeyword */:
                case 35 /* ThisKeyword */:
                case 37 /* TrueKeyword */:
                case 50 /* SuperKeyword */:
                    return true;
            }

            return false;
        }
        Syntax.isExpression = isExpression;

        function realizeToken(token) {
            return new RealizedToken(token.tokenKind, token.leadingTrivia(), token.text(), token.value(), token.valueText(), token.trailingTrivia());
        }
        Syntax.realizeToken = realizeToken;

        function convertToIdentifierName(token) {
            TypeScript.Debug.assert(TypeScript.SyntaxFacts.isAnyKeyword(token.tokenKind));
            return new RealizedToken(11 /* IdentifierName */, token.leadingTrivia(), token.text(), token.text(), token.text(), token.trailingTrivia());
        }
        Syntax.convertToIdentifierName = convertToIdentifierName;

        function tokenToJSON(token) {
            var result = {};

            for (var name in TypeScript.SyntaxKind) {
                if (TypeScript.SyntaxKind[name] === token.kind()) {
                    result.kind = name;
                    break;
                }
            }

            result.width = token.width();
            if (token.fullWidth() !== token.width()) {
                result.fullWidth = token.fullWidth();
            }

            result.text = token.text();

            var value = token.value();
            if (value !== null) {
                result.value = value;
                result.valueText = token.valueText();
            }

            if (token.hasLeadingTrivia()) {
                result.hasLeadingTrivia = true;
            }

            if (token.hasLeadingComment()) {
                result.hasLeadingComment = true;
            }

            if (token.hasLeadingNewLine()) {
                result.hasLeadingNewLine = true;
            }

            if (token.hasLeadingSkippedText()) {
                result.hasLeadingSkippedText = true;
            }

            if (token.hasTrailingTrivia()) {
                result.hasTrailingTrivia = true;
            }

            if (token.hasTrailingComment()) {
                result.hasTrailingComment = true;
            }

            if (token.hasTrailingNewLine()) {
                result.hasTrailingNewLine = true;
            }

            if (token.hasTrailingSkippedText()) {
                result.hasTrailingSkippedText = true;
            }

            var trivia = token.leadingTrivia();
            if (trivia.count() > 0) {
                result.leadingTrivia = trivia;
            }

            trivia = token.trailingTrivia();
            if (trivia.count() > 0) {
                result.trailingTrivia = trivia;
            }

            return result;
        }
        Syntax.tokenToJSON = tokenToJSON;

        function value(token) {
            return value1(token.tokenKind, token.text());
        }
        Syntax.value = value;

        function hexValue(text, start, length) {
            var intChar = 0;
            for (var i = 0; i < length; i++) {
                var ch2 = text.charCodeAt(start + i);
                if (!TypeScript.CharacterInfo.isHexDigit(ch2)) {
                    break;
                }

                intChar = (intChar << 4) + TypeScript.CharacterInfo.hexValue(ch2);
            }

            return intChar;
        }

        var characterArray = [];

        function convertEscapes(text) {
            characterArray.length = 0;
            var result = "";

            for (var i = 0, n = text.length; i < n; i++) {
                var ch = text.charCodeAt(i);

                if (ch === 92 /* backslash */) {
                    i++;
                    if (i < n) {
                        ch = text.charCodeAt(i);
                        switch (ch) {
                            case 48 /* _0 */:
                                characterArray.push(0 /* nullCharacter */);
                                continue;

                            case 98 /* b */:
                                characterArray.push(8 /* backspace */);
                                continue;

                            case 102 /* f */:
                                characterArray.push(12 /* formFeed */);
                                continue;

                            case 110 /* n */:
                                characterArray.push(10 /* lineFeed */);
                                continue;

                            case 114 /* r */:
                                characterArray.push(13 /* carriageReturn */);
                                continue;

                            case 116 /* t */:
                                characterArray.push(9 /* tab */);
                                continue;

                            case 118 /* v */:
                                characterArray.push(11 /* verticalTab */);
                                continue;

                            case 120 /* x */:
                                characterArray.push(hexValue(text, i + 1, 2));
                                i += 2;
                                continue;

                            case 117 /* u */:
                                characterArray.push(hexValue(text, i + 1, 4));
                                i += 4;
                                continue;

                            case 13 /* carriageReturn */:
                                var nextIndex = i + 1;
                                if (nextIndex < text.length && text.charCodeAt(nextIndex) === 10 /* lineFeed */) {
                                    i++;
                                }
                                continue;

                            case 10 /* lineFeed */:
                            case 8233 /* paragraphSeparator */:
                            case 8232 /* lineSeparator */:
                                continue;

                            default:
                        }
                    }
                }

                characterArray.push(ch);

                if (i && !(i % 1024)) {
                    result = result.concat(String.fromCharCode.apply(null, characterArray));
                    characterArray.length = 0;
                }
            }

            if (characterArray.length) {
                result = result.concat(String.fromCharCode.apply(null, characterArray));
            }

            return result;
        }

        function massageEscapes(text) {
            return text.indexOf("\\") >= 0 ? convertEscapes(text) : text;
        }
        Syntax.massageEscapes = massageEscapes;

        function value1(kind, text) {
            if (kind === 11 /* IdentifierName */) {
                return massageEscapes(text);
            }

            switch (kind) {
                case 37 /* TrueKeyword */:
                    return true;
                case 24 /* FalseKeyword */:
                    return false;
                case 32 /* NullKeyword */:
                    return null;
            }

            if (TypeScript.SyntaxFacts.isAnyKeyword(kind) || TypeScript.SyntaxFacts.isAnyPunctuation(kind)) {
                return TypeScript.SyntaxFacts.getText(kind);
            }

            if (kind === 13 /* NumericLiteral */) {
                return TypeScript.IntegerUtilities.isHexInteger(text) ? parseInt(text, 16) : parseFloat(text);
            } else if (kind === 14 /* StringLiteral */) {
                if (text.length > 1 && text.charCodeAt(text.length - 1) === text.charCodeAt(0)) {
                    return massageEscapes(text.substr(1, text.length - 2));
                } else {
                    return massageEscapes(text.substr(1));
                }
            } else if (kind === 12 /* RegularExpressionLiteral */) {
                return regularExpressionValue(text);
            } else if (kind === 10 /* EndOfFileToken */ || kind === 9 /* ErrorToken */) {
                return null;
            } else {
                throw TypeScript.Errors.invalidOperation();
            }
        }

        function regularExpressionValue(text) {
            try  {
                var lastSlash = text.lastIndexOf("/");
                var body = text.substring(1, lastSlash);
                var flags = text.substring(lastSlash + 1);
                return new RegExp(body, flags);
            } catch (e) {
                return null;
            }
        }

        function valueText1(kind, text) {
            var value = value1(kind, text);
            return value === null ? "" : value.toString();
        }

        function valueText(token) {
            var value = token.value();
            return value === null ? "" : value.toString();
        }
        Syntax.valueText = valueText;

        var EmptyToken = (function () {
            function EmptyToken(kind) {
                this.tokenKind = kind;
            }
            EmptyToken.prototype.clone = function () {
                return new EmptyToken(this.tokenKind);
            };

            EmptyToken.prototype.kind = function () {
                return this.tokenKind;
            };

            EmptyToken.prototype.isToken = function () {
                return true;
            };
            EmptyToken.prototype.isNode = function () {
                return false;
            };
            EmptyToken.prototype.isList = function () {
                return false;
            };
            EmptyToken.prototype.isSeparatedList = function () {
                return false;
            };

            EmptyToken.prototype.childCount = function () {
                return 0;
            };

            EmptyToken.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            EmptyToken.prototype.toJSON = function (key) {
                return tokenToJSON(this);
            };
            EmptyToken.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };

            EmptyToken.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            EmptyToken.prototype.firstToken = function () {
                return this;
            };
            EmptyToken.prototype.lastToken = function () {
                return this;
            };
            EmptyToken.prototype.isTypeScriptSpecific = function () {
                return false;
            };

            EmptyToken.prototype.isIncrementallyUnusable = function () {
                return true;
            };

            EmptyToken.prototype.fullWidth = function () {
                return 0;
            };
            EmptyToken.prototype.width = function () {
                return 0;
            };
            EmptyToken.prototype.text = function () {
                return "";
            };
            EmptyToken.prototype.fullText = function () {
                return "";
            };
            EmptyToken.prototype.value = function () {
                return null;
            };
            EmptyToken.prototype.valueText = function () {
                return "";
            };

            EmptyToken.prototype.hasLeadingTrivia = function () {
                return false;
            };
            EmptyToken.prototype.hasLeadingComment = function () {
                return false;
            };
            EmptyToken.prototype.hasLeadingNewLine = function () {
                return false;
            };
            EmptyToken.prototype.hasLeadingSkippedText = function () {
                return false;
            };
            EmptyToken.prototype.leadingTriviaWidth = function () {
                return 0;
            };
            EmptyToken.prototype.hasTrailingTrivia = function () {
                return false;
            };
            EmptyToken.prototype.hasTrailingComment = function () {
                return false;
            };
            EmptyToken.prototype.hasTrailingNewLine = function () {
                return false;
            };
            EmptyToken.prototype.hasTrailingSkippedText = function () {
                return false;
            };
            EmptyToken.prototype.hasSkippedToken = function () {
                return false;
            };

            EmptyToken.prototype.trailingTriviaWidth = function () {
                return 0;
            };
            EmptyToken.prototype.leadingTrivia = function () {
                return Syntax.emptyTriviaList;
            };
            EmptyToken.prototype.trailingTrivia = function () {
                return Syntax.emptyTriviaList;
            };
            EmptyToken.prototype.realize = function () {
                return realizeToken(this);
            };
            EmptyToken.prototype.collectTextElements = function (elements) {
            };

            EmptyToken.prototype.withLeadingTrivia = function (leadingTrivia) {
                return this.realize().withLeadingTrivia(leadingTrivia);
            };

            EmptyToken.prototype.withTrailingTrivia = function (trailingTrivia) {
                return this.realize().withTrailingTrivia(trailingTrivia);
            };

            EmptyToken.prototype.isExpression = function () {
                return isExpression(this);
            };

            EmptyToken.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            EmptyToken.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            EmptyToken.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            EmptyToken.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return EmptyToken;
        })();

        function emptyToken(kind) {
            return new EmptyToken(kind);
        }
        Syntax.emptyToken = emptyToken;

        var RealizedToken = (function () {
            function RealizedToken(tokenKind, leadingTrivia, text, value, valueText, trailingTrivia) {
                this.tokenKind = tokenKind;
                this._leadingTrivia = leadingTrivia;
                this._text = text;
                this._value = value;
                this._valueText = valueText;
                this._trailingTrivia = trailingTrivia;
            }
            RealizedToken.prototype.clone = function () {
                return new RealizedToken(this.tokenKind, this._leadingTrivia, this._text, this._value, this._valueText, this._trailingTrivia);
            };

            RealizedToken.prototype.kind = function () {
                return this.tokenKind;
            };
            RealizedToken.prototype.toJSON = function (key) {
                return tokenToJSON(this);
            };
            RealizedToken.prototype.firstToken = function () {
                return this;
            };
            RealizedToken.prototype.lastToken = function () {
                return this;
            };
            RealizedToken.prototype.isTypeScriptSpecific = function () {
                return false;
            };

            RealizedToken.prototype.isIncrementallyUnusable = function () {
                return true;
            };

            RealizedToken.prototype.accept = function (visitor) {
                return visitor.visitToken(this);
            };

            RealizedToken.prototype.childCount = function () {
                return 0;
            };

            RealizedToken.prototype.childAt = function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            };

            RealizedToken.prototype.isToken = function () {
                return true;
            };
            RealizedToken.prototype.isNode = function () {
                return false;
            };
            RealizedToken.prototype.isList = function () {
                return false;
            };
            RealizedToken.prototype.isSeparatedList = function () {
                return false;
            };
            RealizedToken.prototype.isTrivia = function () {
                return false;
            };
            RealizedToken.prototype.isTriviaList = function () {
                return false;
            };

            RealizedToken.prototype.fullWidth = function () {
                return this._leadingTrivia.fullWidth() + this.width() + this._trailingTrivia.fullWidth();
            };
            RealizedToken.prototype.width = function () {
                return this.text().length;
            };

            RealizedToken.prototype.text = function () {
                return this._text;
            };
            RealizedToken.prototype.fullText = function () {
                return this._leadingTrivia.fullText() + this.text() + this._trailingTrivia.fullText();
            };

            RealizedToken.prototype.value = function () {
                return this._value;
            };
            RealizedToken.prototype.valueText = function () {
                return this._valueText;
            };

            RealizedToken.prototype.hasLeadingTrivia = function () {
                return this._leadingTrivia.count() > 0;
            };
            RealizedToken.prototype.hasLeadingComment = function () {
                return this._leadingTrivia.hasComment();
            };
            RealizedToken.prototype.hasLeadingNewLine = function () {
                return this._leadingTrivia.hasNewLine();
            };
            RealizedToken.prototype.hasLeadingSkippedText = function () {
                return this._leadingTrivia.hasSkippedToken();
            };
            RealizedToken.prototype.leadingTriviaWidth = function () {
                return this._leadingTrivia.fullWidth();
            };

            RealizedToken.prototype.hasTrailingTrivia = function () {
                return this._trailingTrivia.count() > 0;
            };
            RealizedToken.prototype.hasTrailingComment = function () {
                return this._trailingTrivia.hasComment();
            };
            RealizedToken.prototype.hasTrailingNewLine = function () {
                return this._trailingTrivia.hasNewLine();
            };
            RealizedToken.prototype.hasTrailingSkippedText = function () {
                return this._trailingTrivia.hasSkippedToken();
            };
            RealizedToken.prototype.trailingTriviaWidth = function () {
                return this._trailingTrivia.fullWidth();
            };

            RealizedToken.prototype.hasSkippedToken = function () {
                return this.hasLeadingSkippedText() || this.hasTrailingSkippedText();
            };

            RealizedToken.prototype.leadingTrivia = function () {
                return this._leadingTrivia;
            };
            RealizedToken.prototype.trailingTrivia = function () {
                return this._trailingTrivia;
            };

            RealizedToken.prototype.findTokenInternal = function (parent, position, fullStart) {
                return new TypeScript.PositionedToken(parent, this, fullStart);
            };

            RealizedToken.prototype.collectTextElements = function (elements) {
                this.leadingTrivia().collectTextElements(elements);
                elements.push(this.text());
                this.trailingTrivia().collectTextElements(elements);
            };

            RealizedToken.prototype.withLeadingTrivia = function (leadingTrivia) {
                return new RealizedToken(this.tokenKind, leadingTrivia, this._text, this._value, this._valueText, this._trailingTrivia);
            };

            RealizedToken.prototype.withTrailingTrivia = function (trailingTrivia) {
                return new RealizedToken(this.tokenKind, this._leadingTrivia, this._text, this._value, this._valueText, trailingTrivia);
            };

            RealizedToken.prototype.isExpression = function () {
                return isExpression(this);
            };

            RealizedToken.prototype.isPrimaryExpression = function () {
                return this.isExpression();
            };

            RealizedToken.prototype.isMemberExpression = function () {
                return this.isExpression();
            };

            RealizedToken.prototype.isPostfixExpression = function () {
                return this.isExpression();
            };

            RealizedToken.prototype.isUnaryExpression = function () {
                return this.isExpression();
            };
            return RealizedToken;
        })();

        function token(kind, info) {
            if (typeof info === "undefined") { info = null; }
            var text = (info !== null && info.text !== undefined) ? info.text : TypeScript.SyntaxFacts.getText(kind);

            return new RealizedToken(kind, Syntax.triviaList(info === null ? null : info.leadingTrivia), text, value1(kind, text), valueText1(kind, text), Syntax.triviaList(info === null ? null : info.trailingTrivia));
        }
        Syntax.token = token;

        function identifier(text, info) {
            if (typeof info === "undefined") { info = null; }
            info = info || {};
            info.text = text;
            return token(11 /* IdentifierName */, info);
        }
        Syntax.identifier = identifier;
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxTokenReplacer = (function (_super) {
        __extends(SyntaxTokenReplacer, _super);
        function SyntaxTokenReplacer(token1, token2) {
            _super.call(this);
            this.token1 = token1;
            this.token2 = token2;
        }
        SyntaxTokenReplacer.prototype.visitToken = function (token) {
            if (token === this.token1) {
                var result = this.token2;
                this.token1 = null;
                this.token2 = null;

                return result;
            }

            return token;
        };

        SyntaxTokenReplacer.prototype.visitNode = function (node) {
            if (this.token1 === null) {
                return node;
            }

            return _super.prototype.visitNode.call(this, node);
        };

        SyntaxTokenReplacer.prototype.visitList = function (list) {
            if (this.token1 === null) {
                return list;
            }

            return _super.prototype.visitList.call(this, list);
        };

        SyntaxTokenReplacer.prototype.visitSeparatedList = function (list) {
            if (this.token1 === null) {
                return list;
            }

            return _super.prototype.visitSeparatedList.call(this, list);
        };
        return SyntaxTokenReplacer;
    })(TypeScript.SyntaxRewriter);
    TypeScript.SyntaxTokenReplacer = SyntaxTokenReplacer;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        var AbstractTrivia = (function () {
            function AbstractTrivia(_kind) {
                this._kind = _kind;
            }
            AbstractTrivia.prototype.fullWidth = function () {
                throw TypeScript.Errors.abstract();
            };

            AbstractTrivia.prototype.fullText = function () {
                throw TypeScript.Errors.abstract();
            };

            AbstractTrivia.prototype.skippedToken = function () {
                throw TypeScript.Errors.abstract();
            };

            AbstractTrivia.prototype.toJSON = function (key) {
                var result = {};

                for (var name in TypeScript.SyntaxKind) {
                    if (TypeScript.SyntaxKind[name] === this._kind) {
                        result.kind = name;
                        break;
                    }
                }

                if (this.isSkippedToken()) {
                    result.skippedToken = this.skippedToken();
                } else {
                    result.text = this.fullText();
                }
                return result;
            };

            AbstractTrivia.prototype.kind = function () {
                return this._kind;
            };

            AbstractTrivia.prototype.isWhitespace = function () {
                return this.kind() === 4 /* WhitespaceTrivia */;
            };

            AbstractTrivia.prototype.isComment = function () {
                return this.kind() === 7 /* SingleLineCommentTrivia */ || this.kind() === 6 /* MultiLineCommentTrivia */;
            };

            AbstractTrivia.prototype.isNewLine = function () {
                return this.kind() === 5 /* NewLineTrivia */;
            };

            AbstractTrivia.prototype.isSkippedToken = function () {
                return this.kind() === 8 /* SkippedTokenTrivia */;
            };

            AbstractTrivia.prototype.collectTextElements = function (elements) {
                elements.push(this.fullText());
            };
            return AbstractTrivia;
        })();

        var NormalTrivia = (function (_super) {
            __extends(NormalTrivia, _super);
            function NormalTrivia(kind, _text) {
                _super.call(this, kind);
                this._text = _text;
            }
            NormalTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };

            NormalTrivia.prototype.fullText = function () {
                return this._text;
            };

            NormalTrivia.prototype.skippedToken = function () {
                throw TypeScript.Errors.invalidOperation();
            };
            return NormalTrivia;
        })(AbstractTrivia);

        var SkippedTokenTrivia = (function (_super) {
            __extends(SkippedTokenTrivia, _super);
            function SkippedTokenTrivia(_skippedToken) {
                _super.call(this, 8 /* SkippedTokenTrivia */);
                this._skippedToken = _skippedToken;
            }
            SkippedTokenTrivia.prototype.fullWidth = function () {
                return this.fullText().length;
            };

            SkippedTokenTrivia.prototype.fullText = function () {
                return this.skippedToken().fullText();
            };

            SkippedTokenTrivia.prototype.skippedToken = function () {
                return this._skippedToken;
            };
            return SkippedTokenTrivia;
        })(AbstractTrivia);

        var DeferredTrivia = (function (_super) {
            __extends(DeferredTrivia, _super);
            function DeferredTrivia(kind, _text, _fullStart, _fullWidth) {
                _super.call(this, kind);
                this._text = _text;
                this._fullStart = _fullStart;
                this._fullWidth = _fullWidth;
                this._fullText = null;
            }
            DeferredTrivia.prototype.fullWidth = function () {
                return this._fullWidth;
            };

            DeferredTrivia.prototype.fullText = function () {
                if (!this._fullText) {
                    this._fullText = this._text.substr(this._fullStart, this._fullWidth, false);
                    this._text = null;
                }

                return this._fullText;
            };

            DeferredTrivia.prototype.skippedToken = function () {
                throw TypeScript.Errors.invalidOperation();
            };
            return DeferredTrivia;
        })(AbstractTrivia);

        function deferredTrivia(kind, text, fullStart, fullWidth) {
            return new DeferredTrivia(kind, text, fullStart, fullWidth);
        }
        Syntax.deferredTrivia = deferredTrivia;

        function trivia(kind, text) {
            return new NormalTrivia(kind, text);
        }
        Syntax.trivia = trivia;

        function skippedTokenTrivia(token) {
            TypeScript.Debug.assert(!token.hasLeadingTrivia());
            TypeScript.Debug.assert(!token.hasTrailingTrivia());
            TypeScript.Debug.assert(token.fullWidth() > 0);
            return new SkippedTokenTrivia(token);
        }
        Syntax.skippedTokenTrivia = skippedTokenTrivia;

        function spaces(count) {
            return trivia(4 /* WhitespaceTrivia */, TypeScript.StringUtilities.repeat(" ", count));
        }
        Syntax.spaces = spaces;

        function whitespace(text) {
            return trivia(4 /* WhitespaceTrivia */, text);
        }
        Syntax.whitespace = whitespace;

        function multiLineComment(text) {
            return trivia(6 /* MultiLineCommentTrivia */, text);
        }
        Syntax.multiLineComment = multiLineComment;

        function singleLineComment(text) {
            return trivia(7 /* SingleLineCommentTrivia */, text);
        }
        Syntax.singleLineComment = singleLineComment;

        Syntax.spaceTrivia = spaces(1);
        Syntax.lineFeedTrivia = trivia(5 /* NewLineTrivia */, "\n");
        Syntax.carriageReturnTrivia = trivia(5 /* NewLineTrivia */, "\r");
        Syntax.carriageReturnLineFeedTrivia = trivia(5 /* NewLineTrivia */, "\r\n");

        function splitMultiLineCommentTriviaIntoMultipleLines(trivia) {
            var result = [];

            var triviaText = trivia.fullText();
            var currentIndex = 0;

            for (var i = 0; i < triviaText.length; i++) {
                var ch = triviaText.charCodeAt(i);

                var isCarriageReturnLineFeed = false;
                switch (ch) {
                    case 13 /* carriageReturn */:
                        if (i < triviaText.length - 1 && triviaText.charCodeAt(i + 1) === 10 /* lineFeed */) {
                            i++;
                        }

                    case 10 /* lineFeed */:
                    case 8233 /* paragraphSeparator */:
                    case 8232 /* lineSeparator */:
                        result.push(triviaText.substring(currentIndex, i + 1));

                        currentIndex = i + 1;
                        continue;
                }
            }

            result.push(triviaText.substring(currentIndex));
            return result;
        }
        Syntax.splitMultiLineCommentTriviaIntoMultipleLines = splitMultiLineCommentTriviaIntoMultipleLines;
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (Syntax) {
        Syntax.emptyTriviaList = {
            kind: function () {
                return 3 /* TriviaList */;
            },
            count: function () {
                return 0;
            },
            syntaxTriviaAt: function (index) {
                throw TypeScript.Errors.argumentOutOfRange("index");
            },
            last: function () {
                throw TypeScript.Errors.argumentOutOfRange("index");
            },
            fullWidth: function () {
                return 0;
            },
            fullText: function () {
                return "";
            },
            hasComment: function () {
                return false;
            },
            hasNewLine: function () {
                return false;
            },
            hasSkippedToken: function () {
                return false;
            },
            toJSON: function (key) {
                return [];
            },
            collectTextElements: function (elements) {
            },
            toArray: function () {
                return [];
            },
            concat: function (trivia) {
                return trivia;
            }
        };

        function concatTrivia(list1, list2) {
            if (list1.count() === 0) {
                return list2;
            }

            if (list2.count() === 0) {
                return list1;
            }

            var trivia = list1.toArray();
            trivia.push.apply(trivia, list2.toArray());

            return triviaList(trivia);
        }

        function isComment(trivia) {
            return trivia.kind() === 6 /* MultiLineCommentTrivia */ || trivia.kind() === 7 /* SingleLineCommentTrivia */;
        }

        var SingletonSyntaxTriviaList = (function () {
            function SingletonSyntaxTriviaList(item) {
                this.item = item;
            }
            SingletonSyntaxTriviaList.prototype.kind = function () {
                return 3 /* TriviaList */;
            };

            SingletonSyntaxTriviaList.prototype.count = function () {
                return 1;
            };

            SingletonSyntaxTriviaList.prototype.syntaxTriviaAt = function (index) {
                if (index !== 0) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.item;
            };

            SingletonSyntaxTriviaList.prototype.last = function () {
                return this.item;
            };

            SingletonSyntaxTriviaList.prototype.fullWidth = function () {
                return this.item.fullWidth();
            };

            SingletonSyntaxTriviaList.prototype.fullText = function () {
                return this.item.fullText();
            };

            SingletonSyntaxTriviaList.prototype.hasComment = function () {
                return isComment(this.item);
            };

            SingletonSyntaxTriviaList.prototype.hasNewLine = function () {
                return this.item.kind() === 5 /* NewLineTrivia */;
            };

            SingletonSyntaxTriviaList.prototype.hasSkippedToken = function () {
                return this.item.kind() === 8 /* SkippedTokenTrivia */;
            };

            SingletonSyntaxTriviaList.prototype.toJSON = function (key) {
                return [this.item];
            };

            SingletonSyntaxTriviaList.prototype.collectTextElements = function (elements) {
                this.item.collectTextElements(elements);
            };

            SingletonSyntaxTriviaList.prototype.toArray = function () {
                return [this.item];
            };

            SingletonSyntaxTriviaList.prototype.concat = function (trivia) {
                return concatTrivia(this, trivia);
            };
            return SingletonSyntaxTriviaList;
        })();

        var NormalSyntaxTriviaList = (function () {
            function NormalSyntaxTriviaList(trivia) {
                this.trivia = trivia;
            }
            NormalSyntaxTriviaList.prototype.kind = function () {
                return 3 /* TriviaList */;
            };

            NormalSyntaxTriviaList.prototype.count = function () {
                return this.trivia.length;
            };

            NormalSyntaxTriviaList.prototype.syntaxTriviaAt = function (index) {
                if (index < 0 || index >= this.trivia.length) {
                    throw TypeScript.Errors.argumentOutOfRange("index");
                }

                return this.trivia[index];
            };

            NormalSyntaxTriviaList.prototype.last = function () {
                return this.trivia[this.trivia.length - 1];
            };

            NormalSyntaxTriviaList.prototype.fullWidth = function () {
                return TypeScript.ArrayUtilities.sum(this.trivia, function (t) {
                    return t.fullWidth();
                });
            };

            NormalSyntaxTriviaList.prototype.fullText = function () {
                var result = "";

                for (var i = 0, n = this.trivia.length; i < n; i++) {
                    result += this.trivia[i].fullText();
                }

                return result;
            };

            NormalSyntaxTriviaList.prototype.hasComment = function () {
                for (var i = 0; i < this.trivia.length; i++) {
                    if (isComment(this.trivia[i])) {
                        return true;
                    }
                }

                return false;
            };

            NormalSyntaxTriviaList.prototype.hasNewLine = function () {
                for (var i = 0; i < this.trivia.length; i++) {
                    if (this.trivia[i].kind() === 5 /* NewLineTrivia */) {
                        return true;
                    }
                }

                return false;
            };

            NormalSyntaxTriviaList.prototype.hasSkippedToken = function () {
                for (var i = 0; i < this.trivia.length; i++) {
                    if (this.trivia[i].kind() === 8 /* SkippedTokenTrivia */) {
                        return true;
                    }
                }

                return false;
            };

            NormalSyntaxTriviaList.prototype.toJSON = function (key) {
                return this.trivia;
            };

            NormalSyntaxTriviaList.prototype.collectTextElements = function (elements) {
                for (var i = 0; i < this.trivia.length; i++) {
                    this.trivia[i].collectTextElements(elements);
                }
            };

            NormalSyntaxTriviaList.prototype.toArray = function () {
                return this.trivia.slice(0);
            };

            NormalSyntaxTriviaList.prototype.concat = function (trivia) {
                return concatTrivia(this, trivia);
            };
            return NormalSyntaxTriviaList;
        })();

        function triviaList(trivia) {
            if (trivia === undefined || trivia === null || trivia.length === 0) {
                return Syntax.emptyTriviaList;
            }

            if (trivia.length === 1) {
                return new SingletonSyntaxTriviaList(trivia[0]);
            }

            return new NormalSyntaxTriviaList(trivia);
        }
        Syntax.triviaList = triviaList;

        Syntax.spaceTriviaList = triviaList([Syntax.spaceTrivia]);
    })(TypeScript.Syntax || (TypeScript.Syntax = {}));
    var Syntax = TypeScript.Syntax;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxUtilities = (function () {
        function SyntaxUtilities() {
        }
        SyntaxUtilities.isAngleBracket = function (positionedElement) {
            var element = positionedElement.element();
            var parent = positionedElement.parentElement();
            if (parent !== null && (element.kind() === 80 /* LessThanToken */ || element.kind() === 81 /* GreaterThanToken */)) {
                switch (parent.kind()) {
                    case 228 /* TypeArgumentList */:
                    case 229 /* TypeParameterList */:
                    case 220 /* CastExpression */:
                        return true;
                }
            }

            return false;
        };

        SyntaxUtilities.getToken = function (list, kind) {
            for (var i = 0, n = list.childCount(); i < n; i++) {
                var token = list.childAt(i);
                if (token.tokenKind === kind) {
                    return token;
                }
            }

            return null;
        };

        SyntaxUtilities.containsToken = function (list, kind) {
            return SyntaxUtilities.getToken(list, kind) !== null;
        };

        SyntaxUtilities.hasExportKeyword = function (moduleElement) {
            return SyntaxUtilities.getExportKeyword(moduleElement) !== null;
        };

        SyntaxUtilities.getExportKeyword = function (moduleElement) {
            switch (moduleElement.kind()) {
                case 130 /* ModuleDeclaration */:
                case 131 /* ClassDeclaration */:
                case 129 /* FunctionDeclaration */:
                case 148 /* VariableStatement */:
                case 132 /* EnumDeclaration */:
                case 128 /* InterfaceDeclaration */:
                case 133 /* ImportDeclaration */:
                    return SyntaxUtilities.getToken(moduleElement.modifiers, 47 /* ExportKeyword */);
                default:
                    return null;
            }
        };

        SyntaxUtilities.isAmbientDeclarationSyntax = function (positionNode) {
            if (!positionNode) {
                return false;
            }

            var node = positionNode.node();
            switch (node.kind()) {
                case 130 /* ModuleDeclaration */:
                case 131 /* ClassDeclaration */:
                case 129 /* FunctionDeclaration */:
                case 148 /* VariableStatement */:
                case 132 /* EnumDeclaration */:
                    if (SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */)) {
                        return true;
                    }

                case 133 /* ImportDeclaration */:
                case 137 /* ConstructorDeclaration */:
                case 135 /* MemberFunctionDeclaration */:
                case 139 /* GetAccessor */:
                case 140 /* SetAccessor */:
                case 136 /* MemberVariableDeclaration */:
                    if (node.isClassElement() || node.isModuleElement()) {
                        return SyntaxUtilities.isAmbientDeclarationSyntax(positionNode.containingNode());
                    }

                case 243 /* EnumElement */:
                    return SyntaxUtilities.isAmbientDeclarationSyntax(positionNode.containingNode().containingNode());

                default:
                    return SyntaxUtilities.isAmbientDeclarationSyntax(positionNode.containingNode());
            }
        };
        return SyntaxUtilities;
    })();
    TypeScript.SyntaxUtilities = SyntaxUtilities;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxVisitor = (function () {
        function SyntaxVisitor() {
        }
        SyntaxVisitor.prototype.defaultVisit = function (node) {
            return null;
        };

        SyntaxVisitor.prototype.visitToken = function (token) {
            return this.defaultVisit(token);
        };

        SyntaxVisitor.prototype.visitSourceUnit = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitExternalModuleReference = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitModuleNameModuleReference = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitImportDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitExportAssignment = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitClassDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitInterfaceDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitHeritageClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitModuleDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitFunctionDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitVariableStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitVariableDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitVariableDeclarator = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitEqualsValueClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitPrefixUnaryExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitArrayLiteralExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitOmittedExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitParenthesizedExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitSimpleArrowFunctionExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitParenthesizedArrowFunctionExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitQualifiedName = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTypeArgumentList = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitConstructorType = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitFunctionType = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitObjectType = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitArrayType = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitGenericType = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTypeQuery = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTypeAnnotation = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitBlock = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitParameter = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitMemberAccessExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitPostfixUnaryExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitElementAccessExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitInvocationExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitArgumentList = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitBinaryExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitConditionalExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitConstructSignature = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitMethodSignature = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitIndexSignature = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitPropertySignature = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitCallSignature = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitParameterList = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTypeParameterList = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTypeParameter = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitConstraint = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitElseClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitIfStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitExpressionStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitConstructorDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitMemberFunctionDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitGetAccessor = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitSetAccessor = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitMemberVariableDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitIndexMemberDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitThrowStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitReturnStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitObjectCreationExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitSwitchStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitCaseSwitchClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitDefaultSwitchClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitBreakStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitContinueStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitForStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitForInStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitWhileStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitWithStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitEnumDeclaration = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitEnumElement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitCastExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitObjectLiteralExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitSimplePropertyAssignment = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitFunctionPropertyAssignment = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitFunctionExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitEmptyStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTryStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitCatchClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitFinallyClause = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitLabeledStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitDoStatement = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitTypeOfExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitDeleteExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitVoidExpression = function (node) {
            return this.defaultVisit(node);
        };

        SyntaxVisitor.prototype.visitDebuggerStatement = function (node) {
            return this.defaultVisit(node);
        };
        return SyntaxVisitor;
    })();
    TypeScript.SyntaxVisitor = SyntaxVisitor;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxWalker = (function () {
        function SyntaxWalker() {
        }
        SyntaxWalker.prototype.visitToken = function (token) {
        };

        SyntaxWalker.prototype.visitNode = function (node) {
            node.accept(this);
        };

        SyntaxWalker.prototype.visitNodeOrToken = function (nodeOrToken) {
            if (nodeOrToken.isToken()) {
                this.visitToken(nodeOrToken);
            } else {
                this.visitNode(nodeOrToken);
            }
        };

        SyntaxWalker.prototype.visitOptionalToken = function (token) {
            if (token === null) {
                return;
            }

            this.visitToken(token);
        };

        SyntaxWalker.prototype.visitOptionalNode = function (node) {
            if (node === null) {
                return;
            }

            this.visitNode(node);
        };

        SyntaxWalker.prototype.visitOptionalNodeOrToken = function (nodeOrToken) {
            if (nodeOrToken === null) {
                return;
            }

            this.visitNodeOrToken(nodeOrToken);
        };

        SyntaxWalker.prototype.visitList = function (list) {
            for (var i = 0, n = list.childCount(); i < n; i++) {
                this.visitNodeOrToken(list.childAt(i));
            }
        };

        SyntaxWalker.prototype.visitSeparatedList = function (list) {
            for (var i = 0, n = list.childCount(); i < n; i++) {
                var item = list.childAt(i);
                this.visitNodeOrToken(item);
            }
        };

        SyntaxWalker.prototype.visitSourceUnit = function (node) {
            this.visitList(node.moduleElements);
            this.visitToken(node.endOfFileToken);
        };

        SyntaxWalker.prototype.visitExternalModuleReference = function (node) {
            this.visitToken(node.requireKeyword);
            this.visitToken(node.openParenToken);
            this.visitToken(node.stringLiteral);
            this.visitToken(node.closeParenToken);
        };

        SyntaxWalker.prototype.visitModuleNameModuleReference = function (node) {
            this.visitNodeOrToken(node.moduleName);
        };

        SyntaxWalker.prototype.visitImportDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.importKeyword);
            this.visitToken(node.identifier);
            this.visitToken(node.equalsToken);
            this.visitNodeOrToken(node.moduleReference);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitExportAssignment = function (node) {
            this.visitToken(node.exportKeyword);
            this.visitToken(node.equalsToken);
            this.visitToken(node.identifier);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitClassDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.classKeyword);
            this.visitToken(node.identifier);
            this.visitOptionalNode(node.typeParameterList);
            this.visitList(node.heritageClauses);
            this.visitToken(node.openBraceToken);
            this.visitList(node.classElements);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitInterfaceDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.interfaceKeyword);
            this.visitToken(node.identifier);
            this.visitOptionalNode(node.typeParameterList);
            this.visitList(node.heritageClauses);
            this.visitNode(node.body);
        };

        SyntaxWalker.prototype.visitHeritageClause = function (node) {
            this.visitToken(node.extendsOrImplementsKeyword);
            this.visitSeparatedList(node.typeNames);
        };

        SyntaxWalker.prototype.visitModuleDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.moduleKeyword);
            this.visitOptionalNodeOrToken(node.name);
            this.visitOptionalToken(node.stringLiteral);
            this.visitToken(node.openBraceToken);
            this.visitList(node.moduleElements);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitFunctionDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.functionKeyword);
            this.visitToken(node.identifier);
            this.visitNode(node.callSignature);
            this.visitOptionalNode(node.block);
            this.visitOptionalToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitVariableStatement = function (node) {
            this.visitList(node.modifiers);
            this.visitNode(node.variableDeclaration);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitVariableDeclaration = function (node) {
            this.visitToken(node.varKeyword);
            this.visitSeparatedList(node.variableDeclarators);
        };

        SyntaxWalker.prototype.visitVariableDeclarator = function (node) {
            this.visitToken(node.propertyName);
            this.visitOptionalNode(node.typeAnnotation);
            this.visitOptionalNode(node.equalsValueClause);
        };

        SyntaxWalker.prototype.visitEqualsValueClause = function (node) {
            this.visitToken(node.equalsToken);
            this.visitNodeOrToken(node.value);
        };

        SyntaxWalker.prototype.visitPrefixUnaryExpression = function (node) {
            this.visitToken(node.operatorToken);
            this.visitNodeOrToken(node.operand);
        };

        SyntaxWalker.prototype.visitArrayLiteralExpression = function (node) {
            this.visitToken(node.openBracketToken);
            this.visitSeparatedList(node.expressions);
            this.visitToken(node.closeBracketToken);
        };

        SyntaxWalker.prototype.visitOmittedExpression = function (node) {
        };

        SyntaxWalker.prototype.visitParenthesizedExpression = function (node) {
            this.visitToken(node.openParenToken);
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.closeParenToken);
        };

        SyntaxWalker.prototype.visitSimpleArrowFunctionExpression = function (node) {
            this.visitToken(node.identifier);
            this.visitToken(node.equalsGreaterThanToken);
            this.visitOptionalNode(node.block);
            this.visitOptionalNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitParenthesizedArrowFunctionExpression = function (node) {
            this.visitNode(node.callSignature);
            this.visitToken(node.equalsGreaterThanToken);
            this.visitOptionalNode(node.block);
            this.visitOptionalNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitQualifiedName = function (node) {
            this.visitNodeOrToken(node.left);
            this.visitToken(node.dotToken);
            this.visitToken(node.right);
        };

        SyntaxWalker.prototype.visitTypeArgumentList = function (node) {
            this.visitToken(node.lessThanToken);
            this.visitSeparatedList(node.typeArguments);
            this.visitToken(node.greaterThanToken);
        };

        SyntaxWalker.prototype.visitConstructorType = function (node) {
            this.visitToken(node.newKeyword);
            this.visitOptionalNode(node.typeParameterList);
            this.visitNode(node.parameterList);
            this.visitToken(node.equalsGreaterThanToken);
            this.visitNodeOrToken(node.type);
        };

        SyntaxWalker.prototype.visitFunctionType = function (node) {
            this.visitOptionalNode(node.typeParameterList);
            this.visitNode(node.parameterList);
            this.visitToken(node.equalsGreaterThanToken);
            this.visitNodeOrToken(node.type);
        };

        SyntaxWalker.prototype.visitObjectType = function (node) {
            this.visitToken(node.openBraceToken);
            this.visitSeparatedList(node.typeMembers);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitArrayType = function (node) {
            this.visitNodeOrToken(node.type);
            this.visitToken(node.openBracketToken);
            this.visitToken(node.closeBracketToken);
        };

        SyntaxWalker.prototype.visitGenericType = function (node) {
            this.visitNodeOrToken(node.name);
            this.visitNode(node.typeArgumentList);
        };

        SyntaxWalker.prototype.visitTypeQuery = function (node) {
            this.visitToken(node.typeOfKeyword);
            this.visitNodeOrToken(node.name);
        };

        SyntaxWalker.prototype.visitTypeAnnotation = function (node) {
            this.visitToken(node.colonToken);
            this.visitNodeOrToken(node.type);
        };

        SyntaxWalker.prototype.visitBlock = function (node) {
            this.visitToken(node.openBraceToken);
            this.visitList(node.statements);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitParameter = function (node) {
            this.visitOptionalToken(node.dotDotDotToken);
            this.visitList(node.modifiers);
            this.visitToken(node.identifier);
            this.visitOptionalToken(node.questionToken);
            this.visitOptionalNode(node.typeAnnotation);
            this.visitOptionalNode(node.equalsValueClause);
        };

        SyntaxWalker.prototype.visitMemberAccessExpression = function (node) {
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.dotToken);
            this.visitToken(node.name);
        };

        SyntaxWalker.prototype.visitPostfixUnaryExpression = function (node) {
            this.visitNodeOrToken(node.operand);
            this.visitToken(node.operatorToken);
        };

        SyntaxWalker.prototype.visitElementAccessExpression = function (node) {
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.openBracketToken);
            this.visitNodeOrToken(node.argumentExpression);
            this.visitToken(node.closeBracketToken);
        };

        SyntaxWalker.prototype.visitInvocationExpression = function (node) {
            this.visitNodeOrToken(node.expression);
            this.visitNode(node.argumentList);
        };

        SyntaxWalker.prototype.visitArgumentList = function (node) {
            this.visitOptionalNode(node.typeArgumentList);
            this.visitToken(node.openParenToken);
            this.visitSeparatedList(node.arguments);
            this.visitToken(node.closeParenToken);
        };

        SyntaxWalker.prototype.visitBinaryExpression = function (node) {
            this.visitNodeOrToken(node.left);
            this.visitToken(node.operatorToken);
            this.visitNodeOrToken(node.right);
        };

        SyntaxWalker.prototype.visitConditionalExpression = function (node) {
            this.visitNodeOrToken(node.condition);
            this.visitToken(node.questionToken);
            this.visitNodeOrToken(node.whenTrue);
            this.visitToken(node.colonToken);
            this.visitNodeOrToken(node.whenFalse);
        };

        SyntaxWalker.prototype.visitConstructSignature = function (node) {
            this.visitToken(node.newKeyword);
            this.visitNode(node.callSignature);
        };

        SyntaxWalker.prototype.visitMethodSignature = function (node) {
            this.visitToken(node.propertyName);
            this.visitOptionalToken(node.questionToken);
            this.visitNode(node.callSignature);
        };

        SyntaxWalker.prototype.visitIndexSignature = function (node) {
            this.visitToken(node.openBracketToken);
            this.visitNode(node.parameter);
            this.visitToken(node.closeBracketToken);
            this.visitOptionalNode(node.typeAnnotation);
        };

        SyntaxWalker.prototype.visitPropertySignature = function (node) {
            this.visitToken(node.propertyName);
            this.visitOptionalToken(node.questionToken);
            this.visitOptionalNode(node.typeAnnotation);
        };

        SyntaxWalker.prototype.visitCallSignature = function (node) {
            this.visitOptionalNode(node.typeParameterList);
            this.visitNode(node.parameterList);
            this.visitOptionalNode(node.typeAnnotation);
        };

        SyntaxWalker.prototype.visitParameterList = function (node) {
            this.visitToken(node.openParenToken);
            this.visitSeparatedList(node.parameters);
            this.visitToken(node.closeParenToken);
        };

        SyntaxWalker.prototype.visitTypeParameterList = function (node) {
            this.visitToken(node.lessThanToken);
            this.visitSeparatedList(node.typeParameters);
            this.visitToken(node.greaterThanToken);
        };

        SyntaxWalker.prototype.visitTypeParameter = function (node) {
            this.visitToken(node.identifier);
            this.visitOptionalNode(node.constraint);
        };

        SyntaxWalker.prototype.visitConstraint = function (node) {
            this.visitToken(node.extendsKeyword);
            this.visitNodeOrToken(node.type);
        };

        SyntaxWalker.prototype.visitElseClause = function (node) {
            this.visitToken(node.elseKeyword);
            this.visitNodeOrToken(node.statement);
        };

        SyntaxWalker.prototype.visitIfStatement = function (node) {
            this.visitToken(node.ifKeyword);
            this.visitToken(node.openParenToken);
            this.visitNodeOrToken(node.condition);
            this.visitToken(node.closeParenToken);
            this.visitNodeOrToken(node.statement);
            this.visitOptionalNode(node.elseClause);
        };

        SyntaxWalker.prototype.visitExpressionStatement = function (node) {
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitConstructorDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.constructorKeyword);
            this.visitNode(node.callSignature);
            this.visitOptionalNode(node.block);
            this.visitOptionalToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitMemberFunctionDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.propertyName);
            this.visitNode(node.callSignature);
            this.visitOptionalNode(node.block);
            this.visitOptionalToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitGetAccessor = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.getKeyword);
            this.visitToken(node.propertyName);
            this.visitNode(node.parameterList);
            this.visitOptionalNode(node.typeAnnotation);
            this.visitNode(node.block);
        };

        SyntaxWalker.prototype.visitSetAccessor = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.setKeyword);
            this.visitToken(node.propertyName);
            this.visitNode(node.parameterList);
            this.visitNode(node.block);
        };

        SyntaxWalker.prototype.visitMemberVariableDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitNode(node.variableDeclarator);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitIndexMemberDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitNode(node.indexSignature);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitThrowStatement = function (node) {
            this.visitToken(node.throwKeyword);
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitReturnStatement = function (node) {
            this.visitToken(node.returnKeyword);
            this.visitOptionalNodeOrToken(node.expression);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitObjectCreationExpression = function (node) {
            this.visitToken(node.newKeyword);
            this.visitNodeOrToken(node.expression);
            this.visitOptionalNode(node.argumentList);
        };

        SyntaxWalker.prototype.visitSwitchStatement = function (node) {
            this.visitToken(node.switchKeyword);
            this.visitToken(node.openParenToken);
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.closeParenToken);
            this.visitToken(node.openBraceToken);
            this.visitList(node.switchClauses);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitCaseSwitchClause = function (node) {
            this.visitToken(node.caseKeyword);
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.colonToken);
            this.visitList(node.statements);
        };

        SyntaxWalker.prototype.visitDefaultSwitchClause = function (node) {
            this.visitToken(node.defaultKeyword);
            this.visitToken(node.colonToken);
            this.visitList(node.statements);
        };

        SyntaxWalker.prototype.visitBreakStatement = function (node) {
            this.visitToken(node.breakKeyword);
            this.visitOptionalToken(node.identifier);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitContinueStatement = function (node) {
            this.visitToken(node.continueKeyword);
            this.visitOptionalToken(node.identifier);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitForStatement = function (node) {
            this.visitToken(node.forKeyword);
            this.visitToken(node.openParenToken);
            this.visitOptionalNode(node.variableDeclaration);
            this.visitOptionalNodeOrToken(node.initializer);
            this.visitToken(node.firstSemicolonToken);
            this.visitOptionalNodeOrToken(node.condition);
            this.visitToken(node.secondSemicolonToken);
            this.visitOptionalNodeOrToken(node.incrementor);
            this.visitToken(node.closeParenToken);
            this.visitNodeOrToken(node.statement);
        };

        SyntaxWalker.prototype.visitForInStatement = function (node) {
            this.visitToken(node.forKeyword);
            this.visitToken(node.openParenToken);
            this.visitOptionalNode(node.variableDeclaration);
            this.visitOptionalNodeOrToken(node.left);
            this.visitToken(node.inKeyword);
            this.visitNodeOrToken(node.expression);
            this.visitToken(node.closeParenToken);
            this.visitNodeOrToken(node.statement);
        };

        SyntaxWalker.prototype.visitWhileStatement = function (node) {
            this.visitToken(node.whileKeyword);
            this.visitToken(node.openParenToken);
            this.visitNodeOrToken(node.condition);
            this.visitToken(node.closeParenToken);
            this.visitNodeOrToken(node.statement);
        };

        SyntaxWalker.prototype.visitWithStatement = function (node) {
            this.visitToken(node.withKeyword);
            this.visitToken(node.openParenToken);
            this.visitNodeOrToken(node.condition);
            this.visitToken(node.closeParenToken);
            this.visitNodeOrToken(node.statement);
        };

        SyntaxWalker.prototype.visitEnumDeclaration = function (node) {
            this.visitList(node.modifiers);
            this.visitToken(node.enumKeyword);
            this.visitToken(node.identifier);
            this.visitToken(node.openBraceToken);
            this.visitSeparatedList(node.enumElements);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitEnumElement = function (node) {
            this.visitToken(node.propertyName);
            this.visitOptionalNode(node.equalsValueClause);
        };

        SyntaxWalker.prototype.visitCastExpression = function (node) {
            this.visitToken(node.lessThanToken);
            this.visitNodeOrToken(node.type);
            this.visitToken(node.greaterThanToken);
            this.visitNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitObjectLiteralExpression = function (node) {
            this.visitToken(node.openBraceToken);
            this.visitSeparatedList(node.propertyAssignments);
            this.visitToken(node.closeBraceToken);
        };

        SyntaxWalker.prototype.visitSimplePropertyAssignment = function (node) {
            this.visitToken(node.propertyName);
            this.visitToken(node.colonToken);
            this.visitNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitFunctionPropertyAssignment = function (node) {
            this.visitToken(node.propertyName);
            this.visitNode(node.callSignature);
            this.visitNode(node.block);
        };

        SyntaxWalker.prototype.visitFunctionExpression = function (node) {
            this.visitToken(node.functionKeyword);
            this.visitOptionalToken(node.identifier);
            this.visitNode(node.callSignature);
            this.visitNode(node.block);
        };

        SyntaxWalker.prototype.visitEmptyStatement = function (node) {
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitTryStatement = function (node) {
            this.visitToken(node.tryKeyword);
            this.visitNode(node.block);
            this.visitOptionalNode(node.catchClause);
            this.visitOptionalNode(node.finallyClause);
        };

        SyntaxWalker.prototype.visitCatchClause = function (node) {
            this.visitToken(node.catchKeyword);
            this.visitToken(node.openParenToken);
            this.visitToken(node.identifier);
            this.visitOptionalNode(node.typeAnnotation);
            this.visitToken(node.closeParenToken);
            this.visitNode(node.block);
        };

        SyntaxWalker.prototype.visitFinallyClause = function (node) {
            this.visitToken(node.finallyKeyword);
            this.visitNode(node.block);
        };

        SyntaxWalker.prototype.visitLabeledStatement = function (node) {
            this.visitToken(node.identifier);
            this.visitToken(node.colonToken);
            this.visitNodeOrToken(node.statement);
        };

        SyntaxWalker.prototype.visitDoStatement = function (node) {
            this.visitToken(node.doKeyword);
            this.visitNodeOrToken(node.statement);
            this.visitToken(node.whileKeyword);
            this.visitToken(node.openParenToken);
            this.visitNodeOrToken(node.condition);
            this.visitToken(node.closeParenToken);
            this.visitToken(node.semicolonToken);
        };

        SyntaxWalker.prototype.visitTypeOfExpression = function (node) {
            this.visitToken(node.typeOfKeyword);
            this.visitNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitDeleteExpression = function (node) {
            this.visitToken(node.deleteKeyword);
            this.visitNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitVoidExpression = function (node) {
            this.visitToken(node.voidKeyword);
            this.visitNodeOrToken(node.expression);
        };

        SyntaxWalker.prototype.visitDebuggerStatement = function (node) {
            this.visitToken(node.debuggerKeyword);
            this.visitToken(node.semicolonToken);
        };
        return SyntaxWalker;
    })();
    TypeScript.SyntaxWalker = SyntaxWalker;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var PositionTrackingWalker = (function (_super) {
        __extends(PositionTrackingWalker, _super);
        function PositionTrackingWalker() {
            _super.apply(this, arguments);
            this._position = 0;
        }
        PositionTrackingWalker.prototype.visitToken = function (token) {
            this._position += token.fullWidth();
        };

        PositionTrackingWalker.prototype.position = function () {
            return this._position;
        };

        PositionTrackingWalker.prototype.skip = function (element) {
            this._position += element.fullWidth();
        };
        return PositionTrackingWalker;
    })(TypeScript.SyntaxWalker);
    TypeScript.PositionTrackingWalker = PositionTrackingWalker;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxInformationMap = (function (_super) {
        __extends(SyntaxInformationMap, _super);
        function SyntaxInformationMap(trackParents, trackPreviousToken) {
            _super.call(this);
            this.trackParents = trackParents;
            this.trackPreviousToken = trackPreviousToken;
            this.tokenToInformation = TypeScript.Collections.createHashTable(TypeScript.Collections.DefaultHashTableCapacity, TypeScript.Collections.identityHashCode);
            this.elementToPosition = TypeScript.Collections.createHashTable(TypeScript.Collections.DefaultHashTableCapacity, TypeScript.Collections.identityHashCode);
            this._previousToken = null;
            this._previousTokenInformation = null;
            this._currentPosition = 0;
            this._elementToParent = TypeScript.Collections.createHashTable(TypeScript.Collections.DefaultHashTableCapacity, TypeScript.Collections.identityHashCode);
            this._parentStack = [];
            this._parentStack.push(null);
        }
        SyntaxInformationMap.create = function (node, trackParents, trackPreviousToken) {
            var map = new SyntaxInformationMap(trackParents, trackPreviousToken);
            map.visitNode(node);
            return map;
        };

        SyntaxInformationMap.prototype.visitNode = function (node) {
            this.trackParents && this._elementToParent.add(node, TypeScript.ArrayUtilities.last(this._parentStack));
            this.elementToPosition.add(node, this._currentPosition);

            this.trackParents && this._parentStack.push(node);
            _super.prototype.visitNode.call(this, node);
            this.trackParents && this._parentStack.pop();
        };

        SyntaxInformationMap.prototype.visitToken = function (token) {
            this.trackParents && this._elementToParent.add(token, TypeScript.ArrayUtilities.last(this._parentStack));

            if (this.trackPreviousToken) {
                var tokenInformation = {
                    previousToken: this._previousToken,
                    nextToken: null
                };

                if (this._previousTokenInformation !== null) {
                    this._previousTokenInformation.nextToken = token;
                }

                this._previousToken = token;
                this._previousTokenInformation = tokenInformation;

                this.tokenToInformation.add(token, tokenInformation);
            }

            this.elementToPosition.add(token, this._currentPosition);
            this._currentPosition += token.fullWidth();
        };

        SyntaxInformationMap.prototype.parent = function (element) {
            return this._elementToParent.get(element);
        };

        SyntaxInformationMap.prototype.fullStart = function (element) {
            return this.elementToPosition.get(element);
        };

        SyntaxInformationMap.prototype.start = function (element) {
            return this.fullStart(element) + element.leadingTriviaWidth();
        };

        SyntaxInformationMap.prototype.end = function (element) {
            return this.start(element) + element.width();
        };

        SyntaxInformationMap.prototype.previousToken = function (token) {
            return this.tokenInformation(token).previousToken;
        };

        SyntaxInformationMap.prototype.tokenInformation = function (token) {
            return this.tokenToInformation.get(token);
        };

        SyntaxInformationMap.prototype.firstTokenInLineContainingToken = function (token) {
            var current = token;
            while (true) {
                var information = this.tokenInformation(current);
                if (this.isFirstTokenInLineWorker(information)) {
                    break;
                }

                current = information.previousToken;
            }

            return current;
        };

        SyntaxInformationMap.prototype.isFirstTokenInLine = function (token) {
            var information = this.tokenInformation(token);
            return this.isFirstTokenInLineWorker(information);
        };

        SyntaxInformationMap.prototype.isFirstTokenInLineWorker = function (information) {
            return information.previousToken === null || information.previousToken.hasTrailingNewLine();
        };
        return SyntaxInformationMap;
    })(TypeScript.SyntaxWalker);
    TypeScript.SyntaxInformationMap = SyntaxInformationMap;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxNodeInvariantsChecker = (function (_super) {
        __extends(SyntaxNodeInvariantsChecker, _super);
        function SyntaxNodeInvariantsChecker() {
            _super.apply(this, arguments);
            this.tokenTable = TypeScript.Collections.createHashTable(TypeScript.Collections.DefaultHashTableCapacity, TypeScript.Collections.identityHashCode);
        }
        SyntaxNodeInvariantsChecker.checkInvariants = function (node) {
            node.accept(new SyntaxNodeInvariantsChecker());
        };

        SyntaxNodeInvariantsChecker.prototype.visitToken = function (token) {
            this.tokenTable.add(token, token);
        };
        return SyntaxNodeInvariantsChecker;
    })(TypeScript.SyntaxWalker);
    TypeScript.SyntaxNodeInvariantsChecker = SyntaxNodeInvariantsChecker;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var DepthLimitedWalker = (function (_super) {
        __extends(DepthLimitedWalker, _super);
        function DepthLimitedWalker(maximumDepth) {
            _super.call(this);
            this._depth = 0;
            this._maximumDepth = 0;
            this._maximumDepth = maximumDepth;
        }
        DepthLimitedWalker.prototype.visitNode = function (node) {
            if (this._depth < this._maximumDepth) {
                this._depth++;
                _super.prototype.visitNode.call(this, node);
                this._depth--;
            } else {
                this.skip(node);
            }
        };
        return DepthLimitedWalker;
    })(TypeScript.PositionTrackingWalker);
    TypeScript.DepthLimitedWalker = DepthLimitedWalker;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (Parser) {
        

        var ExpressionPrecedence;
        (function (ExpressionPrecedence) {
            ExpressionPrecedence[ExpressionPrecedence["CommaExpressionPrecedence"] = 1] = "CommaExpressionPrecedence";

            ExpressionPrecedence[ExpressionPrecedence["AssignmentExpressionPrecedence"] = 2] = "AssignmentExpressionPrecedence";

            ExpressionPrecedence[ExpressionPrecedence["ConditionalExpressionPrecedence"] = 3] = "ConditionalExpressionPrecedence";

            ExpressionPrecedence[ExpressionPrecedence["ArrowFunctionPrecedence"] = 4] = "ArrowFunctionPrecedence";

            ExpressionPrecedence[ExpressionPrecedence["LogicalOrExpressionPrecedence"] = 5] = "LogicalOrExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["LogicalAndExpressionPrecedence"] = 6] = "LogicalAndExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["BitwiseOrExpressionPrecedence"] = 7] = "BitwiseOrExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["BitwiseExclusiveOrExpressionPrecedence"] = 8] = "BitwiseExclusiveOrExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["BitwiseAndExpressionPrecedence"] = 9] = "BitwiseAndExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["EqualityExpressionPrecedence"] = 10] = "EqualityExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["RelationalExpressionPrecedence"] = 11] = "RelationalExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["ShiftExpressionPrecdence"] = 12] = "ShiftExpressionPrecdence";
            ExpressionPrecedence[ExpressionPrecedence["AdditiveExpressionPrecedence"] = 13] = "AdditiveExpressionPrecedence";
            ExpressionPrecedence[ExpressionPrecedence["MultiplicativeExpressionPrecedence"] = 14] = "MultiplicativeExpressionPrecedence";

            ExpressionPrecedence[ExpressionPrecedence["UnaryExpressionPrecedence"] = 15] = "UnaryExpressionPrecedence";
        })(ExpressionPrecedence || (ExpressionPrecedence = {}));

        var ListParsingState;
        (function (ListParsingState) {
            ListParsingState[ListParsingState["SourceUnit_ModuleElements"] = 1 << 0] = "SourceUnit_ModuleElements";
            ListParsingState[ListParsingState["ClassDeclaration_ClassElements"] = 1 << 1] = "ClassDeclaration_ClassElements";
            ListParsingState[ListParsingState["ModuleDeclaration_ModuleElements"] = 1 << 2] = "ModuleDeclaration_ModuleElements";
            ListParsingState[ListParsingState["SwitchStatement_SwitchClauses"] = 1 << 3] = "SwitchStatement_SwitchClauses";
            ListParsingState[ListParsingState["SwitchClause_Statements"] = 1 << 4] = "SwitchClause_Statements";
            ListParsingState[ListParsingState["Block_Statements"] = 1 << 5] = "Block_Statements";
            ListParsingState[ListParsingState["TryBlock_Statements"] = 1 << 6] = "TryBlock_Statements";
            ListParsingState[ListParsingState["CatchBlock_Statements"] = 1 << 7] = "CatchBlock_Statements";
            ListParsingState[ListParsingState["EnumDeclaration_EnumElements"] = 1 << 8] = "EnumDeclaration_EnumElements";
            ListParsingState[ListParsingState["ObjectType_TypeMembers"] = 1 << 9] = "ObjectType_TypeMembers";
            ListParsingState[ListParsingState["ClassOrInterfaceDeclaration_HeritageClauses"] = 1 << 10] = "ClassOrInterfaceDeclaration_HeritageClauses";
            ListParsingState[ListParsingState["HeritageClause_TypeNameList"] = 1 << 11] = "HeritageClause_TypeNameList";
            ListParsingState[ListParsingState["VariableDeclaration_VariableDeclarators_AllowIn"] = 1 << 12] = "VariableDeclaration_VariableDeclarators_AllowIn";
            ListParsingState[ListParsingState["VariableDeclaration_VariableDeclarators_DisallowIn"] = 1 << 13] = "VariableDeclaration_VariableDeclarators_DisallowIn";
            ListParsingState[ListParsingState["ArgumentList_AssignmentExpressions"] = 1 << 14] = "ArgumentList_AssignmentExpressions";
            ListParsingState[ListParsingState["ObjectLiteralExpression_PropertyAssignments"] = 1 << 15] = "ObjectLiteralExpression_PropertyAssignments";
            ListParsingState[ListParsingState["ArrayLiteralExpression_AssignmentExpressions"] = 1 << 16] = "ArrayLiteralExpression_AssignmentExpressions";
            ListParsingState[ListParsingState["ParameterList_Parameters"] = 1 << 17] = "ParameterList_Parameters";
            ListParsingState[ListParsingState["TypeArgumentList_Types"] = 1 << 18] = "TypeArgumentList_Types";
            ListParsingState[ListParsingState["TypeParameterList_TypeParameters"] = 1 << 19] = "TypeParameterList_TypeParameters";

            ListParsingState[ListParsingState["FirstListParsingState"] = ListParsingState.SourceUnit_ModuleElements] = "FirstListParsingState";
            ListParsingState[ListParsingState["LastListParsingState"] = ListParsingState.TypeParameterList_TypeParameters] = "LastListParsingState";
        })(ListParsingState || (ListParsingState = {}));

        var SyntaxCursor = (function () {
            function SyntaxCursor(sourceUnit) {
                this._elements = [];
                this._index = 0;
                this._pinCount = 0;
                sourceUnit.insertChildrenInto(this._elements, 0);
            }
            SyntaxCursor.prototype.isFinished = function () {
                return this._index === this._elements.length;
            };

            SyntaxCursor.prototype.currentElement = function () {
                if (this.isFinished()) {
                    return null;
                }

                return this._elements[this._index];
            };

            SyntaxCursor.prototype.currentNode = function () {
                var element = this.currentElement();
                return element !== null && element.isNode() ? element : null;
            };

            SyntaxCursor.prototype.moveToFirstChild = function () {
                if (this.isFinished()) {
                    return;
                }

                var element = this._elements[this._index];
                if (element.isToken()) {
                    return;
                }

                var node = element;

                this._elements.splice(this._index, 1);

                node.insertChildrenInto(this._elements, this._index);
            };

            SyntaxCursor.prototype.moveToNextSibling = function () {
                if (this.isFinished()) {
                    return;
                }

                if (this._pinCount > 0) {
                    this._index++;
                    return;
                }

                this._elements.shift();
            };

            SyntaxCursor.prototype.getAndPinCursorIndex = function () {
                this._pinCount++;
                return this._index;
            };

            SyntaxCursor.prototype.releaseAndUnpinCursorIndex = function (index) {
                this._pinCount--;
                if (this._pinCount === 0) {
                }
            };

            SyntaxCursor.prototype.rewindToPinnedCursorIndex = function (index) {
                this._index = index;
            };

            SyntaxCursor.prototype.pinCount = function () {
                return this._pinCount;
            };

            SyntaxCursor.prototype.moveToFirstToken = function () {
                var element;

                while (!this.isFinished()) {
                    element = this.currentElement();
                    if (element.isNode()) {
                        this.moveToFirstChild();
                        continue;
                    }

                    return;
                }
            };

            SyntaxCursor.prototype.currentToken = function () {
                this.moveToFirstToken();
                if (this.isFinished()) {
                    return null;
                }

                var element = this.currentElement();

                return element;
            };

            SyntaxCursor.prototype.peekToken = function (n) {
                this.moveToFirstToken();
                var pin = this.getAndPinCursorIndex();

                for (var i = 0; i < n; i++) {
                    this.moveToNextSibling();
                    this.moveToFirstToken();
                }

                var result = this.currentToken();
                this.rewindToPinnedCursorIndex(pin);
                this.releaseAndUnpinCursorIndex(pin);

                return result;
            };
            return SyntaxCursor;
        })();

        

        var NormalParserSource = (function () {
            function NormalParserSource(fileName, text, languageVersion) {
                this._previousToken = null;
                this._absolutePosition = 0;
                this._tokenDiagnostics = [];
                this.rewindPointPool = [];
                this.rewindPointPoolCount = 0;
                this.slidingWindow = new TypeScript.SlidingWindow(this, TypeScript.ArrayUtilities.createArray(32, null), null);
                this.scanner = new TypeScript.Scanner(fileName, text, languageVersion);
            }
            NormalParserSource.prototype.currentNode = function () {
                return null;
            };

            NormalParserSource.prototype.moveToNextNode = function () {
                throw TypeScript.Errors.invalidOperation();
            };

            NormalParserSource.prototype.absolutePosition = function () {
                return this._absolutePosition;
            };

            NormalParserSource.prototype.previousToken = function () {
                return this._previousToken;
            };

            NormalParserSource.prototype.tokenDiagnostics = function () {
                return this._tokenDiagnostics;
            };

            NormalParserSource.prototype.getOrCreateRewindPoint = function () {
                if (this.rewindPointPoolCount === 0) {
                    return {};
                }

                this.rewindPointPoolCount--;
                var result = this.rewindPointPool[this.rewindPointPoolCount];
                this.rewindPointPool[this.rewindPointPoolCount] = null;
                return result;
            };

            NormalParserSource.prototype.getRewindPoint = function () {
                var slidingWindowIndex = this.slidingWindow.getAndPinAbsoluteIndex();

                var rewindPoint = this.getOrCreateRewindPoint();

                rewindPoint.slidingWindowIndex = slidingWindowIndex;
                rewindPoint.previousToken = this._previousToken;
                rewindPoint.absolutePosition = this._absolutePosition;

                rewindPoint.pinCount = this.slidingWindow.pinCount();

                return rewindPoint;
            };

            NormalParserSource.prototype.isPinned = function () {
                return this.slidingWindow.pinCount() > 0;
            };

            NormalParserSource.prototype.rewind = function (rewindPoint) {
                this.slidingWindow.rewindToPinnedIndex(rewindPoint.slidingWindowIndex);

                this._previousToken = rewindPoint.previousToken;
                this._absolutePosition = rewindPoint.absolutePosition;
            };

            NormalParserSource.prototype.releaseRewindPoint = function (rewindPoint) {
                this.slidingWindow.releaseAndUnpinAbsoluteIndex(rewindPoint.absoluteIndex);

                this.rewindPointPool[this.rewindPointPoolCount] = rewindPoint;
                this.rewindPointPoolCount++;
            };

            NormalParserSource.prototype.fetchMoreItems = function (allowRegularExpression, sourceIndex, window, destinationIndex, spaceAvailable) {
                window[destinationIndex] = this.scanner.scan(this._tokenDiagnostics, allowRegularExpression);
                return 1;
            };

            NormalParserSource.prototype.peekToken = function (n) {
                return this.slidingWindow.peekItemN(n);
            };

            NormalParserSource.prototype.moveToNextToken = function () {
                var currentToken = this.currentToken();
                this._absolutePosition += currentToken.fullWidth();
                this._previousToken = currentToken;

                this.slidingWindow.moveToNextItem();
            };

            NormalParserSource.prototype.currentToken = function () {
                return this.slidingWindow.currentItem(false);
            };

            NormalParserSource.prototype.removeDiagnosticsOnOrAfterPosition = function (position) {
                var tokenDiagnosticsLength = this._tokenDiagnostics.length;
                while (tokenDiagnosticsLength > 0) {
                    var diagnostic = this._tokenDiagnostics[tokenDiagnosticsLength - 1];
                    if (diagnostic.start() >= position) {
                        tokenDiagnosticsLength--;
                    } else {
                        break;
                    }
                }

                this._tokenDiagnostics.length = tokenDiagnosticsLength;
            };

            NormalParserSource.prototype.resetToPosition = function (absolutePosition, previousToken) {
                this._absolutePosition = absolutePosition;
                this._previousToken = previousToken;

                this.removeDiagnosticsOnOrAfterPosition(absolutePosition);

                this.slidingWindow.disgardAllItemsFromCurrentIndexOnwards();

                this.scanner.setAbsoluteIndex(absolutePosition);
            };

            NormalParserSource.prototype.currentTokenAllowingRegularExpression = function () {
                this.resetToPosition(this._absolutePosition, this._previousToken);

                var token = this.slidingWindow.currentItem(true);

                return token;
            };
            return NormalParserSource;
        })();

        var IncrementalParserSource = (function () {
            function IncrementalParserSource(oldSyntaxTree, textChangeRange, newText) {
                this._changeDelta = 0;
                var oldSourceUnit = oldSyntaxTree.sourceUnit();
                this._oldSourceUnitCursor = new SyntaxCursor(oldSourceUnit);

                this._changeRange = IncrementalParserSource.extendToAffectedRange(textChangeRange, oldSourceUnit);

                if (TypeScript.Debug.shouldAssert(2 /* Aggressive */)) {
                    TypeScript.Debug.assert((oldSourceUnit.fullWidth() - this._changeRange.span().length() + this._changeRange.newLength()) === newText.length());
                }

                this._normalParserSource = new NormalParserSource(oldSyntaxTree.fileName(), newText, oldSyntaxTree.parseOptions().languageVersion());
            }
            IncrementalParserSource.extendToAffectedRange = function (changeRange, sourceUnit) {
                var maxLookahead = 1;

                var start = changeRange.span().start();

                for (var i = 0; start > 0 && i <= maxLookahead; i++) {
                    var token = sourceUnit.findToken(start);

                    var position = token.fullStart();

                    start = TypeScript.MathPrototype.max(0, position - 1);
                }

                var finalSpan = TypeScript.TextSpan.fromBounds(start, changeRange.span().end());
                var finalLength = changeRange.newLength() + (changeRange.span().start() - start);

                return new TypeScript.TextChangeRange(finalSpan, finalLength);
            };

            IncrementalParserSource.prototype.absolutePosition = function () {
                return this._normalParserSource.absolutePosition();
            };

            IncrementalParserSource.prototype.previousToken = function () {
                return this._normalParserSource.previousToken();
            };

            IncrementalParserSource.prototype.tokenDiagnostics = function () {
                return this._normalParserSource.tokenDiagnostics();
            };

            IncrementalParserSource.prototype.getRewindPoint = function () {
                var rewindPoint = this._normalParserSource.getRewindPoint();
                var oldSourceUnitCursorIndex = this._oldSourceUnitCursor.getAndPinCursorIndex();

                rewindPoint.changeDelta = this._changeDelta;
                rewindPoint.changeRange = this._changeRange;
                rewindPoint.oldSourceUnitCursorIndex = oldSourceUnitCursorIndex;

                return rewindPoint;
            };

            IncrementalParserSource.prototype.rewind = function (rewindPoint) {
                this._changeRange = rewindPoint.changeRange;
                this._changeDelta = rewindPoint.changeDelta;
                this._oldSourceUnitCursor.rewindToPinnedCursorIndex(rewindPoint.oldSourceUnitCursorIndex);

                this._normalParserSource.rewind(rewindPoint);
            };

            IncrementalParserSource.prototype.releaseRewindPoint = function (rewindPoint) {
                this._oldSourceUnitCursor.releaseAndUnpinCursorIndex(rewindPoint.oldSourceUnitCursorIndex);
                this._normalParserSource.releaseRewindPoint(rewindPoint);
            };

            IncrementalParserSource.prototype.canReadFromOldSourceUnit = function () {
                if (this._normalParserSource.isPinned()) {
                    return false;
                }

                if (this._changeRange !== null && this._changeRange.newSpan().intersectsWithPosition(this.absolutePosition())) {
                    return false;
                }

                this.syncCursorToNewTextIfBehind();

                return this._changeDelta === 0 && !this._oldSourceUnitCursor.isFinished();
            };

            IncrementalParserSource.prototype.currentNode = function () {
                if (this.canReadFromOldSourceUnit()) {
                    return this.tryGetNodeFromOldSourceUnit();
                }

                return null;
            };

            IncrementalParserSource.prototype.currentToken = function () {
                if (this.canReadFromOldSourceUnit()) {
                    var token = this.tryGetTokenFromOldSourceUnit();
                    if (token !== null) {
                        return token;
                    }
                }

                return this._normalParserSource.currentToken();
            };

            IncrementalParserSource.prototype.currentTokenAllowingRegularExpression = function () {
                return this._normalParserSource.currentTokenAllowingRegularExpression();
            };

            IncrementalParserSource.prototype.syncCursorToNewTextIfBehind = function () {
                while (true) {
                    if (this._oldSourceUnitCursor.isFinished()) {
                        break;
                    }

                    if (this._changeDelta >= 0) {
                        break;
                    }

                    var currentElement = this._oldSourceUnitCursor.currentElement();

                    if (currentElement.isNode() && (currentElement.fullWidth() > Math.abs(this._changeDelta))) {
                        this._oldSourceUnitCursor.moveToFirstChild();
                    } else {
                        this._oldSourceUnitCursor.moveToNextSibling();

                        this._changeDelta += currentElement.fullWidth();
                    }
                }
            };

            IncrementalParserSource.prototype.intersectsWithChangeRangeSpanInOriginalText = function (start, length) {
                return this._changeRange !== null && this._changeRange.span().intersectsWith(start, length);
            };

            IncrementalParserSource.prototype.tryGetNodeFromOldSourceUnit = function () {
                while (true) {
                    var node = this._oldSourceUnitCursor.currentNode();
                    if (node === null) {
                        return null;
                    }

                    if (!this.intersectsWithChangeRangeSpanInOriginalText(this.absolutePosition(), node.fullWidth())) {
                        if (!node.isIncrementallyUnusable()) {
                            return node;
                        }
                    }

                    this._oldSourceUnitCursor.moveToFirstChild();
                }
            };

            IncrementalParserSource.prototype.canReuseTokenFromOldSourceUnit = function (position, token) {
                if (token !== null) {
                    if (!this.intersectsWithChangeRangeSpanInOriginalText(position, token.fullWidth())) {
                        if (!token.isIncrementallyUnusable()) {
                            return true;
                        }
                    }
                }

                return false;
            };

            IncrementalParserSource.prototype.tryGetTokenFromOldSourceUnit = function () {
                var token = this._oldSourceUnitCursor.currentToken();

                return this.canReuseTokenFromOldSourceUnit(this.absolutePosition(), token) ? token : null;
            };

            IncrementalParserSource.prototype.peekToken = function (n) {
                if (this.canReadFromOldSourceUnit()) {
                    var token = this.tryPeekTokenFromOldSourceUnit(n);
                    if (token !== null) {
                        return token;
                    }
                }

                return this._normalParserSource.peekToken(n);
            };

            IncrementalParserSource.prototype.tryPeekTokenFromOldSourceUnit = function (n) {
                var currentPosition = this.absolutePosition();
                for (var i = 0; i < n; i++) {
                    var interimToken = this._oldSourceUnitCursor.peekToken(i);
                    if (!this.canReuseTokenFromOldSourceUnit(currentPosition, interimToken)) {
                        return null;
                    }

                    currentPosition += interimToken.fullWidth();
                }

                var token = this._oldSourceUnitCursor.peekToken(n);
                return this.canReuseTokenFromOldSourceUnit(currentPosition, token) ? token : null;
            };

            IncrementalParserSource.prototype.moveToNextNode = function () {
                var currentElement = this._oldSourceUnitCursor.currentElement();
                var currentNode = this._oldSourceUnitCursor.currentNode();

                this._oldSourceUnitCursor.moveToNextSibling();

                var absolutePosition = this.absolutePosition() + currentNode.fullWidth();
                var previousToken = currentNode.lastToken();
                this._normalParserSource.resetToPosition(absolutePosition, previousToken);

                if (this._changeRange !== null) {
                }
            };

            IncrementalParserSource.prototype.moveToNextToken = function () {
                var currentToken = this.currentToken();

                if (this._oldSourceUnitCursor.currentToken() === currentToken) {
                    this._oldSourceUnitCursor.moveToNextSibling();

                    var absolutePosition = this.absolutePosition() + currentToken.fullWidth();
                    var previousToken = currentToken;
                    this._normalParserSource.resetToPosition(absolutePosition, previousToken);

                    if (this._changeRange !== null) {
                    }
                } else {
                    this._changeDelta -= currentToken.fullWidth();

                    this._normalParserSource.moveToNextToken();

                    if (this._changeRange !== null) {
                        var changeRangeSpanInNewText = this._changeRange.newSpan();
                        if (this.absolutePosition() >= changeRangeSpanInNewText.end()) {
                            this._changeDelta += this._changeRange.newLength() - this._changeRange.span().length();
                            this._changeRange = null;
                        }
                    }
                }
            };
            return IncrementalParserSource;
        })();

        var ParserImpl = (function () {
            function ParserImpl(fileName, lineMap, source, parseOptions, newText_forDebuggingPurposesOnly) {
                this.newText_forDebuggingPurposesOnly = newText_forDebuggingPurposesOnly;
                this.listParsingState = 0;
                this.isInStrictMode = false;
                this.diagnostics = [];
                this.factory = TypeScript.Syntax.normalModeFactory;
                this.mergeTokensStorage = [];
                this.arrayPool = [];
                this.fileName = fileName;
                this.lineMap = lineMap;
                this.source = source;
                this.parseOptions = parseOptions;
            }
            ParserImpl.prototype.getRewindPoint = function () {
                var rewindPoint = this.source.getRewindPoint();

                rewindPoint.diagnosticsCount = this.diagnostics.length;

                rewindPoint.isInStrictMode = this.isInStrictMode;
                rewindPoint.listParsingState = this.listParsingState;

                return rewindPoint;
            };

            ParserImpl.prototype.rewind = function (rewindPoint) {
                this.source.rewind(rewindPoint);

                this.diagnostics.length = rewindPoint.diagnosticsCount;
            };

            ParserImpl.prototype.releaseRewindPoint = function (rewindPoint) {
                this.source.releaseRewindPoint(rewindPoint);
            };

            ParserImpl.prototype.currentTokenStart = function () {
                return this.source.absolutePosition() + this.currentToken().leadingTriviaWidth();
            };

            ParserImpl.prototype.previousTokenStart = function () {
                if (this.previousToken() === null) {
                    return 0;
                }

                return this.source.absolutePosition() - this.previousToken().fullWidth() + this.previousToken().leadingTriviaWidth();
            };

            ParserImpl.prototype.previousTokenEnd = function () {
                if (this.previousToken() === null) {
                    return 0;
                }

                return this.previousTokenStart() + this.previousToken().width();
            };

            ParserImpl.prototype.currentNode = function () {
                var node = this.source.currentNode();

                if (node === null || node.parsedInStrictMode() !== this.isInStrictMode) {
                    return null;
                }

                return node;
            };

            ParserImpl.prototype.currentToken = function () {
                return this.source.currentToken();
            };

            ParserImpl.prototype.currentTokenAllowingRegularExpression = function () {
                return this.source.currentTokenAllowingRegularExpression();
            };

            ParserImpl.prototype.peekToken = function (n) {
                return this.source.peekToken(n);
            };

            ParserImpl.prototype.eatAnyToken = function () {
                var token = this.currentToken();
                this.moveToNextToken();
                return token;
            };

            ParserImpl.prototype.moveToNextToken = function () {
                this.source.moveToNextToken();
            };

            ParserImpl.prototype.previousToken = function () {
                return this.source.previousToken();
            };

            ParserImpl.prototype.eatNode = function () {
                var node = this.source.currentNode();
                this.source.moveToNextNode();
                return node;
            };

            ParserImpl.prototype.eatToken = function (kind) {
                var token = this.currentToken();
                if (token.tokenKind === kind) {
                    this.moveToNextToken();
                    return token;
                }

                return this.createMissingToken(kind, token);
            };

            ParserImpl.prototype.tryEatToken = function (kind) {
                if (this.currentToken().tokenKind === kind) {
                    return this.eatToken(kind);
                }

                return null;
            };

            ParserImpl.prototype.eatKeyword = function (kind) {
                var token = this.currentToken();
                if (token.tokenKind === kind) {
                    this.moveToNextToken();
                    return token;
                }

                return this.createMissingToken(kind, token);
            };

            ParserImpl.prototype.isIdentifier = function (token) {
                var tokenKind = token.tokenKind;

                if (tokenKind === 11 /* IdentifierName */) {
                    return true;
                }

                if (tokenKind >= 51 /* FirstFutureReservedStrictKeyword */) {
                    if (tokenKind <= 59 /* LastFutureReservedStrictKeyword */) {
                        return !this.isInStrictMode;
                    }

                    return tokenKind <= 69 /* LastTypeScriptKeyword */;
                }

                return false;
            };

            ParserImpl.prototype.eatIdentifierNameToken = function () {
                var token = this.currentToken();

                if (token.tokenKind === 11 /* IdentifierName */) {
                    this.moveToNextToken();
                    return token;
                }

                if (TypeScript.SyntaxFacts.isAnyKeyword(token.tokenKind)) {
                    this.moveToNextToken();
                    return TypeScript.Syntax.convertToIdentifierName(token);
                }

                return this.createMissingToken(11 /* IdentifierName */, token);
            };

            ParserImpl.prototype.eatIdentifierToken = function () {
                var token = this.currentToken();
                if (this.isIdentifier(token)) {
                    this.moveToNextToken();

                    if (token.tokenKind === 11 /* IdentifierName */) {
                        return token;
                    }

                    return TypeScript.Syntax.convertToIdentifierName(token);
                }

                return this.createMissingToken(11 /* IdentifierName */, token);
            };

            ParserImpl.prototype.canEatAutomaticSemicolon = function (allowWithoutNewLine) {
                var token = this.currentToken();

                if (token.tokenKind === 10 /* EndOfFileToken */) {
                    return true;
                }

                if (token.tokenKind === 71 /* CloseBraceToken */) {
                    return true;
                }

                if (allowWithoutNewLine) {
                    return true;
                }

                if (this.previousToken() !== null && this.previousToken().hasTrailingNewLine()) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.canEatExplicitOrAutomaticSemicolon = function (allowWithoutNewline) {
                var token = this.currentToken();

                if (token.tokenKind === 78 /* SemicolonToken */) {
                    return true;
                }

                return this.canEatAutomaticSemicolon(allowWithoutNewline);
            };

            ParserImpl.prototype.eatExplicitOrAutomaticSemicolon = function (allowWithoutNewline) {
                var token = this.currentToken();

                if (token.tokenKind === 78 /* SemicolonToken */) {
                    return this.eatToken(78 /* SemicolonToken */);
                }

                if (this.canEatAutomaticSemicolon(allowWithoutNewline)) {
                    var semicolonToken = TypeScript.Syntax.emptyToken(78 /* SemicolonToken */);

                    if (!this.parseOptions.allowAutomaticSemicolonInsertion()) {
                        this.addDiagnostic(new TypeScript.Diagnostic(this.fileName, this.lineMap, this.previousTokenEnd(), 0, TypeScript.DiagnosticCode.Automatic_semicolon_insertion_not_allowed, null));
                    }

                    return semicolonToken;
                }

                return this.eatToken(78 /* SemicolonToken */);
            };

            ParserImpl.prototype.isKeyword = function (kind) {
                if (kind >= 15 /* FirstKeyword */) {
                    if (kind <= 50 /* LastFutureReservedKeyword */) {
                        return true;
                    }

                    if (this.isInStrictMode) {
                        return kind <= 59 /* LastFutureReservedStrictKeyword */;
                    }
                }

                return false;
            };

            ParserImpl.prototype.createMissingToken = function (expectedKind, actual) {
                var diagnostic = this.getExpectedTokenDiagnostic(expectedKind, actual);
                this.addDiagnostic(diagnostic);

                return TypeScript.Syntax.emptyToken(expectedKind);
            };

            ParserImpl.prototype.getExpectedTokenDiagnostic = function (expectedKind, actual) {
                var token = this.currentToken();

                if (TypeScript.SyntaxFacts.isAnyKeyword(expectedKind) || TypeScript.SyntaxFacts.isAnyPunctuation(expectedKind)) {
                    return new TypeScript.Diagnostic(this.fileName, this.lineMap, this.currentTokenStart(), token.width(), TypeScript.DiagnosticCode._0_expected, [TypeScript.SyntaxFacts.getText(expectedKind)]);
                } else {
                    if (actual !== null && TypeScript.SyntaxFacts.isAnyKeyword(actual.tokenKind)) {
                        return new TypeScript.Diagnostic(this.fileName, this.lineMap, this.currentTokenStart(), token.width(), TypeScript.DiagnosticCode.Identifier_expected_0_is_a_keyword, [TypeScript.SyntaxFacts.getText(actual.tokenKind)]);
                    } else {
                        return new TypeScript.Diagnostic(this.fileName, this.lineMap, this.currentTokenStart(), token.width(), TypeScript.DiagnosticCode.Identifier_expected, null);
                    }
                }
            };

            ParserImpl.getPrecedence = function (expressionKind) {
                switch (expressionKind) {
                    case 173 /* CommaExpression */:
                        return 1 /* CommaExpressionPrecedence */;

                    case 174 /* AssignmentExpression */:
                    case 175 /* AddAssignmentExpression */:
                    case 176 /* SubtractAssignmentExpression */:
                    case 177 /* MultiplyAssignmentExpression */:
                    case 178 /* DivideAssignmentExpression */:
                    case 179 /* ModuloAssignmentExpression */:
                    case 180 /* AndAssignmentExpression */:
                    case 181 /* ExclusiveOrAssignmentExpression */:
                    case 182 /* OrAssignmentExpression */:
                    case 183 /* LeftShiftAssignmentExpression */:
                    case 184 /* SignedRightShiftAssignmentExpression */:
                    case 185 /* UnsignedRightShiftAssignmentExpression */:
                        return 2 /* AssignmentExpressionPrecedence */;

                    case 186 /* ConditionalExpression */:
                        return 3 /* ConditionalExpressionPrecedence */;

                    case 187 /* LogicalOrExpression */:
                        return 5 /* LogicalOrExpressionPrecedence */;

                    case 188 /* LogicalAndExpression */:
                        return 6 /* LogicalAndExpressionPrecedence */;

                    case 189 /* BitwiseOrExpression */:
                        return 7 /* BitwiseOrExpressionPrecedence */;

                    case 190 /* BitwiseExclusiveOrExpression */:
                        return 8 /* BitwiseExclusiveOrExpressionPrecedence */;

                    case 191 /* BitwiseAndExpression */:
                        return 9 /* BitwiseAndExpressionPrecedence */;

                    case 192 /* EqualsWithTypeConversionExpression */:
                    case 193 /* NotEqualsWithTypeConversionExpression */:
                    case 194 /* EqualsExpression */:
                    case 195 /* NotEqualsExpression */:
                        return 10 /* EqualityExpressionPrecedence */;

                    case 196 /* LessThanExpression */:
                    case 197 /* GreaterThanExpression */:
                    case 198 /* LessThanOrEqualExpression */:
                    case 199 /* GreaterThanOrEqualExpression */:
                    case 200 /* InstanceOfExpression */:
                    case 201 /* InExpression */:
                        return 11 /* RelationalExpressionPrecedence */;

                    case 202 /* LeftShiftExpression */:
                    case 203 /* SignedRightShiftExpression */:
                    case 204 /* UnsignedRightShiftExpression */:
                        return 12 /* ShiftExpressionPrecdence */;

                    case 208 /* AddExpression */:
                    case 209 /* SubtractExpression */:
                        return 13 /* AdditiveExpressionPrecedence */;

                    case 205 /* MultiplyExpression */:
                    case 206 /* DivideExpression */:
                    case 207 /* ModuloExpression */:
                        return 14 /* MultiplicativeExpressionPrecedence */;

                    case 164 /* PlusExpression */:
                    case 165 /* NegateExpression */:
                    case 166 /* BitwiseNotExpression */:
                    case 167 /* LogicalNotExpression */:
                    case 170 /* DeleteExpression */:
                    case 171 /* TypeOfExpression */:
                    case 172 /* VoidExpression */:
                    case 168 /* PreIncrementExpression */:
                    case 169 /* PreDecrementExpression */:
                        return 15 /* UnaryExpressionPrecedence */;
                }

                throw TypeScript.Errors.invalidOperation();
            };

            ParserImpl.prototype.addSkippedTokenAfterNodeOrToken = function (nodeOrToken, skippedToken) {
                if (nodeOrToken.isToken()) {
                    return this.addSkippedTokenAfterToken(nodeOrToken, skippedToken);
                } else if (nodeOrToken.isNode()) {
                    return this.addSkippedTokenAfterNode(nodeOrToken, skippedToken);
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.addSkippedTokenAfterNode = function (node, skippedToken) {
                var oldToken = node.lastToken();
                var newToken = this.addSkippedTokenAfterToken(oldToken, skippedToken);

                return node.replaceToken(oldToken, newToken);
            };

            ParserImpl.prototype.addSkippedTokensBeforeNode = function (node, skippedTokens) {
                if (skippedTokens.length > 0) {
                    var oldToken = node.firstToken();
                    var newToken = this.addSkippedTokensBeforeToken(oldToken, skippedTokens);

                    return node.replaceToken(oldToken, newToken);
                }

                return node;
            };

            ParserImpl.prototype.addSkippedTokensBeforeToken = function (token, skippedTokens) {
                var leadingTrivia = [];
                for (var i = 0, n = skippedTokens.length; i < n; i++) {
                    this.addSkippedTokenToTriviaArray(leadingTrivia, skippedTokens[i]);
                }

                this.addTriviaTo(token.leadingTrivia(), leadingTrivia);

                this.returnArray(skippedTokens);
                return token.withLeadingTrivia(TypeScript.Syntax.triviaList(leadingTrivia));
            };

            ParserImpl.prototype.addSkippedTokensAfterToken = function (token, skippedTokens) {
                if (skippedTokens.length === 0) {
                    this.returnArray(skippedTokens);
                    return token;
                }

                var trailingTrivia = token.trailingTrivia().toArray();

                for (var i = 0, n = skippedTokens.length; i < n; i++) {
                    this.addSkippedTokenToTriviaArray(trailingTrivia, skippedTokens[i]);
                }

                this.returnArray(skippedTokens);
                return token.withTrailingTrivia(TypeScript.Syntax.triviaList(trailingTrivia));
            };

            ParserImpl.prototype.addSkippedTokenAfterToken = function (token, skippedToken) {
                var trailingTrivia = token.trailingTrivia().toArray();
                this.addSkippedTokenToTriviaArray(trailingTrivia, skippedToken);

                return token.withTrailingTrivia(TypeScript.Syntax.triviaList(trailingTrivia));
            };

            ParserImpl.prototype.addSkippedTokenToTriviaArray = function (array, skippedToken) {
                this.addTriviaTo(skippedToken.leadingTrivia(), array);

                var trimmedToken = skippedToken.withLeadingTrivia(TypeScript.Syntax.emptyTriviaList).withTrailingTrivia(TypeScript.Syntax.emptyTriviaList);
                array.push(TypeScript.Syntax.skippedTokenTrivia(trimmedToken));

                this.addTriviaTo(skippedToken.trailingTrivia(), array);
            };

            ParserImpl.prototype.addTriviaTo = function (list, array) {
                for (var i = 0, n = list.count(); i < n; i++) {
                    array.push(list.syntaxTriviaAt(i));
                }
            };

            ParserImpl.prototype.parseSyntaxTree = function (isDeclaration) {
                var sourceUnit = this.parseSourceUnit();

                var allDiagnostics = this.source.tokenDiagnostics().concat(this.diagnostics);
                allDiagnostics.sort(function (a, b) {
                    return a.start() - b.start();
                });

                return new TypeScript.SyntaxTree(sourceUnit, isDeclaration, allDiagnostics, this.fileName, this.lineMap, this.parseOptions);
            };

            ParserImpl.prototype.setStrictMode = function (isInStrictMode) {
                this.isInStrictMode = isInStrictMode;
                this.factory = isInStrictMode ? TypeScript.Syntax.strictModeFactory : TypeScript.Syntax.normalModeFactory;
            };

            ParserImpl.prototype.parseSourceUnit = function () {
                var savedIsInStrictMode = this.isInStrictMode;

                var result = this.parseSyntaxList(1 /* SourceUnit_ModuleElements */, ParserImpl.updateStrictModeState);
                var moduleElements = result.list;

                this.setStrictMode(savedIsInStrictMode);

                var sourceUnit = this.factory.sourceUnit(moduleElements, this.currentToken());
                sourceUnit = this.addSkippedTokensBeforeNode(sourceUnit, result.skippedTokens);

                if (TypeScript.Debug.shouldAssert(2 /* Aggressive */)) {
                    TypeScript.Debug.assert(sourceUnit.fullWidth() === this.newText_forDebuggingPurposesOnly.length());

                    if (TypeScript.Debug.shouldAssert(3 /* VeryAggressive */)) {
                        TypeScript.Debug.assert(sourceUnit.fullText() === this.newText_forDebuggingPurposesOnly.substr(0, this.newText_forDebuggingPurposesOnly.length(), false));
                    }
                }

                return sourceUnit;
            };

            ParserImpl.updateStrictModeState = function (parser, items) {
                if (!parser.isInStrictMode) {
                    for (var i = 0; i < items.length; i++) {
                        var item = items[i];
                        if (!TypeScript.SyntaxFacts.isDirectivePrologueElement(item)) {
                            return;
                        }
                    }

                    parser.setStrictMode(TypeScript.SyntaxFacts.isUseStrictDirective(items[items.length - 1]));
                }
            };

            ParserImpl.prototype.isModuleElement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isModuleElement()) {
                    return true;
                }

                var modifierCount = this.modifierCount();
                return this.isImportDeclaration(modifierCount) || this.isExportAssignment() || this.isModuleDeclaration(modifierCount) || this.isInterfaceDeclaration(modifierCount) || this.isClassDeclaration(modifierCount) || this.isEnumDeclaration(modifierCount) || this.isStatement(inErrorRecovery);
            };

            ParserImpl.prototype.parseModuleElement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isModuleElement()) {
                    return this.eatNode();
                }

                var modifierCount = this.modifierCount();
                if (this.isImportDeclaration(modifierCount)) {
                    return this.parseImportDeclaration();
                } else if (this.isExportAssignment()) {
                    return this.parseExportAssignment();
                } else if (this.isModuleDeclaration(modifierCount)) {
                    return this.parseModuleDeclaration();
                } else if (this.isInterfaceDeclaration(modifierCount)) {
                    return this.parseInterfaceDeclaration();
                } else if (this.isClassDeclaration(modifierCount)) {
                    return this.parseClassDeclaration();
                } else if (this.isEnumDeclaration(modifierCount)) {
                    return this.parseEnumDeclaration();
                } else if (this.isStatement(inErrorRecovery)) {
                    return this.parseStatement(inErrorRecovery);
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.isImportDeclaration = function (modifierCount) {
                if (modifierCount > 0 && this.peekToken(modifierCount).tokenKind === 49 /* ImportKeyword */) {
                    return true;
                }

                return this.currentToken().tokenKind === 49 /* ImportKeyword */ && this.isIdentifier(this.peekToken(1));
            };

            ParserImpl.prototype.parseImportDeclaration = function () {
                var modifiers = this.parseModifiers();
                var importKeyword = this.eatKeyword(49 /* ImportKeyword */);
                var identifier = this.eatIdentifierToken();
                var equalsToken = this.eatToken(107 /* EqualsToken */);
                var moduleReference = this.parseModuleReference();
                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.importDeclaration(modifiers, importKeyword, identifier, equalsToken, moduleReference, semicolonToken);
            };

            ParserImpl.prototype.isExportAssignment = function () {
                return this.currentToken().tokenKind === 47 /* ExportKeyword */ && this.peekToken(1).tokenKind === 107 /* EqualsToken */;
            };

            ParserImpl.prototype.parseExportAssignment = function () {
                var exportKeyword = this.eatKeyword(47 /* ExportKeyword */);
                var equalsToken = this.eatToken(107 /* EqualsToken */);
                var identifier = this.eatIdentifierToken();
                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.exportAssignment(exportKeyword, equalsToken, identifier, semicolonToken);
            };

            ParserImpl.prototype.parseModuleReference = function () {
                if (this.isExternalModuleReference()) {
                    return this.parseExternalModuleReference();
                } else {
                    return this.parseModuleNameModuleReference();
                }
            };

            ParserImpl.prototype.isExternalModuleReference = function () {
                var token0 = this.currentToken();
                if (token0.tokenKind === 66 /* RequireKeyword */) {
                    return this.peekToken(1).tokenKind === 72 /* OpenParenToken */;
                }

                return false;
            };

            ParserImpl.prototype.parseExternalModuleReference = function () {
                var requireKeyword = this.eatKeyword(66 /* RequireKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var stringLiteral = this.eatToken(14 /* StringLiteral */);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);

                return this.factory.externalModuleReference(requireKeyword, openParenToken, stringLiteral, closeParenToken);
            };

            ParserImpl.prototype.parseModuleNameModuleReference = function () {
                var name = this.parseName();
                return this.factory.moduleNameModuleReference(name);
            };

            ParserImpl.prototype.parseIdentifierName = function () {
                var identifierName = this.eatIdentifierNameToken();
                return identifierName;
            };

            ParserImpl.prototype.tryParseTypeArgumentList = function (inExpression) {
                if (this.currentToken().kind() !== 80 /* LessThanToken */) {
                    return null;
                }

                var lessThanToken;
                var greaterThanToken;
                var result;
                var typeArguments;

                if (!inExpression) {
                    lessThanToken = this.eatToken(80 /* LessThanToken */);

                    result = this.parseSeparatedSyntaxList(262144 /* TypeArgumentList_Types */);
                    typeArguments = result.list;
                    lessThanToken = this.addSkippedTokensAfterToken(lessThanToken, result.skippedTokens);

                    greaterThanToken = this.eatToken(81 /* GreaterThanToken */);

                    return this.factory.typeArgumentList(lessThanToken, typeArguments, greaterThanToken);
                }

                var rewindPoint = this.getRewindPoint();

                lessThanToken = this.eatToken(80 /* LessThanToken */);

                result = this.parseSeparatedSyntaxList(262144 /* TypeArgumentList_Types */);
                typeArguments = result.list;
                lessThanToken = this.addSkippedTokensAfterToken(lessThanToken, result.skippedTokens);

                greaterThanToken = this.eatToken(81 /* GreaterThanToken */);

                if (greaterThanToken.fullWidth() === 0 || !this.canFollowTypeArgumentListInExpression(this.currentToken().kind())) {
                    this.rewind(rewindPoint);

                    this.releaseRewindPoint(rewindPoint);
                    return null;
                } else {
                    this.releaseRewindPoint(rewindPoint);
                    var typeArgumentList = this.factory.typeArgumentList(lessThanToken, typeArguments, greaterThanToken);

                    return typeArgumentList;
                }
            };

            ParserImpl.prototype.canFollowTypeArgumentListInExpression = function (kind) {
                switch (kind) {
                    case 72 /* OpenParenToken */:
                    case 76 /* DotToken */:

                    case 73 /* CloseParenToken */:
                    case 75 /* CloseBracketToken */:
                    case 106 /* ColonToken */:
                    case 78 /* SemicolonToken */:
                    case 79 /* CommaToken */:
                    case 105 /* QuestionToken */:
                    case 84 /* EqualsEqualsToken */:
                    case 87 /* EqualsEqualsEqualsToken */:
                    case 86 /* ExclamationEqualsToken */:
                    case 88 /* ExclamationEqualsEqualsToken */:
                    case 103 /* AmpersandAmpersandToken */:
                    case 104 /* BarBarToken */:
                    case 100 /* CaretToken */:
                    case 98 /* AmpersandToken */:
                    case 99 /* BarToken */:
                    case 71 /* CloseBraceToken */:
                    case 10 /* EndOfFileToken */:
                        return true;

                    default:
                        return false;
                }
            };

            ParserImpl.prototype.parseName = function () {
                var shouldContinue = this.isIdentifier(this.currentToken());
                var current = this.eatIdentifierToken();

                while (shouldContinue && this.currentToken().tokenKind === 76 /* DotToken */) {
                    var dotToken = this.eatToken(76 /* DotToken */);

                    var currentToken = this.currentToken();
                    var identifierName;

                    if (TypeScript.SyntaxFacts.isAnyKeyword(currentToken.tokenKind) && this.previousToken().hasTrailingNewLine() && !currentToken.hasTrailingNewLine() && TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(this.peekToken(1))) {
                        identifierName = this.createMissingToken(11 /* IdentifierName */, currentToken);
                    } else {
                        identifierName = this.eatIdentifierNameToken();
                    }

                    current = this.factory.qualifiedName(current, dotToken, identifierName);

                    shouldContinue = identifierName.fullWidth() > 0;
                }

                return current;
            };

            ParserImpl.prototype.isEnumDeclaration = function (modifierCount) {
                if (modifierCount > 0 && this.peekToken(modifierCount).tokenKind === 46 /* EnumKeyword */) {
                    return true;
                }

                return this.currentToken().tokenKind === 46 /* EnumKeyword */ && this.isIdentifier(this.peekToken(1));
            };

            ParserImpl.prototype.parseEnumDeclaration = function () {
                var modifiers = this.parseModifiers();
                var enumKeyword = this.eatKeyword(46 /* EnumKeyword */);
                var identifier = this.eatIdentifierToken();

                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);
                var enumElements = TypeScript.Syntax.emptySeparatedList;

                if (openBraceToken.width() > 0) {
                    var result = this.parseSeparatedSyntaxList(256 /* EnumDeclaration_EnumElements */);
                    enumElements = result.list;
                    openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);
                }

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);

                return this.factory.enumDeclaration(modifiers, enumKeyword, identifier, openBraceToken, enumElements, closeBraceToken);
            };

            ParserImpl.prototype.isEnumElement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().kind() === 243 /* EnumElement */) {
                    return true;
                }

                return this.isPropertyName(this.currentToken(), inErrorRecovery);
            };

            ParserImpl.prototype.parseEnumElement = function () {
                if (this.currentNode() !== null && this.currentNode().kind() === 243 /* EnumElement */) {
                    return this.eatNode();
                }

                var propertyName = this.eatPropertyName();
                var equalsValueClause = null;
                if (this.isEqualsValueClause(false)) {
                    equalsValueClause = this.parseEqualsValueClause(true);
                }

                return this.factory.enumElement(propertyName, equalsValueClause);
            };

            ParserImpl.isModifier = function (token) {
                switch (token.tokenKind) {
                    case 57 /* PublicKeyword */:
                    case 55 /* PrivateKeyword */:
                    case 58 /* StaticKeyword */:
                    case 47 /* ExportKeyword */:
                    case 63 /* DeclareKeyword */:
                        return true;

                    default:
                        return false;
                }
            };

            ParserImpl.prototype.modifierCount = function () {
                var modifierCount = 0;
                while (true) {
                    if (ParserImpl.isModifier(this.peekToken(modifierCount))) {
                        modifierCount++;
                        continue;
                    }

                    break;
                }

                return modifierCount;
            };

            ParserImpl.prototype.parseModifiers = function () {
                var tokens = this.getArray();

                while (true) {
                    if (ParserImpl.isModifier(this.currentToken())) {
                        tokens.push(this.eatAnyToken());
                        continue;
                    }

                    break;
                }

                var result = TypeScript.Syntax.list(tokens);

                this.returnZeroOrOneLengthArray(tokens);

                return result;
            };

            ParserImpl.prototype.isClassDeclaration = function (modifierCount) {
                if (modifierCount > 0 && this.peekToken(modifierCount).tokenKind === 44 /* ClassKeyword */) {
                    return true;
                }

                return this.currentToken().tokenKind === 44 /* ClassKeyword */ && this.isIdentifier(this.peekToken(1));
            };

            ParserImpl.prototype.parseHeritageClauses = function () {
                var heritageClauses = TypeScript.Syntax.emptyList;

                if (this.isHeritageClause()) {
                    var result = this.parseSyntaxList(1024 /* ClassOrInterfaceDeclaration_HeritageClauses */);
                    heritageClauses = result.list;
                    TypeScript.Debug.assert(result.skippedTokens.length === 0);
                }

                return heritageClauses;
            };

            ParserImpl.prototype.parseClassDeclaration = function () {
                var modifiers = this.parseModifiers();

                var classKeyword = this.eatKeyword(44 /* ClassKeyword */);
                var identifier = this.eatIdentifierToken();
                var typeParameterList = this.parseOptionalTypeParameterList(false);
                var heritageClauses = this.parseHeritageClauses();
                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);
                var classElements = TypeScript.Syntax.emptyList;

                if (openBraceToken.width() > 0) {
                    var result = this.parseSyntaxList(2 /* ClassDeclaration_ClassElements */);

                    classElements = result.list;
                    openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);
                }

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);
                return this.factory.classDeclaration(modifiers, classKeyword, identifier, typeParameterList, heritageClauses, openBraceToken, classElements, closeBraceToken);
            };

            ParserImpl.isPublicOrPrivateKeyword = function (token) {
                return token.tokenKind === 57 /* PublicKeyword */ || token.tokenKind === 55 /* PrivateKeyword */;
            };

            ParserImpl.prototype.isAccessor = function (inErrorRecovery) {
                var index = this.modifierCount();

                if (this.peekToken(index).tokenKind !== 64 /* GetKeyword */ && this.peekToken(index).tokenKind !== 68 /* SetKeyword */) {
                    return false;
                }

                index++;
                return this.isPropertyName(this.peekToken(index), inErrorRecovery);
            };

            ParserImpl.prototype.parseAccessor = function (checkForStrictMode) {
                var modifiers = this.parseModifiers();

                if (this.currentToken().tokenKind === 64 /* GetKeyword */) {
                    return this.parseGetMemberAccessorDeclaration(modifiers, checkForStrictMode);
                } else if (this.currentToken().tokenKind === 68 /* SetKeyword */) {
                    return this.parseSetMemberAccessorDeclaration(modifiers, checkForStrictMode);
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.parseGetMemberAccessorDeclaration = function (modifiers, checkForStrictMode) {
                var getKeyword = this.eatKeyword(64 /* GetKeyword */);
                var propertyName = this.eatPropertyName();
                var parameterList = this.parseParameterList();
                var typeAnnotation = this.parseOptionalTypeAnnotation(false);
                var block = this.parseBlock(false, checkForStrictMode);

                return this.factory.getAccessor(modifiers, getKeyword, propertyName, parameterList, typeAnnotation, block);
            };

            ParserImpl.prototype.parseSetMemberAccessorDeclaration = function (modifiers, checkForStrictMode) {
                var setKeyword = this.eatKeyword(68 /* SetKeyword */);
                var propertyName = this.eatPropertyName();
                var parameterList = this.parseParameterList();
                var block = this.parseBlock(false, checkForStrictMode);

                return this.factory.setAccessor(modifiers, setKeyword, propertyName, parameterList, block);
            };

            ParserImpl.prototype.isClassElement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isClassElement()) {
                    return true;
                }

                return this.isConstructorDeclaration() || this.isMemberFunctionDeclaration(inErrorRecovery) || this.isAccessor(inErrorRecovery) || this.isMemberVariableDeclaration(inErrorRecovery) || this.isIndexMemberDeclaration();
            };

            ParserImpl.prototype.parseClassElement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isClassElement()) {
                    return this.eatNode();
                }

                if (this.isConstructorDeclaration()) {
                    return this.parseConstructorDeclaration();
                } else if (this.isMemberFunctionDeclaration(inErrorRecovery)) {
                    return this.parseMemberFunctionDeclaration();
                } else if (this.isAccessor(inErrorRecovery)) {
                    return this.parseAccessor(false);
                } else if (this.isMemberVariableDeclaration(inErrorRecovery)) {
                    return this.parseMemberVariableDeclaration();
                } else if (this.isIndexMemberDeclaration()) {
                    return this.parseIndexMemberDeclaration();
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.isConstructorDeclaration = function () {
                var index = this.modifierCount();
                return this.peekToken(index).tokenKind === 62 /* ConstructorKeyword */;
            };

            ParserImpl.prototype.parseConstructorDeclaration = function () {
                var modifiers = this.parseModifiers();
                var constructorKeyword = this.eatKeyword(62 /* ConstructorKeyword */);
                var callSignature = this.parseCallSignature(false);

                var semicolonToken = null;
                var block = null;

                if (this.isBlock()) {
                    block = this.parseBlock(false, true);
                } else {
                    semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);
                }

                return this.factory.constructorDeclaration(modifiers, constructorKeyword, callSignature, block, semicolonToken);
            };

            ParserImpl.prototype.isMemberFunctionDeclaration = function (inErrorRecovery) {
                var index = 0;

                while (true) {
                    var token = this.peekToken(index);
                    if (this.isPropertyName(token, inErrorRecovery) && this.isCallSignature(index + 1)) {
                        return true;
                    }

                    if (ParserImpl.isModifier(token)) {
                        index++;
                        continue;
                    }

                    return false;
                }
            };

            ParserImpl.prototype.parseMemberFunctionDeclaration = function () {
                var modifierArray = this.getArray();

                while (true) {
                    var currentToken = this.currentToken();
                    if (this.isPropertyName(currentToken, false) && this.isCallSignature(1)) {
                        break;
                    }

                    TypeScript.Debug.assert(ParserImpl.isModifier(currentToken));
                    modifierArray.push(this.eatAnyToken());
                }

                var modifiers = TypeScript.Syntax.list(modifierArray);
                this.returnZeroOrOneLengthArray(modifierArray);

                var propertyName = this.eatPropertyName();
                var callSignature = this.parseCallSignature(false);

                var parseBlockEvenWithNoOpenBrace = false;
                var newCallSignature = this.tryAddUnexpectedEqualsGreaterThanToken(callSignature);
                if (newCallSignature !== callSignature) {
                    parseBlockEvenWithNoOpenBrace = true;
                    callSignature = newCallSignature;
                }

                var block = null;
                var semicolon = null;

                if (parseBlockEvenWithNoOpenBrace || this.isBlock()) {
                    block = this.parseBlock(parseBlockEvenWithNoOpenBrace, true);
                } else {
                    semicolon = this.eatExplicitOrAutomaticSemicolon(false);
                }

                return this.factory.memberFunctionDeclaration(modifiers, propertyName, callSignature, block, semicolon);
            };

            ParserImpl.prototype.isDefinitelyMemberVariablePropertyName = function (index) {
                if (TypeScript.SyntaxFacts.isAnyKeyword(this.peekToken(index).tokenKind)) {
                    switch (this.peekToken(index + 1).tokenKind) {
                        case 78 /* SemicolonToken */:
                        case 107 /* EqualsToken */:
                        case 106 /* ColonToken */:
                        case 71 /* CloseBraceToken */:
                        case 10 /* EndOfFileToken */:
                            return true;
                        default:
                            return false;
                    }
                } else {
                    return true;
                }
            };

            ParserImpl.prototype.isMemberVariableDeclaration = function (inErrorRecovery) {
                var index = 0;

                while (true) {
                    var token = this.peekToken(index);
                    if (this.isPropertyName(token, inErrorRecovery) && this.isDefinitelyMemberVariablePropertyName(index)) {
                        return true;
                    }

                    if (ParserImpl.isModifier(this.peekToken(index))) {
                        index++;
                        continue;
                    }

                    return false;
                }
            };

            ParserImpl.prototype.parseMemberVariableDeclaration = function () {
                var modifierArray = this.getArray();

                while (true) {
                    var currentToken = this.currentToken();
                    if (this.isPropertyName(currentToken, false) && this.isDefinitelyMemberVariablePropertyName(0)) {
                        break;
                    }

                    TypeScript.Debug.assert(ParserImpl.isModifier(currentToken));
                    modifierArray.push(this.eatAnyToken());
                }

                var modifiers = TypeScript.Syntax.list(modifierArray);
                this.returnZeroOrOneLengthArray(modifierArray);

                var variableDeclarator = this.parseVariableDeclarator(true, true);
                var semicolon = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.memberVariableDeclaration(modifiers, variableDeclarator, semicolon);
            };

            ParserImpl.prototype.isIndexMemberDeclaration = function () {
                var index = this.modifierCount();
                return this.isIndexSignature(index);
            };

            ParserImpl.prototype.parseIndexMemberDeclaration = function () {
                var modifiers = this.parseModifiers();
                var indexSignature = this.parseIndexSignature();
                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.indexMemberDeclaration(modifiers, indexSignature, semicolonToken);
            };

            ParserImpl.prototype.tryAddUnexpectedEqualsGreaterThanToken = function (callSignature) {
                var token0 = this.currentToken();

                var hasEqualsGreaterThanToken = token0.tokenKind === 85 /* EqualsGreaterThanToken */;
                if (hasEqualsGreaterThanToken) {
                    if (callSignature.lastToken()) {
                        var diagnostic = new TypeScript.Diagnostic(this.fileName, this.lineMap, this.currentTokenStart(), token0.width(), TypeScript.DiagnosticCode.Unexpected_token_0_expected, [TypeScript.SyntaxFacts.getText(70 /* OpenBraceToken */)]);
                        this.addDiagnostic(diagnostic);

                        var token = this.eatAnyToken();
                        return this.addSkippedTokenAfterNode(callSignature, token0);
                    }
                }

                return callSignature;
            };

            ParserImpl.prototype.isFunctionDeclaration = function () {
                var index = this.modifierCount();
                return this.peekToken(index).tokenKind === 27 /* FunctionKeyword */;
            };

            ParserImpl.prototype.parseFunctionDeclaration = function () {
                var modifiers = this.parseModifiers();
                var functionKeyword = this.eatKeyword(27 /* FunctionKeyword */);
                var identifier = this.eatIdentifierToken();
                var callSignature = this.parseCallSignature(false);

                var parseBlockEvenWithNoOpenBrace = false;
                var newCallSignature = this.tryAddUnexpectedEqualsGreaterThanToken(callSignature);
                if (newCallSignature !== callSignature) {
                    parseBlockEvenWithNoOpenBrace = true;
                    callSignature = newCallSignature;
                }

                var semicolonToken = null;
                var block = null;

                if (parseBlockEvenWithNoOpenBrace || this.isBlock()) {
                    block = this.parseBlock(parseBlockEvenWithNoOpenBrace, true);
                } else {
                    semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);
                }

                return this.factory.functionDeclaration(modifiers, functionKeyword, identifier, callSignature, block, semicolonToken);
            };

            ParserImpl.prototype.isModuleDeclaration = function (modifierCount) {
                if (modifierCount > 0 && this.peekToken(modifierCount).tokenKind === 65 /* ModuleKeyword */) {
                    return true;
                }

                if (this.currentToken().tokenKind === 65 /* ModuleKeyword */) {
                    var token1 = this.peekToken(1);
                    return this.isIdentifier(token1) || token1.tokenKind === 14 /* StringLiteral */;
                }

                return false;
            };

            ParserImpl.prototype.parseModuleDeclaration = function () {
                var modifiers = this.parseModifiers();
                var moduleKeyword = this.eatKeyword(65 /* ModuleKeyword */);

                var moduleName = null;
                var stringLiteral = null;

                if (this.currentToken().tokenKind === 14 /* StringLiteral */) {
                    stringLiteral = this.eatToken(14 /* StringLiteral */);
                } else {
                    moduleName = this.parseName();
                }

                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);

                var moduleElements = TypeScript.Syntax.emptyList;
                if (openBraceToken.width() > 0) {
                    var result = this.parseSyntaxList(4 /* ModuleDeclaration_ModuleElements */);
                    moduleElements = result.list;
                    openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);
                }

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);

                return this.factory.moduleDeclaration(modifiers, moduleKeyword, moduleName, stringLiteral, openBraceToken, moduleElements, closeBraceToken);
            };

            ParserImpl.prototype.isInterfaceDeclaration = function (modifierCount) {
                if (modifierCount > 0 && this.peekToken(modifierCount).tokenKind === 52 /* InterfaceKeyword */) {
                    return true;
                }

                return this.currentToken().tokenKind === 52 /* InterfaceKeyword */ && this.isIdentifier(this.peekToken(1));
            };

            ParserImpl.prototype.parseInterfaceDeclaration = function () {
                var modifiers = this.parseModifiers();
                var interfaceKeyword = this.eatKeyword(52 /* InterfaceKeyword */);
                var identifier = this.eatIdentifierToken();
                var typeParameterList = this.parseOptionalTypeParameterList(false);
                var heritageClauses = this.parseHeritageClauses();

                var objectType = this.parseObjectType();
                return this.factory.interfaceDeclaration(modifiers, interfaceKeyword, identifier, typeParameterList, heritageClauses, objectType);
            };

            ParserImpl.prototype.parseObjectType = function () {
                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);

                var typeMembers = TypeScript.Syntax.emptySeparatedList;
                if (openBraceToken.width() > 0) {
                    var result = this.parseSeparatedSyntaxList(512 /* ObjectType_TypeMembers */);
                    typeMembers = result.list;
                    openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);
                }

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);
                return this.factory.objectType(openBraceToken, typeMembers, closeBraceToken);
            };

            ParserImpl.prototype.isTypeMember = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isTypeMember()) {
                    return true;
                }

                return this.isCallSignature(0) || this.isConstructSignature() || this.isIndexSignature(0) || this.isMethodSignature(inErrorRecovery) || this.isPropertySignature(inErrorRecovery);
            };

            ParserImpl.prototype.parseTypeMember = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isTypeMember()) {
                    return this.eatNode();
                }

                if (this.isCallSignature(0)) {
                    return this.parseCallSignature(false);
                } else if (this.isConstructSignature()) {
                    return this.parseConstructSignature();
                } else if (this.isIndexSignature(0)) {
                    return this.parseIndexSignature();
                } else if (this.isMethodSignature(inErrorRecovery)) {
                    return this.parseMethodSignature();
                } else if (this.isPropertySignature(inErrorRecovery)) {
                    return this.parsePropertySignature();
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.parseConstructSignature = function () {
                var newKeyword = this.eatKeyword(31 /* NewKeyword */);
                var callSignature = this.parseCallSignature(false);

                return this.factory.constructSignature(newKeyword, callSignature);
            };

            ParserImpl.prototype.parseIndexSignature = function () {
                var openBracketToken = this.eatToken(74 /* OpenBracketToken */);
                var parameter = this.parseParameter();
                var closeBracketToken = this.eatToken(75 /* CloseBracketToken */);
                var typeAnnotation = this.parseOptionalTypeAnnotation(false);

                return this.factory.indexSignature(openBracketToken, parameter, closeBracketToken, typeAnnotation);
            };

            ParserImpl.prototype.parseMethodSignature = function () {
                var propertyName = this.eatPropertyName();
                var questionToken = this.tryEatToken(105 /* QuestionToken */);
                var callSignature = this.parseCallSignature(false);

                return this.factory.methodSignature(propertyName, questionToken, callSignature);
            };

            ParserImpl.prototype.parsePropertySignature = function () {
                var propertyName = this.eatPropertyName();
                var questionToken = this.tryEatToken(105 /* QuestionToken */);
                var typeAnnotation = this.parseOptionalTypeAnnotation(false);

                return this.factory.propertySignature(propertyName, questionToken, typeAnnotation);
            };

            ParserImpl.prototype.isCallSignature = function (tokenIndex) {
                var tokenKind = this.peekToken(tokenIndex).tokenKind;
                return tokenKind === 72 /* OpenParenToken */ || tokenKind === 80 /* LessThanToken */;
            };

            ParserImpl.prototype.isConstructSignature = function () {
                if (this.currentToken().tokenKind !== 31 /* NewKeyword */) {
                    return false;
                }

                var token1 = this.peekToken(1);
                return token1.tokenKind === 80 /* LessThanToken */ || token1.tokenKind === 72 /* OpenParenToken */;
            };

            ParserImpl.prototype.isIndexSignature = function (tokenIndex) {
                return this.peekToken(tokenIndex).tokenKind === 74 /* OpenBracketToken */;
            };

            ParserImpl.prototype.isMethodSignature = function (inErrorRecovery) {
                if (this.isPropertyName(this.currentToken(), inErrorRecovery)) {
                    if (this.isCallSignature(1)) {
                        return true;
                    }

                    if (this.peekToken(1).tokenKind === 105 /* QuestionToken */ && this.isCallSignature(2)) {
                        return true;
                    }
                }

                return false;
            };

            ParserImpl.prototype.isPropertySignature = function (inErrorRecovery) {
                var currentToken = this.currentToken();

                if (ParserImpl.isModifier(currentToken) && !currentToken.hasTrailingNewLine() && this.isPropertyName(this.peekToken(1), inErrorRecovery)) {
                    return false;
                }

                return this.isPropertyName(currentToken, inErrorRecovery);
            };

            ParserImpl.prototype.isHeritageClause = function () {
                var token0 = this.currentToken();
                return token0.tokenKind === 48 /* ExtendsKeyword */ || token0.tokenKind === 51 /* ImplementsKeyword */;
            };

            ParserImpl.prototype.isNotHeritageClauseTypeName = function () {
                if (this.currentToken().tokenKind === 51 /* ImplementsKeyword */ || this.currentToken().tokenKind === 48 /* ExtendsKeyword */) {
                    return this.isIdentifier(this.peekToken(1));
                }

                return false;
            };

            ParserImpl.prototype.isHeritageClauseTypeName = function () {
                if (this.isIdentifier(this.currentToken())) {
                    return !this.isNotHeritageClauseTypeName();
                }

                return false;
            };

            ParserImpl.prototype.parseHeritageClause = function () {
                var extendsOrImplementsKeyword = this.eatAnyToken();
                TypeScript.Debug.assert(extendsOrImplementsKeyword.tokenKind === 48 /* ExtendsKeyword */ || extendsOrImplementsKeyword.tokenKind === 51 /* ImplementsKeyword */);

                var result = this.parseSeparatedSyntaxList(2048 /* HeritageClause_TypeNameList */);
                var typeNames = result.list;
                extendsOrImplementsKeyword = this.addSkippedTokensAfterToken(extendsOrImplementsKeyword, result.skippedTokens);

                return this.factory.heritageClause(extendsOrImplementsKeyword.tokenKind === 48 /* ExtendsKeyword */ ? 230 /* ExtendsHeritageClause */ : 231 /* ImplementsHeritageClause */, extendsOrImplementsKeyword, typeNames);
            };

            ParserImpl.prototype.isStatement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isStatement()) {
                    return true;
                }

                var currentToken = this.currentToken();
                var currentTokenKind = currentToken.tokenKind;
                switch (currentTokenKind) {
                    case 57 /* PublicKeyword */:
                    case 55 /* PrivateKeyword */:
                    case 58 /* StaticKeyword */:
                        var token1 = this.peekToken(1);
                        if (TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(token1)) {
                            return false;
                        }

                        break;

                    case 28 /* IfKeyword */:
                    case 70 /* OpenBraceToken */:
                    case 33 /* ReturnKeyword */:
                    case 34 /* SwitchKeyword */:
                    case 36 /* ThrowKeyword */:
                    case 15 /* BreakKeyword */:
                    case 18 /* ContinueKeyword */:
                    case 26 /* ForKeyword */:
                    case 42 /* WhileKeyword */:
                    case 43 /* WithKeyword */:
                    case 22 /* DoKeyword */:
                    case 38 /* TryKeyword */:
                    case 19 /* DebuggerKeyword */:
                        return true;
                }

                if (this.isInterfaceDeclaration(0) || this.isClassDeclaration(0) || this.isEnumDeclaration(0) || this.isModuleDeclaration(0)) {
                    return false;
                }

                return this.isLabeledStatement(currentToken) || this.isVariableStatement() || this.isFunctionDeclaration() || this.isEmptyStatement(currentToken, inErrorRecovery) || this.isExpressionStatement(currentToken);
            };

            ParserImpl.prototype.parseStatement = function (inErrorRecovery) {
                if (this.currentNode() !== null && this.currentNode().isStatement()) {
                    return this.eatNode();
                }

                var currentToken = this.currentToken();
                var currentTokenKind = currentToken.tokenKind;

                switch (currentTokenKind) {
                    case 28 /* IfKeyword */:
                        return this.parseIfStatement();
                    case 70 /* OpenBraceToken */:
                        return this.parseBlock(false, false);
                    case 33 /* ReturnKeyword */:
                        return this.parseReturnStatement();
                    case 34 /* SwitchKeyword */:
                        return this.parseSwitchStatement();
                    case 36 /* ThrowKeyword */:
                        return this.parseThrowStatement();
                    case 15 /* BreakKeyword */:
                        return this.parseBreakStatement();
                    case 18 /* ContinueKeyword */:
                        return this.parseContinueStatement();
                    case 26 /* ForKeyword */:
                        return this.parseForOrForInStatement();
                    case 42 /* WhileKeyword */:
                        return this.parseWhileStatement();
                    case 43 /* WithKeyword */:
                        return this.parseWithStatement();
                    case 22 /* DoKeyword */:
                        return this.parseDoStatement();
                    case 38 /* TryKeyword */:
                        return this.parseTryStatement();
                    case 19 /* DebuggerKeyword */:
                        return this.parseDebuggerStatement();
                }

                if (this.isVariableStatement()) {
                    return this.parseVariableStatement();
                } else if (this.isLabeledStatement(currentToken)) {
                    return this.parseLabeledStatement();
                } else if (this.isFunctionDeclaration()) {
                    return this.parseFunctionDeclaration();
                } else if (this.isEmptyStatement(currentToken, inErrorRecovery)) {
                    return this.parseEmptyStatement();
                } else {
                    return this.parseExpressionStatement();
                }
            };

            ParserImpl.prototype.parseDebuggerStatement = function () {
                var debuggerKeyword = this.eatKeyword(19 /* DebuggerKeyword */);
                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.debuggerStatement(debuggerKeyword, semicolonToken);
            };

            ParserImpl.prototype.parseDoStatement = function () {
                var doKeyword = this.eatKeyword(22 /* DoKeyword */);
                var statement = this.parseStatement(false);
                var whileKeyword = this.eatKeyword(42 /* WhileKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var condition = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);

                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(true);

                return this.factory.doStatement(doKeyword, statement, whileKeyword, openParenToken, condition, closeParenToken, semicolonToken);
            };

            ParserImpl.prototype.isLabeledStatement = function (currentToken) {
                return this.isIdentifier(currentToken) && this.peekToken(1).tokenKind === 106 /* ColonToken */;
            };

            ParserImpl.prototype.parseLabeledStatement = function () {
                var identifier = this.eatIdentifierToken();
                var colonToken = this.eatToken(106 /* ColonToken */);
                var statement = this.parseStatement(false);

                return this.factory.labeledStatement(identifier, colonToken, statement);
            };

            ParserImpl.prototype.parseTryStatement = function () {
                var tryKeyword = this.eatKeyword(38 /* TryKeyword */);

                var savedListParsingState = this.listParsingState;
                this.listParsingState |= 64 /* TryBlock_Statements */;
                var block = this.parseBlock(false, false);
                this.listParsingState = savedListParsingState;

                var catchClause = null;
                if (this.isCatchClause()) {
                    catchClause = this.parseCatchClause();
                }

                var finallyClause = null;
                if (catchClause === null || this.isFinallyClause()) {
                    finallyClause = this.parseFinallyClause();
                }

                return this.factory.tryStatement(tryKeyword, block, catchClause, finallyClause);
            };

            ParserImpl.prototype.isCatchClause = function () {
                return this.currentToken().tokenKind === 17 /* CatchKeyword */;
            };

            ParserImpl.prototype.parseCatchClause = function () {
                var catchKeyword = this.eatKeyword(17 /* CatchKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var identifier = this.eatIdentifierToken();
                var typeAnnotation = this.parseOptionalTypeAnnotation(false);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);

                var savedListParsingState = this.listParsingState;
                this.listParsingState |= 128 /* CatchBlock_Statements */;
                var block = this.parseBlock(false, false);
                this.listParsingState = savedListParsingState;

                return this.factory.catchClause(catchKeyword, openParenToken, identifier, typeAnnotation, closeParenToken, block);
            };

            ParserImpl.prototype.isFinallyClause = function () {
                return this.currentToken().tokenKind === 25 /* FinallyKeyword */;
            };

            ParserImpl.prototype.parseFinallyClause = function () {
                var finallyKeyword = this.eatKeyword(25 /* FinallyKeyword */);
                var block = this.parseBlock(false, false);

                return this.factory.finallyClause(finallyKeyword, block);
            };

            ParserImpl.prototype.parseWithStatement = function () {
                var withKeyword = this.eatKeyword(43 /* WithKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var condition = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);
                var statement = this.parseStatement(false);

                return this.factory.withStatement(withKeyword, openParenToken, condition, closeParenToken, statement);
            };

            ParserImpl.prototype.parseWhileStatement = function () {
                var whileKeyword = this.eatKeyword(42 /* WhileKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var condition = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);
                var statement = this.parseStatement(false);

                return this.factory.whileStatement(whileKeyword, openParenToken, condition, closeParenToken, statement);
            };

            ParserImpl.prototype.isEmptyStatement = function (currentToken, inErrorRecovery) {
                if (inErrorRecovery) {
                    return false;
                }

                return currentToken.tokenKind === 78 /* SemicolonToken */;
            };

            ParserImpl.prototype.parseEmptyStatement = function () {
                var semicolonToken = this.eatToken(78 /* SemicolonToken */);
                return this.factory.emptyStatement(semicolonToken);
            };

            ParserImpl.prototype.parseForOrForInStatement = function () {
                var forKeyword = this.eatKeyword(26 /* ForKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);

                var currentToken = this.currentToken();
                if (currentToken.tokenKind === 40 /* VarKeyword */) {
                    return this.parseForOrForInStatementWithVariableDeclaration(forKeyword, openParenToken);
                } else if (currentToken.tokenKind === 78 /* SemicolonToken */) {
                    return this.parseForStatementWithNoVariableDeclarationOrInitializer(forKeyword, openParenToken);
                } else {
                    return this.parseForOrForInStatementWithInitializer(forKeyword, openParenToken);
                }
            };

            ParserImpl.prototype.parseForOrForInStatementWithVariableDeclaration = function (forKeyword, openParenToken) {
                var variableDeclaration = this.parseVariableDeclaration(false);

                if (this.currentToken().tokenKind === 29 /* InKeyword */) {
                    return this.parseForInStatementWithVariableDeclarationOrInitializer(forKeyword, openParenToken, variableDeclaration, null);
                }

                return this.parseForStatementWithVariableDeclarationOrInitializer(forKeyword, openParenToken, variableDeclaration, null);
            };

            ParserImpl.prototype.parseForInStatementWithVariableDeclarationOrInitializer = function (forKeyword, openParenToken, variableDeclaration, initializer) {
                var inKeyword = this.eatKeyword(29 /* InKeyword */);
                var expression = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);
                var statement = this.parseStatement(false);

                return this.factory.forInStatement(forKeyword, openParenToken, variableDeclaration, initializer, inKeyword, expression, closeParenToken, statement);
            };

            ParserImpl.prototype.parseForOrForInStatementWithInitializer = function (forKeyword, openParenToken) {
                var initializer = this.parseExpression(false);
                if (this.currentToken().tokenKind === 29 /* InKeyword */) {
                    return this.parseForInStatementWithVariableDeclarationOrInitializer(forKeyword, openParenToken, null, initializer);
                } else {
                    return this.parseForStatementWithVariableDeclarationOrInitializer(forKeyword, openParenToken, null, initializer);
                }
            };

            ParserImpl.prototype.parseForStatementWithNoVariableDeclarationOrInitializer = function (forKeyword, openParenToken) {
                return this.parseForStatementWithVariableDeclarationOrInitializer(forKeyword, openParenToken, null, null);
            };

            ParserImpl.prototype.parseForStatementWithVariableDeclarationOrInitializer = function (forKeyword, openParenToken, variableDeclaration, initializer) {
                var firstSemicolonToken = this.eatToken(78 /* SemicolonToken */);

                var condition = null;
                if (this.currentToken().tokenKind !== 78 /* SemicolonToken */ && this.currentToken().tokenKind !== 73 /* CloseParenToken */ && this.currentToken().tokenKind !== 10 /* EndOfFileToken */) {
                    condition = this.parseExpression(true);
                }

                var secondSemicolonToken = this.eatToken(78 /* SemicolonToken */);

                var incrementor = null;
                if (this.currentToken().tokenKind !== 73 /* CloseParenToken */ && this.currentToken().tokenKind !== 10 /* EndOfFileToken */) {
                    incrementor = this.parseExpression(true);
                }

                var closeParenToken = this.eatToken(73 /* CloseParenToken */);
                var statement = this.parseStatement(false);

                return this.factory.forStatement(forKeyword, openParenToken, variableDeclaration, initializer, firstSemicolonToken, condition, secondSemicolonToken, incrementor, closeParenToken, statement);
            };

            ParserImpl.prototype.parseBreakStatement = function () {
                var breakKeyword = this.eatKeyword(15 /* BreakKeyword */);

                var identifier = null;
                if (!this.canEatExplicitOrAutomaticSemicolon(false)) {
                    if (this.isIdentifier(this.currentToken())) {
                        identifier = this.eatIdentifierToken();
                    }
                }

                var semicolon = this.eatExplicitOrAutomaticSemicolon(false);
                return this.factory.breakStatement(breakKeyword, identifier, semicolon);
            };

            ParserImpl.prototype.parseContinueStatement = function () {
                var continueKeyword = this.eatKeyword(18 /* ContinueKeyword */);

                var identifier = null;
                if (!this.canEatExplicitOrAutomaticSemicolon(false)) {
                    if (this.isIdentifier(this.currentToken())) {
                        identifier = this.eatIdentifierToken();
                    }
                }

                var semicolon = this.eatExplicitOrAutomaticSemicolon(false);
                return this.factory.continueStatement(continueKeyword, identifier, semicolon);
            };

            ParserImpl.prototype.parseSwitchStatement = function () {
                var switchKeyword = this.eatKeyword(34 /* SwitchKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var expression = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);

                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);

                var switchClauses = TypeScript.Syntax.emptyList;
                if (openBraceToken.width() > 0) {
                    var result = this.parseSyntaxList(8 /* SwitchStatement_SwitchClauses */);
                    switchClauses = result.list;
                    openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);
                }

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);
                return this.factory.switchStatement(switchKeyword, openParenToken, expression, closeParenToken, openBraceToken, switchClauses, closeBraceToken);
            };

            ParserImpl.prototype.isCaseSwitchClause = function () {
                return this.currentToken().tokenKind === 16 /* CaseKeyword */;
            };

            ParserImpl.prototype.isDefaultSwitchClause = function () {
                return this.currentToken().tokenKind === 20 /* DefaultKeyword */;
            };

            ParserImpl.prototype.isSwitchClause = function () {
                if (this.currentNode() !== null && this.currentNode().isSwitchClause()) {
                    return true;
                }

                return this.isCaseSwitchClause() || this.isDefaultSwitchClause();
            };

            ParserImpl.prototype.parseSwitchClause = function () {
                if (this.currentNode() !== null && this.currentNode().isSwitchClause()) {
                    return this.eatNode();
                }

                if (this.isCaseSwitchClause()) {
                    return this.parseCaseSwitchClause();
                } else if (this.isDefaultSwitchClause()) {
                    return this.parseDefaultSwitchClause();
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.parseCaseSwitchClause = function () {
                var caseKeyword = this.eatKeyword(16 /* CaseKeyword */);
                var expression = this.parseExpression(true);
                var colonToken = this.eatToken(106 /* ColonToken */);
                var statements = TypeScript.Syntax.emptyList;

                if (colonToken.fullWidth() > 0) {
                    var result = this.parseSyntaxList(16 /* SwitchClause_Statements */);
                    statements = result.list;
                    colonToken = this.addSkippedTokensAfterToken(colonToken, result.skippedTokens);
                }

                return this.factory.caseSwitchClause(caseKeyword, expression, colonToken, statements);
            };

            ParserImpl.prototype.parseDefaultSwitchClause = function () {
                var defaultKeyword = this.eatKeyword(20 /* DefaultKeyword */);
                var colonToken = this.eatToken(106 /* ColonToken */);
                var statements = TypeScript.Syntax.emptyList;

                if (colonToken.fullWidth() > 0) {
                    var result = this.parseSyntaxList(16 /* SwitchClause_Statements */);
                    statements = result.list;
                    colonToken = this.addSkippedTokensAfterToken(colonToken, result.skippedTokens);
                }

                return this.factory.defaultSwitchClause(defaultKeyword, colonToken, statements);
            };

            ParserImpl.prototype.parseThrowStatement = function () {
                var throwKeyword = this.eatKeyword(36 /* ThrowKeyword */);

                var expression = null;
                if (this.canEatExplicitOrAutomaticSemicolon(false)) {
                    var token = this.createMissingToken(11 /* IdentifierName */, null);
                    expression = token;
                } else {
                    expression = this.parseExpression(true);
                }

                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.throwStatement(throwKeyword, expression, semicolonToken);
            };

            ParserImpl.prototype.parseReturnStatement = function () {
                var returnKeyword = this.eatKeyword(33 /* ReturnKeyword */);

                var expression = null;
                if (!this.canEatExplicitOrAutomaticSemicolon(false)) {
                    expression = this.parseExpression(true);
                }

                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.returnStatement(returnKeyword, expression, semicolonToken);
            };

            ParserImpl.prototype.isExpressionStatement = function (currentToken) {
                var kind = currentToken.tokenKind;
                if (kind === 70 /* OpenBraceToken */ || kind === 27 /* FunctionKeyword */) {
                    return false;
                }

                return this.isExpression(currentToken);
            };

            ParserImpl.prototype.isAssignmentOrOmittedExpression = function () {
                var currentToken = this.currentToken();
                if (currentToken.tokenKind === 79 /* CommaToken */) {
                    return true;
                }

                return this.isExpression(currentToken);
            };

            ParserImpl.prototype.parseAssignmentOrOmittedExpression = function () {
                if (this.currentToken().tokenKind === 79 /* CommaToken */) {
                    return this.factory.omittedExpression();
                }

                return this.parseAssignmentExpression(true);
            };

            ParserImpl.prototype.isExpression = function (currentToken) {
                switch (currentToken.tokenKind) {
                    case 13 /* NumericLiteral */:
                    case 14 /* StringLiteral */:
                    case 12 /* RegularExpressionLiteral */:

                    case 74 /* OpenBracketToken */:

                    case 72 /* OpenParenToken */:

                    case 80 /* LessThanToken */:

                    case 93 /* PlusPlusToken */:
                    case 94 /* MinusMinusToken */:
                    case 89 /* PlusToken */:
                    case 90 /* MinusToken */:
                    case 102 /* TildeToken */:
                    case 101 /* ExclamationToken */:

                    case 70 /* OpenBraceToken */:

                    case 85 /* EqualsGreaterThanToken */:

                    case 118 /* SlashToken */:
                    case 119 /* SlashEqualsToken */:

                    case 50 /* SuperKeyword */:
                    case 35 /* ThisKeyword */:
                    case 37 /* TrueKeyword */:
                    case 24 /* FalseKeyword */:
                    case 32 /* NullKeyword */:

                    case 31 /* NewKeyword */:

                    case 21 /* DeleteKeyword */:
                    case 41 /* VoidKeyword */:
                    case 39 /* TypeOfKeyword */:

                    case 27 /* FunctionKeyword */:
                        return true;
                }

                return this.isIdentifier(currentToken);
            };

            ParserImpl.prototype.parseExpressionStatement = function () {
                var expression = this.parseExpression(true);

                var semicolon = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.expressionStatement(expression, semicolon);
            };

            ParserImpl.prototype.parseIfStatement = function () {
                var ifKeyword = this.eatKeyword(28 /* IfKeyword */);
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var condition = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);
                var statement = this.parseStatement(false);

                var elseClause = null;
                if (this.isElseClause()) {
                    elseClause = this.parseElseClause();
                }

                return this.factory.ifStatement(ifKeyword, openParenToken, condition, closeParenToken, statement, elseClause);
            };

            ParserImpl.prototype.isElseClause = function () {
                return this.currentToken().tokenKind === 23 /* ElseKeyword */;
            };

            ParserImpl.prototype.parseElseClause = function () {
                var elseKeyword = this.eatKeyword(23 /* ElseKeyword */);
                var statement = this.parseStatement(false);

                return this.factory.elseClause(elseKeyword, statement);
            };

            ParserImpl.prototype.isVariableStatement = function () {
                var index = this.modifierCount();
                return this.peekToken(index).tokenKind === 40 /* VarKeyword */;
            };

            ParserImpl.prototype.parseVariableStatement = function () {
                var modifiers = this.parseModifiers();
                var variableDeclaration = this.parseVariableDeclaration(true);
                var semicolonToken = this.eatExplicitOrAutomaticSemicolon(false);

                return this.factory.variableStatement(modifiers, variableDeclaration, semicolonToken);
            };

            ParserImpl.prototype.parseVariableDeclaration = function (allowIn) {
                var varKeyword = this.eatKeyword(40 /* VarKeyword */);

                var listParsingState = allowIn ? 4096 /* VariableDeclaration_VariableDeclarators_AllowIn */ : 8192 /* VariableDeclaration_VariableDeclarators_DisallowIn */;

                var result = this.parseSeparatedSyntaxList(listParsingState);
                var variableDeclarators = result.list;
                varKeyword = this.addSkippedTokensAfterToken(varKeyword, result.skippedTokens);

                return this.factory.variableDeclaration(varKeyword, variableDeclarators);
            };

            ParserImpl.prototype.isVariableDeclarator = function () {
                if (this.currentNode() !== null && this.currentNode().kind() === 225 /* VariableDeclarator */) {
                    return true;
                }

                return this.isIdentifier(this.currentToken());
            };

            ParserImpl.prototype.canReuseVariableDeclaratorNode = function (node) {
                if (node === null || node.kind() !== 225 /* VariableDeclarator */) {
                    return false;
                }

                var variableDeclarator = node;
                return variableDeclarator.equalsValueClause === null;
            };

            ParserImpl.prototype.parseVariableDeclarator = function (allowIn, allowPropertyName) {
                if (this.canReuseVariableDeclaratorNode(this.currentNode())) {
                    return this.eatNode();
                }

                var propertyName = allowPropertyName ? this.eatPropertyName() : this.eatIdentifierToken();
                var equalsValueClause = null;
                var typeAnnotation = null;

                if (propertyName.width() > 0) {
                    typeAnnotation = this.parseOptionalTypeAnnotation(false);

                    if (this.isEqualsValueClause(false)) {
                        equalsValueClause = this.parseEqualsValueClause(allowIn);
                    }
                }

                return this.factory.variableDeclarator(propertyName, typeAnnotation, equalsValueClause);
            };

            ParserImpl.prototype.isColonValueClause = function () {
                return this.currentToken().tokenKind === 106 /* ColonToken */;
            };

            ParserImpl.prototype.isEqualsValueClause = function (inParameter) {
                var token0 = this.currentToken();
                if (token0.tokenKind === 107 /* EqualsToken */) {
                    return true;
                }

                if (!this.previousToken().hasTrailingNewLine()) {
                    if (token0.tokenKind === 85 /* EqualsGreaterThanToken */) {
                        return false;
                    }

                    if (token0.tokenKind === 70 /* OpenBraceToken */ && inParameter) {
                        return false;
                    }

                    return this.isExpression(token0);
                }

                return false;
            };

            ParserImpl.prototype.parseEqualsValueClause = function (allowIn) {
                var equalsToken = this.eatToken(107 /* EqualsToken */);
                var value = this.parseAssignmentExpression(allowIn);

                return this.factory.equalsValueClause(equalsToken, value);
            };

            ParserImpl.prototype.parseExpression = function (allowIn) {
                return this.parseSubExpression(0, allowIn);
            };

            ParserImpl.prototype.parseAssignmentExpression = function (allowIn) {
                return this.parseSubExpression(2 /* AssignmentExpressionPrecedence */, allowIn);
            };

            ParserImpl.prototype.parseUnaryExpressionOrLower = function () {
                var currentTokenKind = this.currentToken().tokenKind;
                if (TypeScript.SyntaxFacts.isPrefixUnaryExpressionOperatorToken(currentTokenKind)) {
                    var operatorKind = TypeScript.SyntaxFacts.getPrefixUnaryExpressionFromOperatorToken(currentTokenKind);

                    var operatorToken = this.eatAnyToken();

                    var operand = this.parseUnaryExpressionOrLower();
                    return this.factory.prefixUnaryExpression(operatorKind, operatorToken, operand);
                } else if (currentTokenKind === 39 /* TypeOfKeyword */) {
                    return this.parseTypeOfExpression();
                } else if (currentTokenKind === 41 /* VoidKeyword */) {
                    return this.parseVoidExpression();
                } else if (currentTokenKind === 21 /* DeleteKeyword */) {
                    return this.parseDeleteExpression();
                } else if (currentTokenKind === 80 /* LessThanToken */) {
                    return this.parseCastExpression();
                } else {
                    return this.parsePostfixExpressionOrLower();
                }
            };

            ParserImpl.prototype.parseSubExpression = function (precedence, allowIn) {
                if (precedence <= 2 /* AssignmentExpressionPrecedence */) {
                    if (this.isSimpleArrowFunctionExpression()) {
                        return this.parseSimpleArrowFunctionExpression();
                    }

                    var parethesizedArrowFunction = this.tryParseParenthesizedArrowFunctionExpression();
                    if (parethesizedArrowFunction !== null) {
                        return parethesizedArrowFunction;
                    }
                }

                var leftOperand = this.parseUnaryExpressionOrLower();
                return this.parseBinaryOrConditionalExpressions(precedence, allowIn, leftOperand);
            };

            ParserImpl.prototype.parseBinaryOrConditionalExpressions = function (precedence, allowIn, leftOperand) {
                while (true) {
                    var token0 = this.currentToken();
                    var token0Kind = token0.tokenKind;

                    if (TypeScript.SyntaxFacts.isBinaryExpressionOperatorToken(token0Kind)) {
                        if (token0Kind === 29 /* InKeyword */ && !allowIn) {
                            break;
                        }

                        var mergedToken = this.tryMergeBinaryExpressionTokens();
                        var tokenKind = mergedToken === null ? token0Kind : mergedToken.syntaxKind;

                        var binaryExpressionKind = TypeScript.SyntaxFacts.getBinaryExpressionFromOperatorToken(tokenKind);
                        var newPrecedence = ParserImpl.getPrecedence(binaryExpressionKind);

                        if (newPrecedence < precedence) {
                            break;
                        }

                        if (newPrecedence === precedence && !this.isRightAssociative(binaryExpressionKind)) {
                            break;
                        }

                        var operatorToken = mergedToken === null ? token0 : TypeScript.Syntax.token(mergedToken.syntaxKind).withLeadingTrivia(token0.leadingTrivia()).withTrailingTrivia(this.peekToken(mergedToken.tokenCount - 1).trailingTrivia());

                        var skipCount = mergedToken === null ? 1 : mergedToken.tokenCount;
                        for (var i = 0; i < skipCount; i++) {
                            this.eatAnyToken();
                        }

                        leftOperand = this.factory.binaryExpression(binaryExpressionKind, leftOperand, operatorToken, this.parseSubExpression(newPrecedence, allowIn));
                        continue;
                    }

                    if (token0Kind === 105 /* QuestionToken */ && precedence <= 3 /* ConditionalExpressionPrecedence */) {
                        var questionToken = this.eatToken(105 /* QuestionToken */);

                        var whenTrueExpression = this.parseAssignmentExpression(allowIn);
                        var colon = this.eatToken(106 /* ColonToken */);

                        var whenFalseExpression = this.parseAssignmentExpression(allowIn);
                        leftOperand = this.factory.conditionalExpression(leftOperand, questionToken, whenTrueExpression, colon, whenFalseExpression);
                        continue;
                    }

                    break;
                }

                return leftOperand;
            };

            ParserImpl.prototype.tryMergeBinaryExpressionTokens = function () {
                var token0 = this.currentToken();

                if (token0.tokenKind === 81 /* GreaterThanToken */ && !token0.hasTrailingTrivia()) {
                    var storage = this.mergeTokensStorage;
                    storage[0] = 0 /* None */;
                    storage[1] = 0 /* None */;
                    storage[2] = 0 /* None */;

                    for (var i = 0; i < storage.length; i++) {
                        var nextToken = this.peekToken(i + 1);

                        if (!nextToken.hasLeadingTrivia()) {
                            storage[i] = nextToken.tokenKind;
                        }

                        if (nextToken.hasTrailingTrivia()) {
                            break;
                        }
                    }

                    if (storage[0] === 81 /* GreaterThanToken */) {
                        if (storage[1] === 81 /* GreaterThanToken */) {
                            if (storage[2] === 107 /* EqualsToken */) {
                                return { tokenCount: 4, syntaxKind: 114 /* GreaterThanGreaterThanGreaterThanEqualsToken */ };
                            } else {
                                return { tokenCount: 3, syntaxKind: 97 /* GreaterThanGreaterThanGreaterThanToken */ };
                            }
                        } else if (storage[1] === 107 /* EqualsToken */) {
                            return { tokenCount: 3, syntaxKind: 113 /* GreaterThanGreaterThanEqualsToken */ };
                        } else {
                            return { tokenCount: 2, syntaxKind: 96 /* GreaterThanGreaterThanToken */ };
                        }
                    } else if (storage[0] === 107 /* EqualsToken */) {
                        return { tokenCount: 2, syntaxKind: 83 /* GreaterThanEqualsToken */ };
                    }
                }

                return null;
            };

            ParserImpl.prototype.isRightAssociative = function (expressionKind) {
                switch (expressionKind) {
                    case 174 /* AssignmentExpression */:
                    case 175 /* AddAssignmentExpression */:
                    case 176 /* SubtractAssignmentExpression */:
                    case 177 /* MultiplyAssignmentExpression */:
                    case 178 /* DivideAssignmentExpression */:
                    case 179 /* ModuloAssignmentExpression */:
                    case 180 /* AndAssignmentExpression */:
                    case 181 /* ExclusiveOrAssignmentExpression */:
                    case 182 /* OrAssignmentExpression */:
                    case 183 /* LeftShiftAssignmentExpression */:
                    case 184 /* SignedRightShiftAssignmentExpression */:
                    case 185 /* UnsignedRightShiftAssignmentExpression */:
                        return true;
                    default:
                        return false;
                }
            };

            ParserImpl.prototype.parseMemberExpressionOrLower = function (inObjectCreation) {
                if (this.currentToken().tokenKind === 31 /* NewKeyword */) {
                    return this.parseObjectCreationExpression();
                }

                var expression = this.parsePrimaryExpression();
                if (expression === null) {
                    return this.eatIdentifierToken();
                }

                return this.parseMemberExpressionRest(expression, false, inObjectCreation);
            };

            ParserImpl.prototype.parseCallExpressionOrLower = function () {
                var expression;
                if (this.currentToken().tokenKind === 50 /* SuperKeyword */) {
                    expression = this.eatKeyword(50 /* SuperKeyword */);

                    var currentTokenKind = this.currentToken().tokenKind;
                    if (currentTokenKind !== 72 /* OpenParenToken */ && currentTokenKind !== 76 /* DotToken */) {
                        expression = this.factory.memberAccessExpression(expression, this.eatToken(76 /* DotToken */), this.eatIdentifierNameToken());
                    }
                } else {
                    expression = this.parseMemberExpressionOrLower(false);
                }

                return this.parseMemberExpressionRest(expression, true, false);
            };

            ParserImpl.prototype.parseMemberExpressionRest = function (expression, allowArguments, inObjectCreation) {
                while (true) {
                    var currentTokenKind = this.currentToken().tokenKind;

                    switch (currentTokenKind) {
                        case 72 /* OpenParenToken */:
                            if (!allowArguments) {
                                return expression;
                            }

                            expression = this.factory.invocationExpression(expression, this.parseArgumentList(null));
                            continue;

                        case 80 /* LessThanToken */:
                            if (!allowArguments) {
                                return expression;
                            }

                            var argumentList = this.tryParseArgumentList();
                            if (argumentList !== null) {
                                expression = this.factory.invocationExpression(expression, argumentList);
                                continue;
                            }

                            break;

                        case 74 /* OpenBracketToken */:
                            expression = this.parseElementAccessExpression(expression, inObjectCreation);
                            continue;

                        case 76 /* DotToken */:
                            expression = this.factory.memberAccessExpression(expression, this.eatToken(76 /* DotToken */), this.eatIdentifierNameToken());
                            continue;
                    }

                    return expression;
                }
            };

            ParserImpl.prototype.parseLeftHandSideExpressionOrLower = function () {
                if (this.currentToken().tokenKind === 31 /* NewKeyword */) {
                    return this.parseObjectCreationExpression();
                } else {
                    return this.parseCallExpressionOrLower();
                }
            };

            ParserImpl.prototype.parsePostfixExpressionOrLower = function () {
                var expression = this.parseLeftHandSideExpressionOrLower();
                if (expression === null) {
                    return this.eatIdentifierToken();
                }

                var currentTokenKind = this.currentToken().tokenKind;

                switch (currentTokenKind) {
                    case 93 /* PlusPlusToken */:
                    case 94 /* MinusMinusToken */:
                        if (this.previousToken() !== null && this.previousToken().hasTrailingNewLine()) {
                            break;
                        }

                        return this.factory.postfixUnaryExpression(TypeScript.SyntaxFacts.getPostfixUnaryExpressionFromOperatorToken(currentTokenKind), expression, this.eatAnyToken());
                }

                return expression;
            };

            ParserImpl.prototype.tryParseGenericArgumentList = function () {
                var rewindPoint = this.getRewindPoint();

                var typeArgumentList = this.tryParseTypeArgumentList(true);
                var token0 = this.currentToken();

                var isOpenParen = token0.tokenKind === 72 /* OpenParenToken */;
                var isDot = token0.tokenKind === 76 /* DotToken */;
                var isOpenParenOrDot = isOpenParen || isDot;

                var argumentList = null;
                if (typeArgumentList === null || !isOpenParenOrDot) {
                    this.rewind(rewindPoint);
                    this.releaseRewindPoint(rewindPoint);
                    return null;
                } else {
                    this.releaseRewindPoint(rewindPoint);

                    if (isDot) {
                        var diagnostic = new TypeScript.Diagnostic(this.fileName, this.lineMap, this.currentTokenStart(), token0.width(), TypeScript.DiagnosticCode.A_parameter_list_must_follow_a_generic_type_argument_list_expected, null);
                        this.addDiagnostic(diagnostic);

                        return this.factory.argumentList(typeArgumentList, TypeScript.Syntax.emptyToken(72 /* OpenParenToken */), TypeScript.Syntax.emptySeparatedList, TypeScript.Syntax.emptyToken(73 /* CloseParenToken */));
                    } else {
                        return this.parseArgumentList(typeArgumentList);
                    }
                }
            };

            ParserImpl.prototype.tryParseArgumentList = function () {
                if (this.currentToken().tokenKind === 80 /* LessThanToken */) {
                    return this.tryParseGenericArgumentList();
                }

                if (this.currentToken().tokenKind === 72 /* OpenParenToken */) {
                    return this.parseArgumentList(null);
                }

                return null;
            };

            ParserImpl.prototype.parseArgumentList = function (typeArgumentList) {
                var openParenToken = this.eatToken(72 /* OpenParenToken */);

                var _arguments = TypeScript.Syntax.emptySeparatedList;

                if (openParenToken.fullWidth() > 0) {
                    var result = this.parseSeparatedSyntaxList(16384 /* ArgumentList_AssignmentExpressions */);
                    _arguments = result.list;
                    openParenToken = this.addSkippedTokensAfterToken(openParenToken, result.skippedTokens);
                }

                var closeParenToken = this.eatToken(73 /* CloseParenToken */);

                return this.factory.argumentList(typeArgumentList, openParenToken, _arguments, closeParenToken);
            };

            ParserImpl.prototype.parseElementAccessExpression = function (expression, inObjectCreation) {
                var start = this.currentTokenStart();
                var openBracketToken = this.eatToken(74 /* OpenBracketToken */);
                var argumentExpression;

                if (this.currentToken().tokenKind === 75 /* CloseBracketToken */ && inObjectCreation) {
                    var end = this.currentTokenStart() + this.currentToken().width();
                    var diagnostic = new TypeScript.Diagnostic(this.fileName, this.lineMap, start, end - start, TypeScript.DiagnosticCode.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead, null);
                    this.addDiagnostic(diagnostic);

                    argumentExpression = TypeScript.Syntax.emptyToken(11 /* IdentifierName */);
                } else {
                    argumentExpression = this.parseExpression(true);
                }

                var closeBracketToken = this.eatToken(75 /* CloseBracketToken */);

                return this.factory.elementAccessExpression(expression, openBracketToken, argumentExpression, closeBracketToken);
            };

            ParserImpl.prototype.parsePrimaryExpression = function () {
                var currentToken = this.currentToken();

                if (this.isIdentifier(currentToken)) {
                    return this.eatIdentifierToken();
                }

                var currentTokenKind = currentToken.tokenKind;
                switch (currentTokenKind) {
                    case 35 /* ThisKeyword */:
                        return this.parseThisExpression();

                    case 37 /* TrueKeyword */:
                    case 24 /* FalseKeyword */:
                        return this.parseLiteralExpression();

                    case 32 /* NullKeyword */:
                        return this.parseLiteralExpression();

                    case 27 /* FunctionKeyword */:
                        return this.parseFunctionExpression();

                    case 13 /* NumericLiteral */:
                        return this.parseLiteralExpression();

                    case 12 /* RegularExpressionLiteral */:
                        return this.parseLiteralExpression();

                    case 14 /* StringLiteral */:
                        return this.parseLiteralExpression();

                    case 74 /* OpenBracketToken */:
                        return this.parseArrayLiteralExpression();

                    case 70 /* OpenBraceToken */:
                        return this.parseObjectLiteralExpression();

                    case 72 /* OpenParenToken */:
                        return this.parseParenthesizedExpression();

                    case 118 /* SlashToken */:
                    case 119 /* SlashEqualsToken */:
                        var result = this.tryReparseDivideAsRegularExpression();
                        if (result !== null) {
                            return result;
                        }
                        break;
                }

                return null;
            };

            ParserImpl.prototype.tryReparseDivideAsRegularExpression = function () {
                var currentToken = this.currentToken();

                if (this.previousToken() !== null) {
                    var previousTokenKind = this.previousToken().tokenKind;
                    switch (previousTokenKind) {
                        case 11 /* IdentifierName */:
                            return null;

                        case 35 /* ThisKeyword */:
                        case 37 /* TrueKeyword */:
                        case 24 /* FalseKeyword */:
                            return null;

                        case 14 /* StringLiteral */:
                        case 13 /* NumericLiteral */:
                        case 12 /* RegularExpressionLiteral */:
                        case 93 /* PlusPlusToken */:
                        case 94 /* MinusMinusToken */:
                        case 75 /* CloseBracketToken */:
                            return null;
                    }
                }

                currentToken = this.currentTokenAllowingRegularExpression();

                if (currentToken.tokenKind === 118 /* SlashToken */ || currentToken.tokenKind === 119 /* SlashEqualsToken */) {
                    return null;
                } else if (currentToken.tokenKind === 12 /* RegularExpressionLiteral */) {
                    return this.parseLiteralExpression();
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.parseTypeOfExpression = function () {
                var typeOfKeyword = this.eatKeyword(39 /* TypeOfKeyword */);
                var expression = this.parseUnaryExpressionOrLower();

                return this.factory.typeOfExpression(typeOfKeyword, expression);
            };

            ParserImpl.prototype.parseDeleteExpression = function () {
                var deleteKeyword = this.eatKeyword(21 /* DeleteKeyword */);
                var expression = this.parseUnaryExpressionOrLower();

                return this.factory.deleteExpression(deleteKeyword, expression);
            };

            ParserImpl.prototype.parseVoidExpression = function () {
                var voidKeyword = this.eatKeyword(41 /* VoidKeyword */);
                var expression = this.parseUnaryExpressionOrLower();

                return this.factory.voidExpression(voidKeyword, expression);
            };

            ParserImpl.prototype.parseFunctionExpression = function () {
                var functionKeyword = this.eatKeyword(27 /* FunctionKeyword */);
                var identifier = null;

                if (this.isIdentifier(this.currentToken())) {
                    identifier = this.eatIdentifierToken();
                }

                var callSignature = this.parseCallSignature(false);
                var block = this.parseBlock(false, true);

                return this.factory.functionExpression(functionKeyword, identifier, callSignature, block);
            };

            ParserImpl.prototype.parseObjectCreationExpression = function () {
                var newKeyword = this.eatKeyword(31 /* NewKeyword */);

                var expression = this.parseObjectCreationExpressionOrLower(true);
                var argumentList = this.tryParseArgumentList();

                var result = this.factory.objectCreationExpression(newKeyword, expression, argumentList);
                return this.parseMemberExpressionRest(result, true, false);
            };

            ParserImpl.prototype.parseObjectCreationExpressionOrLower = function (inObjectCreation) {
                if (this.currentToken().tokenKind === 31 /* NewKeyword */) {
                    return this.parseObjectCreationExpression();
                } else {
                    return this.parseMemberExpressionOrLower(inObjectCreation);
                }
            };

            ParserImpl.prototype.parseCastExpression = function () {
                var lessThanToken = this.eatToken(80 /* LessThanToken */);
                var type = this.parseType();
                var greaterThanToken = this.eatToken(81 /* GreaterThanToken */);
                var expression = this.parseUnaryExpressionOrLower();

                return this.factory.castExpression(lessThanToken, type, greaterThanToken, expression);
            };

            ParserImpl.prototype.parseParenthesizedExpression = function () {
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var expression = this.parseExpression(true);
                var closeParenToken = this.eatToken(73 /* CloseParenToken */);

                return this.factory.parenthesizedExpression(openParenToken, expression, closeParenToken);
            };

            ParserImpl.prototype.tryParseParenthesizedArrowFunctionExpression = function () {
                var tokenKind = this.currentToken().tokenKind;
                if (tokenKind !== 72 /* OpenParenToken */ && tokenKind !== 80 /* LessThanToken */) {
                    return null;
                }

                if (this.isDefinitelyArrowFunctionExpression()) {
                    return this.parseParenthesizedArrowFunctionExpression(false);
                }

                if (!this.isPossiblyArrowFunctionExpression()) {
                    return null;
                }

                var rewindPoint = this.getRewindPoint();

                var arrowFunction = this.parseParenthesizedArrowFunctionExpression(true);
                if (arrowFunction === null) {
                    this.rewind(rewindPoint);
                }

                this.releaseRewindPoint(rewindPoint);
                return arrowFunction;
            };

            ParserImpl.prototype.parseParenthesizedArrowFunctionExpression = function (requireArrow) {
                var currentToken = this.currentToken();

                var callSignature = this.parseCallSignature(true);

                if (requireArrow && this.currentToken().tokenKind !== 85 /* EqualsGreaterThanToken */) {
                    return null;
                }

                var equalsGreaterThanToken = this.eatToken(85 /* EqualsGreaterThanToken */);

                var block = this.tryParseArrowFunctionBlock();
                var expression = null;
                if (block === null) {
                    expression = this.parseAssignmentExpression(true);
                }

                return this.factory.parenthesizedArrowFunctionExpression(callSignature, equalsGreaterThanToken, block, expression);
            };

            ParserImpl.prototype.tryParseArrowFunctionBlock = function () {
                if (this.isBlock()) {
                    return this.parseBlock(false, false);
                } else {
                    if (this.isStatement(false) && !this.isExpressionStatement(this.currentToken()) && !this.isFunctionDeclaration()) {
                        return this.parseBlock(true, false);
                    } else {
                        return null;
                    }
                }
            };

            ParserImpl.prototype.isSimpleArrowFunctionExpression = function () {
                if (this.currentToken().tokenKind === 85 /* EqualsGreaterThanToken */) {
                    return true;
                }

                return this.isIdentifier(this.currentToken()) && this.peekToken(1).tokenKind === 85 /* EqualsGreaterThanToken */;
            };

            ParserImpl.prototype.parseSimpleArrowFunctionExpression = function () {
                var identifier = this.eatIdentifierToken();
                var equalsGreaterThanToken = this.eatToken(85 /* EqualsGreaterThanToken */);

                var block = this.tryParseArrowFunctionBlock();
                var expression = null;
                if (block === null) {
                    expression = this.parseAssignmentExpression(true);
                }

                return this.factory.simpleArrowFunctionExpression(identifier, equalsGreaterThanToken, block, expression);
            };

            ParserImpl.prototype.isBlock = function () {
                return this.currentToken().tokenKind === 70 /* OpenBraceToken */;
            };

            ParserImpl.prototype.isDefinitelyArrowFunctionExpression = function () {
                var token0 = this.currentToken();
                if (token0.tokenKind !== 72 /* OpenParenToken */) {
                    return false;
                }

                var token1 = this.peekToken(1);
                var token2;

                if (token1.tokenKind === 73 /* CloseParenToken */) {
                    token2 = this.peekToken(2);
                    return token2.tokenKind === 106 /* ColonToken */ || token2.tokenKind === 85 /* EqualsGreaterThanToken */ || token2.tokenKind === 70 /* OpenBraceToken */;
                }

                if (token1.tokenKind === 77 /* DotDotDotToken */) {
                    return true;
                }

                token2 = this.peekToken(2);
                if (token1.tokenKind === 57 /* PublicKeyword */ || token1.tokenKind === 55 /* PrivateKeyword */) {
                    if (this.isIdentifier(token2)) {
                        return true;
                    }
                }

                if (!this.isIdentifier(token1)) {
                    return false;
                }

                if (token2.tokenKind === 106 /* ColonToken */) {
                    return true;
                }

                var token3 = this.peekToken(3);
                if (token2.tokenKind === 105 /* QuestionToken */) {
                    if (token3.tokenKind === 106 /* ColonToken */ || token3.tokenKind === 73 /* CloseParenToken */ || token3.tokenKind === 79 /* CommaToken */) {
                        return true;
                    }
                }

                if (token2.tokenKind === 73 /* CloseParenToken */) {
                    if (token3.tokenKind === 85 /* EqualsGreaterThanToken */) {
                        return true;
                    }
                }

                return false;
            };

            ParserImpl.prototype.isPossiblyArrowFunctionExpression = function () {
                var token0 = this.currentToken();
                if (token0.tokenKind !== 72 /* OpenParenToken */) {
                    return true;
                }

                var token1 = this.peekToken(1);

                if (!this.isIdentifier(token1)) {
                    return false;
                }

                var token2 = this.peekToken(2);
                if (token2.tokenKind === 107 /* EqualsToken */) {
                    return true;
                }

                if (token2.tokenKind === 79 /* CommaToken */) {
                    return true;
                }

                if (token2.tokenKind === 73 /* CloseParenToken */) {
                    var token3 = this.peekToken(3);
                    if (token3.tokenKind === 106 /* ColonToken */) {
                        return true;
                    }
                }

                return false;
            };

            ParserImpl.prototype.parseObjectLiteralExpression = function () {
                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);

                var result = this.parseSeparatedSyntaxList(32768 /* ObjectLiteralExpression_PropertyAssignments */);
                var propertyAssignments = result.list;
                openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);

                return this.factory.objectLiteralExpression(openBraceToken, propertyAssignments, closeBraceToken);
            };

            ParserImpl.prototype.parsePropertyAssignment = function (inErrorRecovery) {
                if (this.isAccessor(inErrorRecovery)) {
                    return this.parseAccessor(true);
                } else if (this.isFunctionPropertyAssignment(inErrorRecovery)) {
                    return this.parseFunctionPropertyAssignment();
                } else if (this.isSimplePropertyAssignment(inErrorRecovery)) {
                    return this.parseSimplePropertyAssignment();
                } else {
                    throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.isPropertyAssignment = function (inErrorRecovery) {
                return this.isAccessor(inErrorRecovery) || this.isFunctionPropertyAssignment(inErrorRecovery) || this.isSimplePropertyAssignment(inErrorRecovery);
            };

            ParserImpl.prototype.eatPropertyName = function () {
                return TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(this.currentToken()) ? this.eatIdentifierNameToken() : this.eatAnyToken();
            };

            ParserImpl.prototype.isFunctionPropertyAssignment = function (inErrorRecovery) {
                return this.isPropertyName(this.currentToken(), inErrorRecovery) && this.isCallSignature(1);
            };

            ParserImpl.prototype.parseFunctionPropertyAssignment = function () {
                var propertyName = this.eatPropertyName();
                var callSignature = this.parseCallSignature(false);
                var block = this.parseBlock(false, true);

                return this.factory.functionPropertyAssignment(propertyName, callSignature, block);
            };

            ParserImpl.prototype.isSimplePropertyAssignment = function (inErrorRecovery) {
                return this.isPropertyName(this.currentToken(), inErrorRecovery);
            };

            ParserImpl.prototype.parseSimplePropertyAssignment = function () {
                var propertyName = this.eatPropertyName();
                var colonToken = this.eatToken(106 /* ColonToken */);
                var expression = this.parseAssignmentExpression(true);

                return this.factory.simplePropertyAssignment(propertyName, colonToken, expression);
            };

            ParserImpl.prototype.isPropertyName = function (token, inErrorRecovery) {
                if (TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(token)) {
                    if (inErrorRecovery) {
                        return this.isIdentifier(token);
                    } else {
                        return true;
                    }
                }

                switch (token.tokenKind) {
                    case 14 /* StringLiteral */:
                    case 13 /* NumericLiteral */:
                        return true;

                    default:
                        return false;
                }
            };

            ParserImpl.prototype.parseArrayLiteralExpression = function () {
                var openBracketToken = this.eatToken(74 /* OpenBracketToken */);

                var result = this.parseSeparatedSyntaxList(65536 /* ArrayLiteralExpression_AssignmentExpressions */);
                var expressions = result.list;
                openBracketToken = this.addSkippedTokensAfterToken(openBracketToken, result.skippedTokens);

                var closeBracketToken = this.eatToken(75 /* CloseBracketToken */);

                return this.factory.arrayLiteralExpression(openBracketToken, expressions, closeBracketToken);
            };

            ParserImpl.prototype.parseLiteralExpression = function () {
                return this.eatAnyToken();
            };

            ParserImpl.prototype.parseThisExpression = function () {
                return this.eatKeyword(35 /* ThisKeyword */);
            };

            ParserImpl.prototype.parseBlock = function (parseBlockEvenWithNoOpenBrace, checkForStrictMode) {
                var openBraceToken = this.eatToken(70 /* OpenBraceToken */);

                var statements = TypeScript.Syntax.emptyList;

                if (parseBlockEvenWithNoOpenBrace || openBraceToken.width() > 0) {
                    var savedIsInStrictMode = this.isInStrictMode;

                    var processItems = checkForStrictMode ? ParserImpl.updateStrictModeState : null;
                    var result = this.parseSyntaxList(32 /* Block_Statements */, processItems);
                    statements = result.list;
                    openBraceToken = this.addSkippedTokensAfterToken(openBraceToken, result.skippedTokens);

                    this.setStrictMode(savedIsInStrictMode);
                }

                var closeBraceToken = this.eatToken(71 /* CloseBraceToken */);

                return this.factory.block(openBraceToken, statements, closeBraceToken);
            };

            ParserImpl.prototype.parseCallSignature = function (requireCompleteTypeParameterList) {
                var typeParameterList = this.parseOptionalTypeParameterList(requireCompleteTypeParameterList);
                var parameterList = this.parseParameterList();
                var typeAnnotation = this.parseOptionalTypeAnnotation(false);

                return this.factory.callSignature(typeParameterList, parameterList, typeAnnotation);
            };

            ParserImpl.prototype.parseOptionalTypeParameterList = function (requireCompleteTypeParameterList) {
                if (this.currentToken().tokenKind !== 80 /* LessThanToken */) {
                    return null;
                }

                var rewindPoint = this.getRewindPoint();

                var lessThanToken = this.eatToken(80 /* LessThanToken */);

                var result = this.parseSeparatedSyntaxList(524288 /* TypeParameterList_TypeParameters */);
                var typeParameters = result.list;
                lessThanToken = this.addSkippedTokensAfterToken(lessThanToken, result.skippedTokens);

                var greaterThanToken = this.eatToken(81 /* GreaterThanToken */);

                if (requireCompleteTypeParameterList && greaterThanToken.fullWidth() === 0) {
                    this.rewind(rewindPoint);
                    this.releaseRewindPoint(rewindPoint);
                    return null;
                } else {
                    this.releaseRewindPoint(rewindPoint);
                    var typeParameterList = this.factory.typeParameterList(lessThanToken, typeParameters, greaterThanToken);

                    return typeParameterList;
                }
            };

            ParserImpl.prototype.isTypeParameter = function () {
                return this.isIdentifier(this.currentToken());
            };

            ParserImpl.prototype.parseTypeParameter = function () {
                var identifier = this.eatIdentifierToken();
                var constraint = this.parseOptionalConstraint();

                return this.factory.typeParameter(identifier, constraint);
            };

            ParserImpl.prototype.parseOptionalConstraint = function () {
                if (this.currentToken().kind() !== 48 /* ExtendsKeyword */) {
                    return null;
                }

                var extendsKeyword = this.eatKeyword(48 /* ExtendsKeyword */);
                var type = this.parseType();

                return this.factory.constraint(extendsKeyword, type);
            };

            ParserImpl.prototype.parseParameterList = function () {
                var openParenToken = this.eatToken(72 /* OpenParenToken */);
                var parameters = TypeScript.Syntax.emptySeparatedList;

                if (openParenToken.width() > 0) {
                    var result = this.parseSeparatedSyntaxList(131072 /* ParameterList_Parameters */);
                    parameters = result.list;
                    openParenToken = this.addSkippedTokensAfterToken(openParenToken, result.skippedTokens);
                }

                var closeParenToken = this.eatToken(73 /* CloseParenToken */);
                return this.factory.parameterList(openParenToken, parameters, closeParenToken);
            };

            ParserImpl.prototype.isTypeAnnotation = function () {
                return this.currentToken().tokenKind === 106 /* ColonToken */;
            };

            ParserImpl.prototype.parseOptionalTypeAnnotation = function (allowStringLiteral) {
                return this.isTypeAnnotation() ? this.parseTypeAnnotation(allowStringLiteral) : null;
            };

            ParserImpl.prototype.parseTypeAnnotation = function (allowStringLiteral) {
                var colonToken = this.eatToken(106 /* ColonToken */);
                var type = allowStringLiteral && this.currentToken().tokenKind === 14 /* StringLiteral */ ? this.eatToken(14 /* StringLiteral */) : this.parseType();

                return this.factory.typeAnnotation(colonToken, type);
            };

            ParserImpl.prototype.isType = function () {
                var currentToken = this.currentToken();
                var currentTokenKind = currentToken.tokenKind;

                switch (currentTokenKind) {
                    case 39 /* TypeOfKeyword */:

                    case 60 /* AnyKeyword */:
                    case 67 /* NumberKeyword */:
                    case 61 /* BooleanKeyword */:
                    case 69 /* StringKeyword */:
                    case 41 /* VoidKeyword */:

                    case 70 /* OpenBraceToken */:

                    case 72 /* OpenParenToken */:
                    case 80 /* LessThanToken */:

                    case 31 /* NewKeyword */:
                        return true;
                }

                return this.isIdentifier(currentToken);
            };

            ParserImpl.prototype.parseType = function () {
                var currentToken = this.currentToken();
                var currentTokenKind = currentToken.tokenKind;

                var type = this.parseNonArrayType(currentToken);

                while (this.currentToken().tokenKind === 74 /* OpenBracketToken */) {
                    var openBracketToken = this.eatToken(74 /* OpenBracketToken */);
                    var closeBracketToken = this.eatToken(75 /* CloseBracketToken */);

                    type = this.factory.arrayType(type, openBracketToken, closeBracketToken);
                }

                return type;
            };

            ParserImpl.prototype.isTypeQuery = function () {
                return this.currentToken().tokenKind === 39 /* TypeOfKeyword */;
            };

            ParserImpl.prototype.parseTypeQuery = function () {
                var typeOfKeyword = this.eatToken(39 /* TypeOfKeyword */);
                var name = this.parseName();

                return this.factory.typeQuery(typeOfKeyword, name);
            };

            ParserImpl.prototype.parseNonArrayType = function (currentToken) {
                var currentTokenKind = currentToken.tokenKind;
                switch (currentTokenKind) {
                    case 60 /* AnyKeyword */:
                    case 67 /* NumberKeyword */:
                    case 61 /* BooleanKeyword */:
                    case 69 /* StringKeyword */:
                    case 41 /* VoidKeyword */:
                        return this.eatAnyToken();

                    case 70 /* OpenBraceToken */:
                        return this.parseObjectType();

                    case 72 /* OpenParenToken */:
                    case 80 /* LessThanToken */:
                        return this.parseFunctionType();

                    case 31 /* NewKeyword */:
                        return this.parseConstructorType();

                    case 39 /* TypeOfKeyword */:
                        return this.parseTypeQuery();
                }

                return this.parseNameOrGenericType();
            };

            ParserImpl.prototype.parseNameOrGenericType = function () {
                var name = this.parseName();
                var typeArgumentList = this.tryParseTypeArgumentList(false);

                return typeArgumentList === null ? name : this.factory.genericType(name, typeArgumentList);
            };

            ParserImpl.prototype.parseFunctionType = function () {
                var typeParameterList = this.parseOptionalTypeParameterList(false);
                var parameterList = this.parseParameterList();
                var equalsGreaterThanToken = this.eatToken(85 /* EqualsGreaterThanToken */);
                var returnType = this.parseType();

                return this.factory.functionType(typeParameterList, parameterList, equalsGreaterThanToken, returnType);
            };

            ParserImpl.prototype.parseConstructorType = function () {
                var newKeyword = this.eatKeyword(31 /* NewKeyword */);
                var typeParameterList = this.parseOptionalTypeParameterList(false);
                var parameterList = this.parseParameterList();
                var equalsGreaterThanToken = this.eatToken(85 /* EqualsGreaterThanToken */);
                var type = this.parseType();

                return this.factory.constructorType(newKeyword, typeParameterList, parameterList, equalsGreaterThanToken, type);
            };

            ParserImpl.prototype.isParameter = function () {
                if (this.currentNode() !== null && this.currentNode().kind() === 242 /* Parameter */) {
                    return true;
                }

                var token = this.currentToken();
                var tokenKind = token.tokenKind;
                if (tokenKind === 77 /* DotDotDotToken */) {
                    return true;
                }

                if (ParserImpl.isModifier(token) && !this.isModifierUsedAsParameterIdentifier(token)) {
                    return true;
                }

                return this.isIdentifier(token);
            };

            ParserImpl.prototype.isModifierUsedAsParameterIdentifier = function (token) {
                if (this.isIdentifier(token)) {
                    var nextTokenKind = this.peekToken(1).tokenKind;
                    switch (nextTokenKind) {
                        case 73 /* CloseParenToken */:
                        case 106 /* ColonToken */:
                        case 107 /* EqualsToken */:
                        case 79 /* CommaToken */:
                        case 105 /* QuestionToken */:
                            return true;
                    }
                }

                return false;
            };

            ParserImpl.prototype.parseParameter = function () {
                if (this.currentNode() !== null && this.currentNode().kind() === 242 /* Parameter */) {
                    return this.eatNode();
                }

                var dotDotDotToken = this.tryEatToken(77 /* DotDotDotToken */);

                var modifierArray = this.getArray();

                while (true) {
                    var currentToken = this.currentToken();
                    if (ParserImpl.isModifier(currentToken) && !this.isModifierUsedAsParameterIdentifier(currentToken)) {
                        modifierArray.push(this.eatAnyToken());
                        continue;
                    }

                    break;
                }

                var modifiers = TypeScript.Syntax.list(modifierArray);
                this.returnZeroOrOneLengthArray(modifierArray);

                var identifier = this.eatIdentifierToken();
                var questionToken = this.tryEatToken(105 /* QuestionToken */);
                var typeAnnotation = this.parseOptionalTypeAnnotation(true);

                var equalsValueClause = null;
                if (this.isEqualsValueClause(true)) {
                    equalsValueClause = this.parseEqualsValueClause(true);
                }

                return this.factory.parameter(dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause);
            };

            ParserImpl.prototype.parseSyntaxList = function (currentListType, processItems) {
                if (typeof processItems === "undefined") { processItems = null; }
                var savedListParsingState = this.listParsingState;
                this.listParsingState |= currentListType;

                var result = this.parseSyntaxListWorker(currentListType, processItems);

                this.listParsingState = savedListParsingState;

                return result;
            };

            ParserImpl.prototype.parseSeparatedSyntaxList = function (currentListType) {
                var savedListParsingState = this.listParsingState;
                this.listParsingState |= currentListType;

                var result = this.parseSeparatedSyntaxListWorker(currentListType);

                this.listParsingState = savedListParsingState;

                return result;
            };

            ParserImpl.prototype.abortParsingListOrMoveToNextToken = function (currentListType, items, skippedTokens) {
                this.reportUnexpectedTokenDiagnostic(currentListType);

                for (var state = 524288 /* LastListParsingState */; state >= 1 /* FirstListParsingState */; state >>= 1) {
                    if ((this.listParsingState & state) !== 0) {
                        if (this.isExpectedListTerminator(state) || this.isExpectedListItem(state, true)) {
                            return true;
                        }
                    }
                }

                var skippedToken = this.currentToken();

                this.moveToNextToken();

                this.addSkippedTokenToList(items, skippedTokens, skippedToken);

                return false;
            };

            ParserImpl.prototype.addSkippedTokenToList = function (items, skippedTokens, skippedToken) {
                for (var i = items.length - 1; i >= 0; i--) {
                    var item = items[i];
                    var lastToken = item.lastToken();
                    if (lastToken.fullWidth() > 0) {
                        items[i] = this.addSkippedTokenAfterNodeOrToken(item, skippedToken);
                        return;
                    }
                }

                skippedTokens.push(skippedToken);
            };

            ParserImpl.prototype.tryParseExpectedListItem = function (currentListType, inErrorRecovery, items, processItems) {
                if (this.isExpectedListItem(currentListType, inErrorRecovery)) {
                    var item = this.parseExpectedListItem(currentListType, inErrorRecovery);

                    items.push(item);

                    if (processItems !== null) {
                        processItems(this, items);
                    }
                }
            };

            ParserImpl.prototype.listIsTerminated = function (currentListType) {
                return this.isExpectedListTerminator(currentListType) || this.currentToken().tokenKind === 10 /* EndOfFileToken */;
            };

            ParserImpl.prototype.getArray = function () {
                if (this.arrayPool.length > 0) {
                    return this.arrayPool.pop();
                }

                return [];
            };

            ParserImpl.prototype.returnZeroOrOneLengthArray = function (array) {
                if (array.length <= 1) {
                    this.returnArray(array);
                }
            };

            ParserImpl.prototype.returnArray = function (array) {
                array.length = 0;
                this.arrayPool.push(array);
            };

            ParserImpl.prototype.parseSyntaxListWorker = function (currentListType, processItems) {
                var items = this.getArray();
                var skippedTokens = this.getArray();

                while (true) {
                    var oldItemsCount = items.length;
                    this.tryParseExpectedListItem(currentListType, false, items, processItems);

                    var newItemsCount = items.length;
                    if (newItemsCount === oldItemsCount) {
                        if (this.listIsTerminated(currentListType)) {
                            break;
                        }

                        var abort = this.abortParsingListOrMoveToNextToken(currentListType, items, skippedTokens);
                        if (abort) {
                            break;
                        }
                    }
                }

                var result = TypeScript.Syntax.list(items);

                this.returnZeroOrOneLengthArray(items);

                return { skippedTokens: skippedTokens, list: result };
            };

            ParserImpl.prototype.parseSeparatedSyntaxListWorker = function (currentListType) {
                var items = this.getArray();
                var skippedTokens = this.getArray();
                TypeScript.Debug.assert(items.length === 0);
                TypeScript.Debug.assert(skippedTokens.length === 0);
                TypeScript.Debug.assert(skippedTokens !== items);

                var separatorKind = this.separatorKind(currentListType);
                var allowAutomaticSemicolonInsertion = separatorKind === 78 /* SemicolonToken */;

                var inErrorRecovery = false;
                var listWasTerminated = false;
                while (true) {
                    var oldItemsCount = items.length;

                    this.tryParseExpectedListItem(currentListType, inErrorRecovery, items, null);

                    var newItemsCount = items.length;
                    if (newItemsCount === oldItemsCount) {
                        if (this.listIsTerminated(currentListType)) {
                            listWasTerminated = true;
                            break;
                        }

                        var abort = this.abortParsingListOrMoveToNextToken(currentListType, items, skippedTokens);
                        if (abort) {
                            break;
                        } else {
                            inErrorRecovery = true;
                            continue;
                        }
                    }

                    inErrorRecovery = false;

                    var currentToken = this.currentToken();
                    if (currentToken.tokenKind === separatorKind || currentToken.tokenKind === 79 /* CommaToken */) {
                        items.push(this.eatAnyToken());
                        continue;
                    }

                    if (this.listIsTerminated(currentListType)) {
                        listWasTerminated = true;
                        break;
                    }

                    if (allowAutomaticSemicolonInsertion && this.canEatAutomaticSemicolon(false)) {
                        items.push(this.eatExplicitOrAutomaticSemicolon(false));

                        continue;
                    }

                    items.push(this.eatToken(separatorKind));

                    inErrorRecovery = true;
                }

                var result = TypeScript.Syntax.separatedList(items);

                this.returnZeroOrOneLengthArray(items);

                return { skippedTokens: skippedTokens, list: result };
            };

            ParserImpl.prototype.separatorKind = function (currentListType) {
                switch (currentListType) {
                    case 2048 /* HeritageClause_TypeNameList */:
                    case 16384 /* ArgumentList_AssignmentExpressions */:
                    case 256 /* EnumDeclaration_EnumElements */:
                    case 4096 /* VariableDeclaration_VariableDeclarators_AllowIn */:
                    case 8192 /* VariableDeclaration_VariableDeclarators_DisallowIn */:
                    case 32768 /* ObjectLiteralExpression_PropertyAssignments */:
                    case 131072 /* ParameterList_Parameters */:
                    case 65536 /* ArrayLiteralExpression_AssignmentExpressions */:
                    case 262144 /* TypeArgumentList_Types */:
                    case 524288 /* TypeParameterList_TypeParameters */:
                        return 79 /* CommaToken */;

                    case 512 /* ObjectType_TypeMembers */:
                        return 78 /* SemicolonToken */;

                    case 1 /* SourceUnit_ModuleElements */:
                    case 1024 /* ClassOrInterfaceDeclaration_HeritageClauses */:
                    case 2 /* ClassDeclaration_ClassElements */:
                    case 4 /* ModuleDeclaration_ModuleElements */:
                    case 8 /* SwitchStatement_SwitchClauses */:
                    case 16 /* SwitchClause_Statements */:
                    case 32 /* Block_Statements */:
                    default:
                        throw TypeScript.Errors.notYetImplemented();
                }
            };

            ParserImpl.prototype.reportUnexpectedTokenDiagnostic = function (listType) {
                var token = this.currentToken();

                var diagnostic = new TypeScript.Diagnostic(this.fileName, this.lineMap, this.currentTokenStart(), token.width(), TypeScript.DiagnosticCode.Unexpected_token_0_expected, [this.getExpectedListElementType(listType)]);
                this.addDiagnostic(diagnostic);
            };

            ParserImpl.prototype.addDiagnostic = function (diagnostic) {
                if (this.diagnostics.length > 0 && this.diagnostics[this.diagnostics.length - 1].start() === diagnostic.start()) {
                    return;
                }

                this.diagnostics.push(diagnostic);
            };

            ParserImpl.prototype.isExpectedListTerminator = function (currentListType) {
                switch (currentListType) {
                    case 1 /* SourceUnit_ModuleElements */:
                        return this.isExpectedSourceUnit_ModuleElementsTerminator();

                    case 1024 /* ClassOrInterfaceDeclaration_HeritageClauses */:
                        return this.isExpectedClassOrInterfaceDeclaration_HeritageClausesTerminator();

                    case 2 /* ClassDeclaration_ClassElements */:
                        return this.isExpectedClassDeclaration_ClassElementsTerminator();

                    case 4 /* ModuleDeclaration_ModuleElements */:
                        return this.isExpectedModuleDeclaration_ModuleElementsTerminator();

                    case 8 /* SwitchStatement_SwitchClauses */:
                        return this.isExpectedSwitchStatement_SwitchClausesTerminator();

                    case 16 /* SwitchClause_Statements */:
                        return this.isExpectedSwitchClause_StatementsTerminator();

                    case 32 /* Block_Statements */:
                        return this.isExpectedBlock_StatementsTerminator();

                    case 64 /* TryBlock_Statements */:
                        return this.isExpectedTryBlock_StatementsTerminator();

                    case 128 /* CatchBlock_Statements */:
                        return this.isExpectedCatchBlock_StatementsTerminator();

                    case 256 /* EnumDeclaration_EnumElements */:
                        return this.isExpectedEnumDeclaration_EnumElementsTerminator();

                    case 512 /* ObjectType_TypeMembers */:
                        return this.isExpectedObjectType_TypeMembersTerminator();

                    case 16384 /* ArgumentList_AssignmentExpressions */:
                        return this.isExpectedArgumentList_AssignmentExpressionsTerminator();

                    case 2048 /* HeritageClause_TypeNameList */:
                        return this.isExpectedHeritageClause_TypeNameListTerminator();

                    case 4096 /* VariableDeclaration_VariableDeclarators_AllowIn */:
                        return this.isExpectedVariableDeclaration_VariableDeclarators_AllowInTerminator();

                    case 8192 /* VariableDeclaration_VariableDeclarators_DisallowIn */:
                        return this.isExpectedVariableDeclaration_VariableDeclarators_DisallowInTerminator();

                    case 32768 /* ObjectLiteralExpression_PropertyAssignments */:
                        return this.isExpectedObjectLiteralExpression_PropertyAssignmentsTerminator();

                    case 131072 /* ParameterList_Parameters */:
                        return this.isExpectedParameterList_ParametersTerminator();

                    case 262144 /* TypeArgumentList_Types */:
                        return this.isExpectedTypeArgumentList_TypesTerminator();

                    case 524288 /* TypeParameterList_TypeParameters */:
                        return this.isExpectedTypeParameterList_TypeParametersTerminator();

                    case 65536 /* ArrayLiteralExpression_AssignmentExpressions */:
                        return this.isExpectedLiteralExpression_AssignmentExpressionsTerminator();

                    default:
                        throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.isExpectedSourceUnit_ModuleElementsTerminator = function () {
                return this.currentToken().tokenKind === 10 /* EndOfFileToken */;
            };

            ParserImpl.prototype.isExpectedEnumDeclaration_EnumElementsTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedModuleDeclaration_ModuleElementsTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedObjectType_TypeMembersTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedObjectLiteralExpression_PropertyAssignmentsTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedLiteralExpression_AssignmentExpressionsTerminator = function () {
                return this.currentToken().tokenKind === 75 /* CloseBracketToken */;
            };

            ParserImpl.prototype.isExpectedTypeArgumentList_TypesTerminator = function () {
                var token = this.currentToken();
                if (token.tokenKind === 81 /* GreaterThanToken */) {
                    return true;
                }

                if (this.canFollowTypeArgumentListInExpression(token.tokenKind)) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.isExpectedTypeParameterList_TypeParametersTerminator = function () {
                var token = this.currentToken();
                if (token.tokenKind === 81 /* GreaterThanToken */) {
                    return true;
                }

                if (token.tokenKind === 72 /* OpenParenToken */ || token.tokenKind === 70 /* OpenBraceToken */ || token.tokenKind === 48 /* ExtendsKeyword */ || token.tokenKind === 51 /* ImplementsKeyword */) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.isExpectedParameterList_ParametersTerminator = function () {
                var token = this.currentToken();
                if (token.tokenKind === 73 /* CloseParenToken */) {
                    return true;
                }

                if (token.tokenKind === 70 /* OpenBraceToken */) {
                    return true;
                }

                if (token.tokenKind === 85 /* EqualsGreaterThanToken */) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.isExpectedVariableDeclaration_VariableDeclarators_DisallowInTerminator = function () {
                if (this.currentToken().tokenKind === 78 /* SemicolonToken */ || this.currentToken().tokenKind === 73 /* CloseParenToken */) {
                    return true;
                }

                if (this.currentToken().tokenKind === 29 /* InKeyword */) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.isExpectedVariableDeclaration_VariableDeclarators_AllowInTerminator = function () {
                if (this.previousToken().tokenKind === 79 /* CommaToken */) {
                    return false;
                }

                if (this.currentToken().tokenKind === 85 /* EqualsGreaterThanToken */) {
                    return true;
                }

                return this.canEatExplicitOrAutomaticSemicolon(false);
            };

            ParserImpl.prototype.isExpectedClassOrInterfaceDeclaration_HeritageClausesTerminator = function () {
                var token0 = this.currentToken();
                if (token0.tokenKind === 70 /* OpenBraceToken */ || token0.tokenKind === 71 /* CloseBraceToken */) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.isExpectedHeritageClause_TypeNameListTerminator = function () {
                var token0 = this.currentToken();
                if (token0.tokenKind === 48 /* ExtendsKeyword */ || token0.tokenKind === 51 /* ImplementsKeyword */) {
                    return true;
                }

                if (this.isExpectedClassOrInterfaceDeclaration_HeritageClausesTerminator()) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.isExpectedArgumentList_AssignmentExpressionsTerminator = function () {
                var token0 = this.currentToken();
                return token0.tokenKind === 73 /* CloseParenToken */ || token0.tokenKind === 78 /* SemicolonToken */;
            };

            ParserImpl.prototype.isExpectedClassDeclaration_ClassElementsTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedSwitchStatement_SwitchClausesTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedSwitchClause_StatementsTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */ || this.isSwitchClause();
            };

            ParserImpl.prototype.isExpectedBlock_StatementsTerminator = function () {
                return this.currentToken().tokenKind === 71 /* CloseBraceToken */;
            };

            ParserImpl.prototype.isExpectedTryBlock_StatementsTerminator = function () {
                return this.currentToken().tokenKind === 17 /* CatchKeyword */ || this.currentToken().tokenKind === 25 /* FinallyKeyword */;
            };

            ParserImpl.prototype.isExpectedCatchBlock_StatementsTerminator = function () {
                return this.currentToken().tokenKind === 25 /* FinallyKeyword */;
            };

            ParserImpl.prototype.isExpectedListItem = function (currentListType, inErrorRecovery) {
                switch (currentListType) {
                    case 1 /* SourceUnit_ModuleElements */:
                        return this.isModuleElement(inErrorRecovery);

                    case 1024 /* ClassOrInterfaceDeclaration_HeritageClauses */:
                        return this.isHeritageClause();

                    case 2 /* ClassDeclaration_ClassElements */:
                        return this.isClassElement(inErrorRecovery);

                    case 4 /* ModuleDeclaration_ModuleElements */:
                        return this.isModuleElement(inErrorRecovery);

                    case 8 /* SwitchStatement_SwitchClauses */:
                        return this.isSwitchClause();

                    case 16 /* SwitchClause_Statements */:
                        return this.isStatement(inErrorRecovery);

                    case 32 /* Block_Statements */:
                        return this.isStatement(inErrorRecovery);

                    case 64 /* TryBlock_Statements */:
                    case 128 /* CatchBlock_Statements */:
                        return false;

                    case 256 /* EnumDeclaration_EnumElements */:
                        return this.isEnumElement(inErrorRecovery);

                    case 4096 /* VariableDeclaration_VariableDeclarators_AllowIn */:
                    case 8192 /* VariableDeclaration_VariableDeclarators_DisallowIn */:
                        return this.isVariableDeclarator();

                    case 512 /* ObjectType_TypeMembers */:
                        return this.isTypeMember(inErrorRecovery);

                    case 16384 /* ArgumentList_AssignmentExpressions */:
                        return this.isExpectedArgumentList_AssignmentExpression();

                    case 2048 /* HeritageClause_TypeNameList */:
                        return this.isHeritageClauseTypeName();

                    case 32768 /* ObjectLiteralExpression_PropertyAssignments */:
                        return this.isPropertyAssignment(inErrorRecovery);

                    case 131072 /* ParameterList_Parameters */:
                        return this.isParameter();

                    case 262144 /* TypeArgumentList_Types */:
                        return this.isType();

                    case 524288 /* TypeParameterList_TypeParameters */:
                        return this.isTypeParameter();

                    case 65536 /* ArrayLiteralExpression_AssignmentExpressions */:
                        return this.isAssignmentOrOmittedExpression();

                    default:
                        throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.isExpectedArgumentList_AssignmentExpression = function () {
                var currentToken = this.currentToken();
                if (this.isExpression(currentToken)) {
                    return true;
                }

                if (currentToken.tokenKind === 79 /* CommaToken */) {
                    return true;
                }

                return false;
            };

            ParserImpl.prototype.parseExpectedListItem = function (currentListType, inErrorRecovery) {
                switch (currentListType) {
                    case 1 /* SourceUnit_ModuleElements */:
                        return this.parseModuleElement(inErrorRecovery);

                    case 1024 /* ClassOrInterfaceDeclaration_HeritageClauses */:
                        return this.parseHeritageClause();

                    case 2 /* ClassDeclaration_ClassElements */:
                        return this.parseClassElement(inErrorRecovery);

                    case 4 /* ModuleDeclaration_ModuleElements */:
                        return this.parseModuleElement(inErrorRecovery);

                    case 8 /* SwitchStatement_SwitchClauses */:
                        return this.parseSwitchClause();

                    case 16 /* SwitchClause_Statements */:
                        return this.parseStatement(inErrorRecovery);

                    case 32 /* Block_Statements */:
                        return this.parseStatement(inErrorRecovery);

                    case 256 /* EnumDeclaration_EnumElements */:
                        return this.parseEnumElement();

                    case 512 /* ObjectType_TypeMembers */:
                        return this.parseTypeMember(inErrorRecovery);

                    case 16384 /* ArgumentList_AssignmentExpressions */:
                        return this.parseAssignmentExpression(true);

                    case 2048 /* HeritageClause_TypeNameList */:
                        return this.parseNameOrGenericType();

                    case 4096 /* VariableDeclaration_VariableDeclarators_AllowIn */:
                        return this.parseVariableDeclarator(true, false);

                    case 8192 /* VariableDeclaration_VariableDeclarators_DisallowIn */:
                        return this.parseVariableDeclarator(false, false);

                    case 32768 /* ObjectLiteralExpression_PropertyAssignments */:
                        return this.parsePropertyAssignment(inErrorRecovery);

                    case 65536 /* ArrayLiteralExpression_AssignmentExpressions */:
                        return this.parseAssignmentOrOmittedExpression();

                    case 131072 /* ParameterList_Parameters */:
                        return this.parseParameter();

                    case 262144 /* TypeArgumentList_Types */:
                        return this.parseType();

                    case 524288 /* TypeParameterList_TypeParameters */:
                        return this.parseTypeParameter();

                    default:
                        throw TypeScript.Errors.invalidOperation();
                }
            };

            ParserImpl.prototype.getExpectedListElementType = function (currentListType) {
                switch (currentListType) {
                    case 1 /* SourceUnit_ModuleElements */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.module_class_interface_enum_import_or_statement, null);

                    case 1024 /* ClassOrInterfaceDeclaration_HeritageClauses */:
                        return '{';

                    case 2 /* ClassDeclaration_ClassElements */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.constructor_function_accessor_or_variable, null);

                    case 4 /* ModuleDeclaration_ModuleElements */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.module_class_interface_enum_import_or_statement, null);

                    case 8 /* SwitchStatement_SwitchClauses */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.case_or_default_clause, null);

                    case 16 /* SwitchClause_Statements */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.statement, null);

                    case 32 /* Block_Statements */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.statement, null);

                    case 4096 /* VariableDeclaration_VariableDeclarators_AllowIn */:
                    case 8192 /* VariableDeclaration_VariableDeclarators_DisallowIn */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.identifier, null);

                    case 256 /* EnumDeclaration_EnumElements */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.identifier, null);

                    case 512 /* ObjectType_TypeMembers */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.call_construct_index_property_or_function_signature, null);

                    case 16384 /* ArgumentList_AssignmentExpressions */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.expression, null);

                    case 2048 /* HeritageClause_TypeNameList */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.type_name, null);

                    case 32768 /* ObjectLiteralExpression_PropertyAssignments */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.property_or_accessor, null);

                    case 131072 /* ParameterList_Parameters */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.parameter, null);

                    case 262144 /* TypeArgumentList_Types */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.type, null);

                    case 524288 /* TypeParameterList_TypeParameters */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.type_parameter, null);

                    case 65536 /* ArrayLiteralExpression_AssignmentExpressions */:
                        return TypeScript.getLocalizedText(TypeScript.DiagnosticCode.expression, null);

                    default:
                        throw TypeScript.Errors.invalidOperation();
                }
            };
            return ParserImpl;
        })();

        function parse(fileName, text, isDeclaration, options) {
            var source = new NormalParserSource(fileName, text, options.languageVersion());

            return new ParserImpl(fileName, text.lineMap(), source, options, text).parseSyntaxTree(isDeclaration);
        }
        Parser.parse = parse;

        function incrementalParse(oldSyntaxTree, textChangeRange, newText) {
            if (textChangeRange.isUnchanged()) {
                return oldSyntaxTree;
            }

            var source = new IncrementalParserSource(oldSyntaxTree, textChangeRange, newText);

            return new ParserImpl(oldSyntaxTree.fileName(), newText.lineMap(), source, oldSyntaxTree.parseOptions(), newText).parseSyntaxTree(oldSyntaxTree.isDeclaration());
        }
        Parser.incrementalParse = incrementalParse;
    })(TypeScript.Parser || (TypeScript.Parser = {}));
    var Parser = TypeScript.Parser;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxTree = (function () {
        function SyntaxTree(sourceUnit, isDeclaration, diagnostics, fileName, lineMap, parseOtions) {
            this._allDiagnostics = null;
            this._sourceUnit = sourceUnit;
            this._isDeclaration = isDeclaration;
            this._parserDiagnostics = diagnostics;
            this._fileName = fileName;
            this._lineMap = lineMap;
            this._parseOptions = parseOtions;
        }
        SyntaxTree.prototype.toJSON = function (key) {
            var result = {};

            result.isDeclaration = this._isDeclaration;
            result.languageVersion = TypeScript.LanguageVersion[this._parseOptions.languageVersion()];
            result.parseOptions = this._parseOptions;

            if (this.diagnostics().length > 0) {
                result.diagnostics = this.diagnostics();
            }

            result.sourceUnit = this._sourceUnit;
            result.lineMap = this._lineMap;

            return result;
        };

        SyntaxTree.prototype.sourceUnit = function () {
            return this._sourceUnit;
        };

        SyntaxTree.prototype.isDeclaration = function () {
            return this._isDeclaration;
        };

        SyntaxTree.prototype.computeDiagnostics = function () {
            if (this._parserDiagnostics.length > 0) {
                return this._parserDiagnostics;
            }

            var diagnostics = [];
            this.sourceUnit().accept(new GrammarCheckerWalker(this, diagnostics));

            return diagnostics;
        };

        SyntaxTree.prototype.diagnostics = function () {
            if (this._allDiagnostics === null) {
                this._allDiagnostics = this.computeDiagnostics();
            }

            return this._allDiagnostics;
        };

        SyntaxTree.prototype.fileName = function () {
            return this._fileName;
        };

        SyntaxTree.prototype.lineMap = function () {
            return this._lineMap;
        };

        SyntaxTree.prototype.parseOptions = function () {
            return this._parseOptions;
        };

        SyntaxTree.prototype.structuralEquals = function (tree) {
            return TypeScript.ArrayUtilities.sequenceEquals(this.diagnostics(), tree.diagnostics(), TypeScript.Diagnostic.equals) && this.sourceUnit().structuralEquals(tree.sourceUnit());
        };
        return SyntaxTree;
    })();
    TypeScript.SyntaxTree = SyntaxTree;

    var GrammarCheckerWalker = (function (_super) {
        __extends(GrammarCheckerWalker, _super);
        function GrammarCheckerWalker(syntaxTree, diagnostics) {
            _super.call(this);
            this.syntaxTree = syntaxTree;
            this.diagnostics = diagnostics;
            this.inAmbientDeclaration = false;
            this.inBlock = false;
            this.inObjectLiteralExpression = false;
            this.currentConstructor = null;
        }
        GrammarCheckerWalker.prototype.childFullStart = function (parent, child) {
            return this.position() + TypeScript.Syntax.childOffset(parent, child);
        };

        GrammarCheckerWalker.prototype.childStart = function (parent, child) {
            return this.childFullStart(parent, child) + child.leadingTriviaWidth();
        };

        GrammarCheckerWalker.prototype.pushDiagnostic = function (start, length, diagnosticKey, args) {
            if (typeof args === "undefined") { args = null; }
            this.diagnostics.push(new TypeScript.Diagnostic(this.syntaxTree.fileName(), this.syntaxTree.lineMap(), start, length, diagnosticKey, args));
        };

        GrammarCheckerWalker.prototype.pushDiagnostic1 = function (elementFullStart, element, diagnosticKey, args) {
            if (typeof args === "undefined") { args = null; }
            this.diagnostics.push(new TypeScript.Diagnostic(this.syntaxTree.fileName(), this.syntaxTree.lineMap(), elementFullStart + element.leadingTriviaWidth(), element.width(), diagnosticKey, args));
        };

        GrammarCheckerWalker.prototype.visitCatchClause = function (node) {
            if (node.typeAnnotation) {
                this.pushDiagnostic(this.childStart(node, node.typeAnnotation), node.typeAnnotation.width(), TypeScript.DiagnosticCode.Catch_clause_parameter_cannot_have_a_type_annotation);
            }

            _super.prototype.visitCatchClause.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkParameterListOrder = function (node) {
            var parameterFullStart = this.childFullStart(node, node.parameters);

            var seenOptionalParameter = false;
            var parameterCount = node.parameters.nonSeparatorCount();

            for (var i = 0, n = node.parameters.childCount(); i < n; i++) {
                var nodeOrToken = node.parameters.childAt(i);
                if (i % 2 === 0) {
                    var parameterIndex = i / 2;
                    var parameter = node.parameters.childAt(i);

                    if (parameter.dotDotDotToken) {
                        if (parameterIndex !== (parameterCount - 1)) {
                            this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Rest_parameter_must_be_last_in_list);
                            return true;
                        }

                        if (parameter.questionToken) {
                            this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Rest_parameter_cannot_be_optional);
                            return true;
                        }

                        if (parameter.equalsValueClause) {
                            this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Rest_parameter_cannot_have_an_initializer);
                            return true;
                        }
                    } else if (parameter.questionToken || parameter.equalsValueClause) {
                        seenOptionalParameter = true;

                        if (parameter.questionToken && parameter.equalsValueClause) {
                            this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Parameter_cannot_have_question_mark_and_initializer);
                            return true;
                        }
                    } else {
                        if (seenOptionalParameter) {
                            this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Required_parameter_cannot_follow_optional_parameter);
                            return true;
                        }
                    }
                }

                parameterFullStart += nodeOrToken.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkParameterListAcessibilityModifiers = function (node) {
            var parameterFullStart = this.childFullStart(node, node.parameters);

            for (var i = 0, n = node.parameters.childCount(); i < n; i++) {
                var nodeOrToken = node.parameters.childAt(i);
                if (i % 2 === 0) {
                    var parameter = node.parameters.childAt(i);

                    if (this.checkParameterAccessibilityModifiers(node, parameter, parameterFullStart)) {
                        return true;
                    }
                }

                parameterFullStart += nodeOrToken.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkParameterAccessibilityModifiers = function (parameterList, parameter, parameterFullStart) {
            if (parameter.modifiers.childCount() > 0) {
                var modifiers = parameter.modifiers;
                var modifierFullStart = parameterFullStart + TypeScript.Syntax.childOffset(parameter, modifiers);

                for (var i = 0, n = modifiers.childCount(); i < n; i++) {
                    var modifier = modifiers.childAt(i);

                    if (this.checkParameterAccessibilityModifier(parameterList, modifier, modifierFullStart, i)) {
                        return true;
                    }

                    modifierFullStart += modifier.fullWidth();
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkParameterAccessibilityModifier = function (parameterList, modifier, modifierFullStart, modifierIndex) {
            if (modifier.tokenKind !== 57 /* PublicKeyword */ && modifier.tokenKind !== 55 /* PrivateKeyword */) {
                this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_cannot_appear_on_a_parameter, [modifier.text()]);
                return true;
            } else {
                if (modifierIndex > 0) {
                    this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode.Accessibility_modifier_already_seen);
                    return true;
                }

                if (!this.inAmbientDeclaration && this.currentConstructor && !this.currentConstructor.block && this.currentConstructor.callSignature.parameterList === parameterList) {
                    this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode.Parameter_property_declarations_cannot_be_used_in_a_constructor_overload);
                    return true;
                } else if (this.inAmbientDeclaration || this.currentConstructor === null || this.currentConstructor.callSignature.parameterList !== parameterList) {
                    this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode.Parameter_property_declarations_can_only_be_used_in_a_non_ambient_constructor_declaration);
                    return true;
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForTrailingSeparator = function (parent, list) {
            if (list.childCount() === 0 || list.childCount() % 2 === 1) {
                return false;
            }

            var currentElementFullStart = this.childFullStart(parent, list);

            for (var i = 0, n = list.childCount(); i < n; i++) {
                var child = list.childAt(i);
                if (i === n - 1) {
                    this.pushDiagnostic1(currentElementFullStart, child, TypeScript.DiagnosticCode.Trailing_separator_not_allowed);
                }

                currentElementFullStart += child.fullWidth();
            }

            return true;
        };

        GrammarCheckerWalker.prototype.checkForAtLeastOneElement = function (parent, list, expected) {
            if (list.childCount() > 0) {
                return false;
            }

            var listFullStart = this.childFullStart(parent, list);
            var tokenAtStart = this.syntaxTree.sourceUnit().findToken(listFullStart);

            this.pushDiagnostic1(listFullStart, tokenAtStart.token(), TypeScript.DiagnosticCode.Unexpected_token_0_expected, [expected]);

            return true;
        };

        GrammarCheckerWalker.prototype.visitParameterList = function (node) {
            if (this.checkParameterListAcessibilityModifiers(node) || this.checkParameterListOrder(node) || this.checkForTrailingSeparator(node, node.parameters)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitParameterList.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitHeritageClause = function (node) {
            if (this.checkForTrailingSeparator(node, node.typeNames) || this.checkForAtLeastOneElement(node, node.typeNames, TypeScript.getLocalizedText(TypeScript.DiagnosticCode.type_name, null))) {
                this.skip(node);
                return;
            }

            _super.prototype.visitHeritageClause.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitArgumentList = function (node) {
            if (this.checkForTrailingSeparator(node, node.arguments)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitArgumentList.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitVariableDeclaration = function (node) {
            if (this.checkForTrailingSeparator(node, node.variableDeclarators) || this.checkForAtLeastOneElement(node, node.variableDeclarators, TypeScript.getLocalizedText(TypeScript.DiagnosticCode.identifier, null))) {
                this.skip(node);
                return;
            }

            _super.prototype.visitVariableDeclaration.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitTypeArgumentList = function (node) {
            if (this.checkForTrailingSeparator(node, node.typeArguments) || this.checkForAtLeastOneElement(node, node.typeArguments, TypeScript.getLocalizedText(TypeScript.DiagnosticCode.identifier, null))) {
                this.skip(node);
                return;
            }

            _super.prototype.visitTypeArgumentList.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitTypeParameterList = function (node) {
            if (this.checkForTrailingSeparator(node, node.typeParameters) || this.checkForAtLeastOneElement(node, node.typeParameters, TypeScript.getLocalizedText(TypeScript.DiagnosticCode.identifier, null))) {
                this.skip(node);
                return;
            }

            _super.prototype.visitTypeParameterList.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkIndexSignatureParameter = function (node) {
            var parameterFullStart = this.childFullStart(node, node.parameter);
            var parameter = node.parameter;

            if (parameter.dotDotDotToken) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Index_signatures_cannot_have_rest_parameters);
                return true;
            } else if (parameter.modifiers.childCount() > 0) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Index_signature_parameter_cannot_have_accessibility_modifiers);
                return true;
            } else if (parameter.questionToken) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Index_signature_parameter_cannot_have_a_question_mark);
                return true;
            } else if (parameter.equalsValueClause) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Index_signature_parameter_cannot_have_an_initializer);
                return true;
            } else if (!parameter.typeAnnotation) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Index_signature_parameter_must_have_a_type_annotation);
                return true;
            } else if (parameter.typeAnnotation.type.kind() !== 69 /* StringKeyword */ && parameter.typeAnnotation.type.kind() !== 67 /* NumberKeyword */) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.Index_signature_parameter_type_must_be_string_or_number);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitIndexSignature = function (node) {
            if (this.checkIndexSignatureParameter(node)) {
                this.skip(node);
                return;
            }

            if (!node.typeAnnotation) {
                this.pushDiagnostic1(this.position(), node, TypeScript.DiagnosticCode.Index_signature_must_have_a_type_annotation);
                this.skip(node);
                return;
            }

            _super.prototype.visitIndexSignature.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkClassDeclarationHeritageClauses = function (node) {
            var heritageClauseFullStart = this.childFullStart(node, node.heritageClauses);

            var seenExtendsClause = false;
            var seenImplementsClause = false;

            for (var i = 0, n = node.heritageClauses.childCount(); i < n; i++) {
                TypeScript.Debug.assert(i <= 2);
                var heritageClause = node.heritageClauses.childAt(i);

                if (heritageClause.extendsOrImplementsKeyword.tokenKind === 48 /* ExtendsKeyword */) {
                    if (seenExtendsClause) {
                        this.pushDiagnostic1(heritageClauseFullStart, heritageClause, TypeScript.DiagnosticCode.extends_clause_already_seen);
                        return true;
                    }

                    if (seenImplementsClause) {
                        this.pushDiagnostic1(heritageClauseFullStart, heritageClause, TypeScript.DiagnosticCode.extends_clause_must_precede_implements_clause);
                        return true;
                    }

                    if (heritageClause.typeNames.nonSeparatorCount() > 1) {
                        this.pushDiagnostic1(heritageClauseFullStart, heritageClause, TypeScript.DiagnosticCode.Classes_can_only_extend_a_single_class);
                        return true;
                    }

                    seenExtendsClause = true;
                } else {
                    TypeScript.Debug.assert(heritageClause.extendsOrImplementsKeyword.tokenKind === 51 /* ImplementsKeyword */);
                    if (seenImplementsClause) {
                        this.pushDiagnostic1(heritageClauseFullStart, heritageClause, TypeScript.DiagnosticCode.implements_clause_already_seen);
                        return true;
                    }

                    seenImplementsClause = true;
                }

                heritageClauseFullStart += heritageClause.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForDisallowedDeclareModifier = function (modifiers) {
            if (this.inAmbientDeclaration) {
                var declareToken = TypeScript.SyntaxUtilities.getToken(modifiers, 63 /* DeclareKeyword */);

                if (declareToken) {
                    this.pushDiagnostic1(this.childFullStart(modifiers, declareToken), declareToken, TypeScript.DiagnosticCode.declare_modifier_not_allowed_for_code_already_in_an_ambient_context);
                    return true;
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForRequiredDeclareModifier = function (moduleElement, typeKeyword, modifiers) {
            if (!this.inAmbientDeclaration && this.syntaxTree.isDeclaration()) {
                if (!TypeScript.SyntaxUtilities.containsToken(modifiers, 63 /* DeclareKeyword */)) {
                    this.pushDiagnostic1(this.childFullStart(moduleElement, typeKeyword), typeKeyword.firstToken(), TypeScript.DiagnosticCode.declare_modifier_required_for_top_level_element);
                    return true;
                }
            }
        };

        GrammarCheckerWalker.prototype.checkFunctionOverloads = function (node, moduleElements) {
            if (!this.inAmbientDeclaration && !this.syntaxTree.isDeclaration()) {
                var moduleElementFullStart = this.childFullStart(node, moduleElements);

                var inFunctionOverloadChain = false;
                var functionOverloadChainName = null;

                for (var i = 0, n = moduleElements.childCount(); i < n; i++) {
                    var moduleElement = moduleElements.childAt(i);
                    var lastElement = i === (n - 1);

                    if (inFunctionOverloadChain) {
                        if (moduleElement.kind() !== 129 /* FunctionDeclaration */) {
                            this.pushDiagnostic1(moduleElementFullStart, moduleElement.firstToken(), TypeScript.DiagnosticCode.Function_implementation_expected);
                            return true;
                        }

                        var functionDeclaration = moduleElement;
                        if (functionDeclaration.identifier.valueText() !== functionOverloadChainName) {
                            var identifierFullStart = moduleElementFullStart + TypeScript.Syntax.childOffset(moduleElement, functionDeclaration.identifier);
                            this.pushDiagnostic1(identifierFullStart, functionDeclaration.identifier, TypeScript.DiagnosticCode.Function_overload_name_must_be_0, [functionOverloadChainName]);
                            return true;
                        }
                    }

                    if (moduleElement.kind() === 129 /* FunctionDeclaration */) {
                        functionDeclaration = moduleElement;
                        if (!TypeScript.SyntaxUtilities.containsToken(functionDeclaration.modifiers, 63 /* DeclareKeyword */)) {
                            inFunctionOverloadChain = functionDeclaration.block === null;
                            functionOverloadChainName = functionDeclaration.identifier.valueText();

                            if (inFunctionOverloadChain) {
                                if (lastElement) {
                                    this.pushDiagnostic1(moduleElementFullStart, moduleElement.firstToken(), TypeScript.DiagnosticCode.Function_implementation_expected);
                                    return true;
                                } else {
                                    var nextElement = moduleElements.childAt(i + 1);
                                    if (nextElement.kind() === 129 /* FunctionDeclaration */) {
                                        var nextFunction = nextElement;

                                        if (nextFunction.identifier.valueText() !== functionOverloadChainName && nextFunction.block === null) {
                                            var identifierFullStart = moduleElementFullStart + TypeScript.Syntax.childOffset(moduleElement, functionDeclaration.identifier);
                                            this.pushDiagnostic1(identifierFullStart, functionDeclaration.identifier, TypeScript.DiagnosticCode.Function_implementation_expected);
                                            return true;
                                        }
                                    }
                                }
                            }
                        } else {
                            inFunctionOverloadChain = false;
                            functionOverloadChainName = "";
                        }
                    }

                    moduleElementFullStart += moduleElement.fullWidth();
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkClassOverloads = function (node) {
            if (!this.inAmbientDeclaration && !TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */)) {
                var classElementFullStart = this.childFullStart(node, node.classElements);

                var inFunctionOverloadChain = false;
                var inConstructorOverloadChain = false;

                var functionOverloadChainName = null;
                var isInStaticOverloadChain = null;
                var memberFunctionDeclaration = null;

                for (var i = 0, n = node.classElements.childCount(); i < n; i++) {
                    var classElement = node.classElements.childAt(i);
                    var lastElement = i === (n - 1);
                    var isStaticOverload = null;

                    if (inFunctionOverloadChain) {
                        if (classElement.kind() !== 135 /* MemberFunctionDeclaration */) {
                            this.pushDiagnostic1(classElementFullStart, classElement.firstToken(), TypeScript.DiagnosticCode.Function_implementation_expected);
                            return true;
                        }

                        memberFunctionDeclaration = classElement;
                        if (memberFunctionDeclaration.propertyName.valueText() !== functionOverloadChainName) {
                            var propertyNameFullStart = classElementFullStart + TypeScript.Syntax.childOffset(classElement, memberFunctionDeclaration.propertyName);
                            this.pushDiagnostic1(propertyNameFullStart, memberFunctionDeclaration.propertyName, TypeScript.DiagnosticCode.Function_overload_name_must_be_0, [functionOverloadChainName]);
                            return true;
                        }

                        isStaticOverload = TypeScript.SyntaxUtilities.containsToken(memberFunctionDeclaration.modifiers, 58 /* StaticKeyword */);
                        if (isStaticOverload !== isInStaticOverloadChain) {
                            var propertyNameFullStart = classElementFullStart + TypeScript.Syntax.childOffset(classElement, memberFunctionDeclaration.propertyName);
                            var diagnostic = isInStaticOverloadChain ? TypeScript.DiagnosticCode.Function_overload_must_be_static : TypeScript.DiagnosticCode.Function_overload_must_not_be_static;
                            this.pushDiagnostic1(propertyNameFullStart, memberFunctionDeclaration.propertyName, diagnostic, null);
                            return true;
                        }
                    } else if (inConstructorOverloadChain) {
                        if (classElement.kind() !== 137 /* ConstructorDeclaration */) {
                            this.pushDiagnostic1(classElementFullStart, classElement.firstToken(), TypeScript.DiagnosticCode.Constructor_implementation_expected);
                            return true;
                        }
                    }

                    if (classElement.kind() === 135 /* MemberFunctionDeclaration */) {
                        memberFunctionDeclaration = classElement;

                        inFunctionOverloadChain = memberFunctionDeclaration.block === null;
                        functionOverloadChainName = memberFunctionDeclaration.propertyName.valueText();
                        isInStaticOverloadChain = TypeScript.SyntaxUtilities.containsToken(memberFunctionDeclaration.modifiers, 58 /* StaticKeyword */);

                        if (inFunctionOverloadChain) {
                            if (lastElement) {
                                this.pushDiagnostic1(classElementFullStart, classElement.firstToken(), TypeScript.DiagnosticCode.Function_implementation_expected);
                                return true;
                            } else {
                                var nextElement = node.classElements.childAt(i + 1);
                                if (nextElement.kind() === 135 /* MemberFunctionDeclaration */) {
                                    var nextMemberFunction = nextElement;

                                    if (nextMemberFunction.propertyName.valueText() !== functionOverloadChainName && nextMemberFunction.block === null) {
                                        var propertyNameFullStart = classElementFullStart + TypeScript.Syntax.childOffset(classElement, memberFunctionDeclaration.propertyName);
                                        this.pushDiagnostic1(propertyNameFullStart, memberFunctionDeclaration.propertyName, TypeScript.DiagnosticCode.Function_implementation_expected);
                                        return true;
                                    }
                                }
                            }
                        }
                    } else if (classElement.kind() === 137 /* ConstructorDeclaration */) {
                        var constructorDeclaration = classElement;

                        inConstructorOverloadChain = constructorDeclaration.block === null;
                        if (lastElement && inConstructorOverloadChain) {
                            this.pushDiagnostic1(classElementFullStart, classElement.firstToken(), TypeScript.DiagnosticCode.Constructor_implementation_expected);
                            return true;
                        }
                    }

                    classElementFullStart += classElement.fullWidth();
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForReservedName = function (parent, name, diagnosticKey) {
            var nameFullStart = this.childFullStart(parent, name);
            var token;
            var tokenFullStart;

            var current = name;
            while (current !== null) {
                if (current.kind() === 121 /* QualifiedName */) {
                    var qualifiedName = current;
                    token = qualifiedName.right;
                    tokenFullStart = nameFullStart + this.childFullStart(qualifiedName, token);
                    current = qualifiedName.left;
                } else {
                    TypeScript.Debug.assert(current.kind() === 11 /* IdentifierName */);
                    token = current;
                    tokenFullStart = nameFullStart;
                    current = null;
                }

                switch (token.valueText()) {
                    case "any":
                    case "number":
                    case "boolean":
                    case "string":
                    case "void":
                        this.pushDiagnostic(tokenFullStart + token.leadingTriviaWidth(), token.width(), diagnosticKey, [token.valueText()]);
                        return true;
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitClassDeclaration = function (node) {
            if (this.checkForReservedName(node, node.identifier, TypeScript.DiagnosticCode.Class_name_cannot_be_0) || this.checkForDisallowedDeclareModifier(node.modifiers) || this.checkForRequiredDeclareModifier(node, node.classKeyword, node.modifiers) || this.checkModuleElementModifiers(node.modifiers) || this.checkClassDeclarationHeritageClauses(node) || this.checkClassOverloads(node)) {
                this.skip(node);
                return;
            }

            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = this.inAmbientDeclaration || this.syntaxTree.isDeclaration() || TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */);
            _super.prototype.visitClassDeclaration.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.checkInterfaceDeclarationHeritageClauses = function (node) {
            var heritageClauseFullStart = this.childFullStart(node, node.heritageClauses);

            var seenExtendsClause = false;

            for (var i = 0, n = node.heritageClauses.childCount(); i < n; i++) {
                TypeScript.Debug.assert(i <= 1);
                var heritageClause = node.heritageClauses.childAt(i);

                if (heritageClause.extendsOrImplementsKeyword.tokenKind === 48 /* ExtendsKeyword */) {
                    if (seenExtendsClause) {
                        this.pushDiagnostic1(heritageClauseFullStart, heritageClause, TypeScript.DiagnosticCode.extends_clause_already_seen);
                        return true;
                    }

                    seenExtendsClause = true;
                } else {
                    TypeScript.Debug.assert(heritageClause.extendsOrImplementsKeyword.tokenKind === 51 /* ImplementsKeyword */);
                    this.pushDiagnostic1(heritageClauseFullStart, heritageClause, TypeScript.DiagnosticCode.Interface_declaration_cannot_have_implements_clause);
                    return true;
                }

                heritageClauseFullStart += heritageClause.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkInterfaceModifiers = function (modifiers) {
            var modifierFullStart = this.position();

            for (var i = 0, n = modifiers.childCount(); i < n; i++) {
                var modifier = modifiers.childAt(i);
                if (modifier.tokenKind === 63 /* DeclareKeyword */) {
                    this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode.declare_modifier_cannot_appear_on_an_interface_declaration);
                    return true;
                }

                modifierFullStart += modifier.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitInterfaceDeclaration = function (node) {
            if (this.checkForReservedName(node, node.identifier, TypeScript.DiagnosticCode.Interface_name_cannot_be_0) || this.checkInterfaceModifiers(node.modifiers) || this.checkModuleElementModifiers(node.modifiers) || this.checkInterfaceDeclarationHeritageClauses(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitInterfaceDeclaration.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkClassElementModifiers = function (list) {
            var modifierFullStart = this.position();

            var seenAccessibilityModifier = false;
            var seenStaticModifier = false;

            for (var i = 0, n = list.childCount(); i < n; i++) {
                var modifier = list.childAt(i);
                if (modifier.tokenKind === 57 /* PublicKeyword */ || modifier.tokenKind === 55 /* PrivateKeyword */) {
                    if (seenAccessibilityModifier) {
                        this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode.Accessibility_modifier_already_seen);
                        return true;
                    }

                    if (seenStaticModifier) {
                        var previousToken = list.childAt(i - 1);
                        this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_must_precede_1_modifier, [modifier.text(), previousToken.text()]);
                        return true;
                    }

                    seenAccessibilityModifier = true;
                } else if (modifier.tokenKind === 58 /* StaticKeyword */) {
                    if (seenStaticModifier) {
                        this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_already_seen, [modifier.text()]);
                        return true;
                    }

                    seenStaticModifier = true;
                } else {
                    this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_cannot_appear_on_a_class_element, [modifier.text()]);
                    return true;
                }

                modifierFullStart += modifier.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitMemberVariableDeclaration = function (node) {
            if (this.checkClassElementModifiers(node.modifiers)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitMemberVariableDeclaration.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitMemberFunctionDeclaration = function (node) {
            if (this.checkClassElementModifiers(node.modifiers)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitMemberFunctionDeclaration.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkGetAccessorParameter = function (node, getKeyword, parameterList) {
            var getKeywordFullStart = this.childFullStart(node, getKeyword);
            if (parameterList.parameters.childCount() !== 0) {
                this.pushDiagnostic1(getKeywordFullStart, getKeyword, TypeScript.DiagnosticCode.get_accessor_cannot_have_parameters);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitIndexMemberDeclaration = function (node) {
            if (this.checkIndexMemberModifiers(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitIndexMemberDeclaration.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkIndexMemberModifiers = function (node) {
            if (node.modifiers.childCount() > 0) {
                var modifierFullStart = this.childFullStart(node, node.modifiers);
                this.pushDiagnostic1(modifierFullStart, node.modifiers.childAt(0), TypeScript.DiagnosticCode.Modifiers_cannot_appear_here);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkEcmaScriptVersionIsAtLeast = function (parent, node, languageVersion, diagnosticKey) {
            if (this.syntaxTree.parseOptions().languageVersion() < languageVersion) {
                var nodeFullStart = this.childFullStart(parent, node);
                this.pushDiagnostic1(nodeFullStart, node, diagnosticKey);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitObjectLiteralExpression = function (node) {
            var savedInObjectLiteralExpression = this.inObjectLiteralExpression;
            this.inObjectLiteralExpression = true;
            _super.prototype.visitObjectLiteralExpression.call(this, node);
            this.inObjectLiteralExpression = savedInObjectLiteralExpression;
        };

        GrammarCheckerWalker.prototype.visitGetAccessor = function (node) {
            if (this.checkForAccessorDeclarationInAmbientContext(node) || this.checkEcmaScriptVersionIsAtLeast(node, node.getKeyword, 1 /* EcmaScript5 */, TypeScript.DiagnosticCode.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher) || this.checkForDisallowedModifiers(node, node.modifiers) || this.checkClassElementModifiers(node.modifiers) || this.checkGetAccessorParameter(node, node.getKeyword, node.parameterList)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitGetAccessor.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkForAccessorDeclarationInAmbientContext = function (accessor) {
            if (this.inAmbientDeclaration) {
                this.pushDiagnostic1(this.position(), accessor, TypeScript.DiagnosticCode.Accessors_are_not_allowed_in_ambient_contexts, null);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkSetAccessorParameter = function (node, setKeyword, parameterList) {
            var setKeywordFullStart = this.childFullStart(node, setKeyword);
            if (parameterList.parameters.childCount() !== 1) {
                this.pushDiagnostic1(setKeywordFullStart, setKeyword, TypeScript.DiagnosticCode.set_accessor_must_have_one_and_only_one_parameter);
                return true;
            }

            var parameterListFullStart = this.childFullStart(node, parameterList);
            var parameterFullStart = parameterListFullStart + TypeScript.Syntax.childOffset(parameterList, parameterList.openParenToken);
            var parameter = parameterList.parameters.childAt(0);

            if (parameter.questionToken) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.set_accessor_parameter_cannot_be_optional);
                return true;
            }

            if (parameter.equalsValueClause) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.set_accessor_parameter_cannot_have_an_initializer);
                return true;
            }

            if (parameter.dotDotDotToken) {
                this.pushDiagnostic1(parameterFullStart, parameter, TypeScript.DiagnosticCode.set_accessor_cannot_have_rest_parameter);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitSetAccessor = function (node) {
            if (this.checkForAccessorDeclarationInAmbientContext(node) || this.checkEcmaScriptVersionIsAtLeast(node, node.setKeyword, 1 /* EcmaScript5 */, TypeScript.DiagnosticCode.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher) || this.checkForDisallowedModifiers(node, node.modifiers) || this.checkClassElementModifiers(node.modifiers) || this.checkSetAccessorParameter(node, node.setKeyword, node.parameterList)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitSetAccessor.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitEnumDeclaration = function (node) {
            if (this.checkForReservedName(node, node.identifier, TypeScript.DiagnosticCode.Enum_name_cannot_be_0) || this.checkForDisallowedDeclareModifier(node.modifiers) || this.checkForRequiredDeclareModifier(node, node.enumKeyword, node.modifiers) || this.checkModuleElementModifiers(node.modifiers), this.checkEnumElements(node)) {
                this.skip(node);
                return;
            }

            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = this.inAmbientDeclaration || this.syntaxTree.isDeclaration() || TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */);
            _super.prototype.visitEnumDeclaration.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.checkEnumElements = function (node) {
            var enumElementFullStart = this.childFullStart(node, node.enumElements);

            var previousValueWasComputed = false;
            for (var i = 0, n = node.enumElements.childCount(); i < n; i++) {
                var child = node.enumElements.childAt(i);

                if (i % 2 === 0) {
                    var enumElement = child;

                    if (!enumElement.equalsValueClause && previousValueWasComputed) {
                        this.pushDiagnostic1(enumElementFullStart, enumElement, TypeScript.DiagnosticCode.Enum_member_must_have_initializer, null);
                        return true;
                    }

                    if (enumElement.equalsValueClause) {
                        var value = enumElement.equalsValueClause.value;
                        previousValueWasComputed = !TypeScript.Syntax.isIntegerLiteral(value);
                    }
                }

                enumElementFullStart += child.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitEnumElement = function (node) {
            if (this.inAmbientDeclaration && node.equalsValueClause) {
                var expression = node.equalsValueClause.value;
                if (!TypeScript.Syntax.isIntegerLiteral(expression)) {
                    this.pushDiagnostic1(this.childFullStart(node, node.equalsValueClause), node.equalsValueClause.firstToken(), TypeScript.DiagnosticCode.Ambient_enum_elements_can_only_have_integer_literal_initializers);
                    this.skip(node);
                    return;
                }
            }

            _super.prototype.visitEnumElement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitInvocationExpression = function (node) {
            if (node.expression.kind() === 50 /* SuperKeyword */ && node.argumentList.typeArgumentList !== null) {
                this.pushDiagnostic1(this.position(), node, TypeScript.DiagnosticCode.super_invocation_cannot_have_type_arguments);
            }

            _super.prototype.visitInvocationExpression.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkModuleElementModifiers = function (modifiers) {
            var modifierFullStart = this.position();
            var seenExportModifier = false;
            var seenDeclareModifier = false;

            for (var i = 0, n = modifiers.childCount(); i < n; i++) {
                var modifier = modifiers.childAt(i);
                if (modifier.tokenKind === 57 /* PublicKeyword */ || modifier.tokenKind === 55 /* PrivateKeyword */ || modifier.tokenKind === 58 /* StaticKeyword */) {
                    this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_cannot_appear_on_a_module_element, [modifier.text()]);
                    return true;
                }

                if (modifier.tokenKind === 63 /* DeclareKeyword */) {
                    if (seenDeclareModifier) {
                        this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode.Accessibility_modifier_already_seen);
                        return;
                    }

                    seenDeclareModifier = true;
                } else if (modifier.tokenKind === 47 /* ExportKeyword */) {
                    if (seenExportModifier) {
                        this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_already_seen, [modifier.text()]);
                        return;
                    }

                    if (seenDeclareModifier) {
                        this.pushDiagnostic1(modifierFullStart, modifier, TypeScript.DiagnosticCode._0_modifier_must_precede_1_modifier, [TypeScript.SyntaxFacts.getText(47 /* ExportKeyword */), TypeScript.SyntaxFacts.getText(63 /* DeclareKeyword */)]);
                        return;
                    }

                    seenExportModifier = true;
                }

                modifierFullStart += modifier.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForDisallowedImportDeclaration = function (node) {
            var currentElementFullStart = this.childFullStart(node, node.moduleElements);

            for (var i = 0, n = node.moduleElements.childCount(); i < n; i++) {
                var child = node.moduleElements.childAt(i);
                if (child.kind() === 133 /* ImportDeclaration */) {
                    var importDeclaration = child;
                    if (importDeclaration.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                        if (node.stringLiteral === null) {
                            this.pushDiagnostic1(currentElementFullStart, importDeclaration, TypeScript.DiagnosticCode.Import_declarations_in_an_internal_module_cannot_reference_an_external_module, null);
                        }
                    }
                }

                currentElementFullStart += child.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForDisallowedDeclareModifierOnImportDeclaration = function (modifiers) {
            var declareToken = TypeScript.SyntaxUtilities.getToken(modifiers, 63 /* DeclareKeyword */);

            if (declareToken) {
                this.pushDiagnostic1(this.childFullStart(modifiers, declareToken), declareToken, TypeScript.DiagnosticCode.declare_modifier_not_allowed_on_import_declaration);
                return true;
            }
        };

        GrammarCheckerWalker.prototype.visitImportDeclaration = function (node) {
            if (this.checkForDisallowedDeclareModifierOnImportDeclaration(node.modifiers) || this.checkModuleElementModifiers(node.modifiers)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitImportDeclaration.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitModuleDeclaration = function (node) {
            if (this.checkForReservedName(node, node.name, TypeScript.DiagnosticCode.Module_name_cannot_be_0) || this.checkForDisallowedDeclareModifier(node.modifiers) || this.checkForRequiredDeclareModifier(node, node.moduleKeyword, node.modifiers) || this.checkModuleElementModifiers(node.modifiers) || this.checkForDisallowedImportDeclaration(node) || this.checkForDisallowedExports(node, node.moduleElements) || this.checkForMultipleExportAssignments(node, node.moduleElements)) {
                this.skip(node);
                return;
            }

            if (!TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */) && this.checkFunctionOverloads(node, node.moduleElements)) {
                this.skip(node);
                return;
            }

            if (node.stringLiteral) {
                if (!this.inAmbientDeclaration && !TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */)) {
                    var stringLiteralFullStart = this.childFullStart(node, node.stringLiteral);
                    this.pushDiagnostic1(stringLiteralFullStart, node.stringLiteral, TypeScript.DiagnosticCode.Only_ambient_modules_can_use_quoted_names);
                    this.skip(node);
                    return;
                }
            }

            if (!node.stringLiteral && this.checkForDisallowedExportAssignment(node)) {
                this.skip(node);
                return;
            }

            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = this.inAmbientDeclaration || this.syntaxTree.isDeclaration() || TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */);
            _super.prototype.visitModuleDeclaration.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.checkForDisallowedExports = function (node, moduleElements) {
            var seenExportedElement = false;
            for (var i = 0, n = moduleElements.childCount(); i < n; i++) {
                var child = moduleElements.childAt(i);

                if (TypeScript.SyntaxUtilities.hasExportKeyword(child)) {
                    seenExportedElement = true;
                    break;
                }
            }

            var moduleElementFullStart = this.childFullStart(node, moduleElements);
            if (seenExportedElement) {
                for (var i = 0, n = moduleElements.childCount(); i < n; i++) {
                    var child = moduleElements.childAt(i);

                    if (child.kind() === 134 /* ExportAssignment */) {
                        this.pushDiagnostic1(moduleElementFullStart, child, TypeScript.DiagnosticCode.Export_assignment_not_allowed_in_module_with_exported_element);
                        return true;
                    }

                    moduleElementFullStart += child.fullWidth();
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkForMultipleExportAssignments = function (node, moduleElements) {
            var moduleElementFullStart = this.childFullStart(node, moduleElements);
            var seenExportAssignment = false;
            var errorFound = false;
            for (var i = 0, n = moduleElements.childCount(); i < n; i++) {
                var child = moduleElements.childAt(i);
                if (child.kind() === 134 /* ExportAssignment */) {
                    if (seenExportAssignment) {
                        this.pushDiagnostic1(moduleElementFullStart, child, TypeScript.DiagnosticCode.Module_cannot_have_multiple_export_assignments);
                        errorFound = true;
                    }
                    seenExportAssignment = true;
                }

                moduleElementFullStart += child.fullWidth();
            }

            return errorFound;
        };

        GrammarCheckerWalker.prototype.checkForDisallowedExportAssignment = function (node) {
            var moduleElementFullStart = this.childFullStart(node, node.moduleElements);

            for (var i = 0, n = node.moduleElements.childCount(); i < n; i++) {
                var child = node.moduleElements.childAt(i);

                if (child.kind() === 134 /* ExportAssignment */) {
                    this.pushDiagnostic1(moduleElementFullStart, child, TypeScript.DiagnosticCode.Export_assignment_cannot_be_used_in_internal_modules);

                    return true;
                }

                moduleElementFullStart += child.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitBlock = function (node) {
            if (this.inAmbientDeclaration || this.syntaxTree.isDeclaration()) {
                this.pushDiagnostic1(this.position(), node.firstToken(), TypeScript.DiagnosticCode.Implementations_are_not_allowed_in_ambient_contexts);
                this.skip(node);
                return;
            }

            if (this.checkFunctionOverloads(node, node.statements)) {
                this.skip(node);
                return;
            }

            var savedInBlock = this.inBlock;
            this.inBlock = true;
            _super.prototype.visitBlock.call(this, node);
            this.inBlock = savedInBlock;
        };

        GrammarCheckerWalker.prototype.checkForStatementInAmbientContxt = function (node) {
            if (this.inAmbientDeclaration || this.syntaxTree.isDeclaration()) {
                this.pushDiagnostic1(this.position(), node.firstToken(), TypeScript.DiagnosticCode.Statements_are_not_allowed_in_ambient_contexts);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitBreakStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitBreakStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitContinueStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitContinueStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitDebuggerStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitDebuggerStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitDoStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitDoStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitEmptyStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitEmptyStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitExpressionStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitExpressionStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitForInStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node) || this.checkForInStatementVariableDeclaration(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitForInStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkForInStatementVariableDeclaration = function (node) {
            if (node.variableDeclaration && node.variableDeclaration.variableDeclarators.nonSeparatorCount() > 1) {
                var variableDeclarationFullStart = this.childFullStart(node, node.variableDeclaration);

                this.pushDiagnostic1(variableDeclarationFullStart, node.variableDeclaration, TypeScript.DiagnosticCode.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitForStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitForStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitIfStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitIfStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitLabeledStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitLabeledStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitReturnStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitReturnStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitSwitchStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitSwitchStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitThrowStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitThrowStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitTryStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitTryStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitWhileStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitWhileStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitWithStatement = function (node) {
            if (this.checkForStatementInAmbientContxt(node)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitWithStatement.call(this, node);
        };

        GrammarCheckerWalker.prototype.checkForDisallowedModifiers = function (parent, modifiers) {
            if (this.inBlock || this.inObjectLiteralExpression) {
                if (modifiers.childCount() > 0) {
                    var modifierFullStart = this.childFullStart(parent, modifiers);
                    this.pushDiagnostic1(modifierFullStart, modifiers.childAt(0), TypeScript.DiagnosticCode.Modifiers_cannot_appear_here);
                    return true;
                }
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitFunctionDeclaration = function (node) {
            if (this.checkForDisallowedDeclareModifier(node.modifiers) || this.checkForDisallowedModifiers(node, node.modifiers) || this.checkForRequiredDeclareModifier(node, node.functionKeyword, node.modifiers) || this.checkModuleElementModifiers(node.modifiers)) {
                this.skip(node);
                return;
            }

            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = this.inAmbientDeclaration || this.syntaxTree.isDeclaration() || TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */);
            _super.prototype.visitFunctionDeclaration.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.visitVariableStatement = function (node) {
            if (this.checkForDisallowedDeclareModifier(node.modifiers) || this.checkForDisallowedModifiers(node, node.modifiers) || this.checkForRequiredDeclareModifier(node, node.variableDeclaration, node.modifiers) || this.checkModuleElementModifiers(node.modifiers)) {
                this.skip(node);
                return;
            }

            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = this.inAmbientDeclaration || this.syntaxTree.isDeclaration() || TypeScript.SyntaxUtilities.containsToken(node.modifiers, 63 /* DeclareKeyword */);
            _super.prototype.visitVariableStatement.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.checkListSeparators = function (parent, list, kind) {
            var currentElementFullStart = this.childFullStart(parent, list);

            for (var i = 0, n = list.childCount(); i < n; i++) {
                var child = list.childAt(i);
                if (i % 2 === 1 && child.kind() !== kind) {
                    this.pushDiagnostic1(currentElementFullStart, child, TypeScript.DiagnosticCode._0_expected, [TypeScript.SyntaxFacts.getText(kind)]);
                }

                currentElementFullStart += child.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitObjectType = function (node) {
            if (this.checkListSeparators(node, node.typeMembers, 78 /* SemicolonToken */)) {
                this.skip(node);
                return;
            }

            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = true;
            _super.prototype.visitObjectType.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.visitArrayType = function (node) {
            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = true;
            _super.prototype.visitArrayType.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.visitFunctionType = function (node) {
            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = true;
            _super.prototype.visitFunctionType.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.visitConstructorType = function (node) {
            var savedInAmbientDeclaration = this.inAmbientDeclaration;
            this.inAmbientDeclaration = true;
            _super.prototype.visitConstructorType.call(this, node);
            this.inAmbientDeclaration = savedInAmbientDeclaration;
        };

        GrammarCheckerWalker.prototype.visitVariableDeclarator = function (node) {
            if (this.inAmbientDeclaration && node.equalsValueClause) {
                this.pushDiagnostic1(this.childFullStart(node, node.equalsValueClause), node.equalsValueClause.firstToken(), TypeScript.DiagnosticCode.Initializers_are_not_allowed_in_ambient_contexts);
                this.skip(node);
                return;
            }

            _super.prototype.visitVariableDeclarator.call(this, node);
        };

        GrammarCheckerWalker.prototype.visitConstructorDeclaration = function (node) {
            if (this.checkClassElementModifiers(node.modifiers) || this.checkConstructorModifiers(node.modifiers) || this.checkConstructorTypeParameterList(node) || this.checkConstructorTypeAnnotation(node)) {
                this.skip(node);
                return;
            }

            var savedCurrentConstructor = this.currentConstructor;
            this.currentConstructor = node;
            _super.prototype.visitConstructorDeclaration.call(this, node);
            this.currentConstructor = savedCurrentConstructor;
        };

        GrammarCheckerWalker.prototype.checkConstructorModifiers = function (modifiers) {
            var currentElementFullStart = this.position();

            for (var i = 0, n = modifiers.childCount(); i < n; i++) {
                var child = modifiers.childAt(i);
                if (child.kind() !== 57 /* PublicKeyword */) {
                    this.pushDiagnostic1(currentElementFullStart, child, TypeScript.DiagnosticCode._0_modifier_cannot_appear_on_a_constructor_declaration, [TypeScript.SyntaxFacts.getText(child.kind())]);
                    return true;
                }

                currentElementFullStart += child.fullWidth();
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkConstructorTypeParameterList = function (node) {
            var currentElementFullStart = this.position();

            if (node.callSignature.typeParameterList) {
                var callSignatureFullStart = this.childFullStart(node, node.callSignature);
                var typeParameterListFullStart = callSignatureFullStart + TypeScript.Syntax.childOffset(node.callSignature, node.callSignature.typeAnnotation);
                this.pushDiagnostic1(callSignatureFullStart, node.callSignature.typeParameterList, TypeScript.DiagnosticCode.Type_parameters_cannot_appear_on_a_constructor_declaration);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.checkConstructorTypeAnnotation = function (node) {
            var currentElementFullStart = this.position();

            if (node.callSignature.typeAnnotation) {
                var callSignatureFullStart = this.childFullStart(node, node.callSignature);
                var typeAnnotationFullStart = callSignatureFullStart + TypeScript.Syntax.childOffset(node.callSignature, node.callSignature.typeAnnotation);
                this.pushDiagnostic1(typeAnnotationFullStart, node.callSignature.typeAnnotation, TypeScript.DiagnosticCode.Type_annotation_cannot_appear_on_a_constructor_declaration);
                return true;
            }

            return false;
        };

        GrammarCheckerWalker.prototype.visitSourceUnit = function (node) {
            if (this.checkFunctionOverloads(node, node.moduleElements) || this.checkForDisallowedExports(node, node.moduleElements) || this.checkForMultipleExportAssignments(node, node.moduleElements)) {
                this.skip(node);
                return;
            }

            _super.prototype.visitSourceUnit.call(this, node);
        };
        return GrammarCheckerWalker;
    })(TypeScript.PositionTrackingWalker);
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var Unicode = (function () {
        function Unicode() {
        }
        Unicode.lookupInUnicodeMap = function (code, map) {
            if (code < map[0]) {
                return false;
            }

            var lo = 0;
            var hi = map.length;
            var mid;

            while (lo + 1 < hi) {
                mid = lo + (hi - lo) / 2;

                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;
        };

        Unicode.isIdentifierStart = function (code, languageVersion) {
            if (languageVersion === 0 /* EcmaScript3 */) {
                return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES3IdentifierStart);
            } else if (languageVersion === 1 /* EcmaScript5 */) {
                return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES5IdentifierStart);
            } else {
                throw TypeScript.Errors.argumentOutOfRange("languageVersion");
            }
        };

        Unicode.isIdentifierPart = function (code, languageVersion) {
            if (languageVersion === 0 /* EcmaScript3 */) {
                return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES3IdentifierPart);
            } else if (languageVersion === 1 /* EcmaScript5 */) {
                return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES5IdentifierPart);
            } else {
                throw TypeScript.Errors.argumentOutOfRange("languageVersion");
            }
        };
        Unicode.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];
        Unicode.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];

        Unicode.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];
        Unicode.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];
        return Unicode;
    })();
    TypeScript.Unicode = Unicode;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (CompilerDiagnostics) {
        CompilerDiagnostics.debug = false;

        CompilerDiagnostics.diagnosticWriter = null;

        CompilerDiagnostics.analysisPass = 0;

        function Alert(output) {
            if (CompilerDiagnostics.diagnosticWriter) {
                CompilerDiagnostics.diagnosticWriter.Alert(output);
            }
        }
        CompilerDiagnostics.Alert = Alert;

        function debugPrint(s) {
            if (CompilerDiagnostics.debug) {
                Alert(s);
            }
        }
        CompilerDiagnostics.debugPrint = debugPrint;

        function assert(condition, s) {
            if (CompilerDiagnostics.debug) {
                if (!condition) {
                    Alert(s);
                }
            }
        }
        CompilerDiagnostics.assert = assert;
    })(TypeScript.CompilerDiagnostics || (TypeScript.CompilerDiagnostics = {}));
    var CompilerDiagnostics = TypeScript.CompilerDiagnostics;

    var NullLogger = (function () {
        function NullLogger() {
        }
        NullLogger.prototype.information = function () {
            return false;
        };
        NullLogger.prototype.debug = function () {
            return false;
        };
        NullLogger.prototype.warning = function () {
            return false;
        };
        NullLogger.prototype.error = function () {
            return false;
        };
        NullLogger.prototype.fatal = function () {
            return false;
        };
        NullLogger.prototype.log = function (s) {
        };
        return NullLogger;
    })();
    TypeScript.NullLogger = NullLogger;

    function timeFunction(logger, funcDescription, func) {
        var start = (new Date()).getTime();
        var result = func();
        var end = (new Date()).getTime();
        if (logger.information()) {
            logger.log(funcDescription + " completed in " + (end - start) + " msec");
        }
        return result;
    }
    TypeScript.timeFunction = timeFunction;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var Document = (function () {
        function Document(_compiler, _semanticInfoChain, fileName, referencedFiles, _scriptSnapshot, byteOrderMark, version, isOpen, _syntaxTree, _topLevelDecl) {
            this._compiler = _compiler;
            this._semanticInfoChain = _semanticInfoChain;
            this.fileName = fileName;
            this.referencedFiles = referencedFiles;
            this._scriptSnapshot = _scriptSnapshot;
            this.byteOrderMark = byteOrderMark;
            this.version = version;
            this.isOpen = isOpen;
            this._syntaxTree = _syntaxTree;
            this._topLevelDecl = _topLevelDecl;
            this._diagnostics = null;
            this._bloomFilter = null;
            this._sourceUnit = null;
            this._lineMap = null;
            this._declASTMap = [];
            this._astDeclMap = [];
            this._amdDependencies = undefined;
            this._externalModuleIndicatorSpan = undefined;
        }
        Document.prototype.invalidate = function () {
            this._declASTMap.length = 0;
            this._astDeclMap.length = 0;
            this._topLevelDecl = null;

            this._syntaxTree = null;
            this._sourceUnit = null;
            this._diagnostics = null;
            this._bloomFilter = null;
        };

        Document.prototype.isDeclareFile = function () {
            return TypeScript.isDTSFile(this.fileName);
        };

        Document.prototype.cacheSyntaxTreeInfo = function (syntaxTree) {
            var start = new Date().getTime();
            this._diagnostics = syntaxTree.diagnostics();
            TypeScript.syntaxDiagnosticsTime += new Date().getTime() - start;

            this._lineMap = syntaxTree.lineMap();

            var sourceUnit = syntaxTree.sourceUnit();
            var leadingTrivia = sourceUnit.leadingTrivia();

            this._externalModuleIndicatorSpan = this.getImplicitImportSpan(leadingTrivia) || this.getTopLevelImportOrExportSpan(sourceUnit);

            var amdDependencies = [];
            for (var i = 0, n = leadingTrivia.count(); i < n; i++) {
                var trivia = leadingTrivia.syntaxTriviaAt(i);
                if (trivia.isComment()) {
                    var amdDependency = this.getAmdDependency(trivia.fullText());
                    if (amdDependency) {
                        amdDependencies.push(amdDependency);
                    }
                }
            }

            this._amdDependencies = amdDependencies;
        };

        Document.prototype.getAmdDependency = function (comment) {
            var amdDependencyRegEx = /^\/\/\/\s*<amd-dependency\s+path=('|")(.+?)\1/gim;
            var match = amdDependencyRegEx.exec(comment);
            return match ? match[2] : null;
        };

        Document.prototype.getImplicitImportSpan = function (sourceUnitLeadingTrivia) {
            var position = 0;

            for (var i = 0, n = sourceUnitLeadingTrivia.count(); i < n; i++) {
                var trivia = sourceUnitLeadingTrivia.syntaxTriviaAt(i);

                if (trivia.isComment()) {
                    var span = this.getImplicitImportSpanWorker(trivia, position);
                    if (span) {
                        return span;
                    }
                }

                position += trivia.fullWidth();
            }

            return null;
        };

        Document.prototype.getImplicitImportSpanWorker = function (trivia, position) {
            var implicitImportRegEx = /^(\/\/\/\s*<implicit-import\s*)*\/>/gim;
            var match = implicitImportRegEx.exec(trivia.fullText());

            if (match) {
                return new TypeScript.TextSpan(position, trivia.fullWidth());
            }

            return null;
        };

        Document.prototype.getTopLevelImportOrExportSpan = function (node) {
            var firstToken;
            var position = 0;

            for (var i = 0, n = node.moduleElements.childCount(); i < n; i++) {
                var moduleElement = node.moduleElements.childAt(i);

                firstToken = moduleElement.firstToken();
                if (firstToken !== null && firstToken.tokenKind === 47 /* ExportKeyword */) {
                    return new TypeScript.TextSpan(position + firstToken.leadingTriviaWidth(), firstToken.width());
                }

                if (moduleElement.kind() === 133 /* ImportDeclaration */) {
                    var importDecl = moduleElement;
                    if (importDecl.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                        return new TypeScript.TextSpan(position + importDecl.leadingTriviaWidth(), importDecl.width());
                    }
                }

                position += moduleElement.fullWidth();
            }

            return null;
            ;
        };

        Document.prototype.sourceUnit = function () {
            if (!this._sourceUnit) {
                var start = new Date().getTime();
                var syntaxTree = this.syntaxTree();
                this._sourceUnit = TypeScript.SyntaxTreeToAstVisitor.visit(syntaxTree, this.fileName, this._compiler.compilationSettings(), this.isOpen);
                TypeScript.astTranslationTime += new Date().getTime() - start;

                if (!this.isOpen) {
                    this._syntaxTree = null;
                }
            }

            return this._sourceUnit;
        };

        Document.prototype.diagnostics = function () {
            if (this._diagnostics === null) {
                this.syntaxTree();
                TypeScript.Debug.assert(this._diagnostics);
            }

            return this._diagnostics;
        };

        Document.prototype.lineMap = function () {
            if (this._lineMap === null) {
                this.syntaxTree();
                TypeScript.Debug.assert(this._lineMap);
            }

            return this._lineMap;
        };

        Document.prototype.isExternalModule = function () {
            return this.externalModuleIndicatorSpan() !== null;
        };

        Document.prototype.externalModuleIndicatorSpan = function () {
            if (this._externalModuleIndicatorSpan === undefined) {
                this.syntaxTree();
                TypeScript.Debug.assert(this._externalModuleIndicatorSpan !== undefined);
            }

            return this._externalModuleIndicatorSpan;
        };

        Document.prototype.amdDependencies = function () {
            if (this._amdDependencies === undefined) {
                this.syntaxTree();
                TypeScript.Debug.assert(this._amdDependencies !== undefined);
            }

            return this._amdDependencies;
        };

        Document.prototype.syntaxTree = function () {
            var result = this._syntaxTree;
            if (!result) {
                var start = new Date().getTime();

                result = TypeScript.Parser.parse(this.fileName, TypeScript.SimpleText.fromScriptSnapshot(this._scriptSnapshot), TypeScript.isDTSFile(this.fileName), TypeScript.getParseOptions(this._compiler.compilationSettings()));

                TypeScript.syntaxTreeParseTime += new Date().getTime() - start;

                if (this.isOpen || !this._sourceUnit) {
                    this._syntaxTree = result;
                }
            }

            this.cacheSyntaxTreeInfo(result);
            return result;
        };

        Document.prototype.bloomFilter = function () {
            if (!this._bloomFilter) {
                var identifiers = TypeScript.createIntrinsicsObject();
                var pre = function (cur) {
                    if (TypeScript.ASTHelpers.isValidAstNode(cur)) {
                        if (cur.kind() === 11 /* IdentifierName */) {
                            var nodeText = cur.valueText();

                            identifiers[nodeText] = true;
                        }
                    }
                };

                TypeScript.getAstWalkerFactory().simpleWalk(this.sourceUnit(), pre, null, identifiers);

                var identifierCount = 0;
                for (var name in identifiers) {
                    if (identifiers[name]) {
                        identifierCount++;
                    }
                }

                this._bloomFilter = new TypeScript.BloomFilter(identifierCount);
                this._bloomFilter.addKeys(identifiers);
            }
            return this._bloomFilter;
        };

        Document.prototype.emitToOwnOutputFile = function () {
            return !this._compiler.compilationSettings().outFileOption() || this.isExternalModule();
        };

        Document.prototype.update = function (scriptSnapshot, version, isOpen, textChangeRange) {
            var oldSyntaxTree = this._syntaxTree;

            if (textChangeRange !== null && TypeScript.Debug.shouldAssert(1 /* Normal */)) {
                var oldText = this._scriptSnapshot;
                var newText = scriptSnapshot;

                TypeScript.Debug.assert((oldText.getLength() - textChangeRange.span().length() + textChangeRange.newLength()) === newText.getLength());

                if (TypeScript.Debug.shouldAssert(3 /* VeryAggressive */)) {
                    var oldTextPrefix = oldText.getText(0, textChangeRange.span().start());
                    var newTextPrefix = newText.getText(0, textChangeRange.span().start());
                    TypeScript.Debug.assert(oldTextPrefix === newTextPrefix);

                    var oldTextSuffix = oldText.getText(textChangeRange.span().end(), oldText.getLength());
                    var newTextSuffix = newText.getText(textChangeRange.newSpan().end(), newText.getLength());
                    TypeScript.Debug.assert(oldTextSuffix === newTextSuffix);
                }
            }

            var text = TypeScript.SimpleText.fromScriptSnapshot(scriptSnapshot);

            var newSyntaxTree = textChangeRange === null || oldSyntaxTree === null ? TypeScript.Parser.parse(this.fileName, text, TypeScript.isDTSFile(this.fileName), TypeScript.getParseOptions(this._compiler.compilationSettings())) : TypeScript.Parser.incrementalParse(oldSyntaxTree, textChangeRange, text);

            return new Document(this._compiler, this._semanticInfoChain, this.fileName, this.referencedFiles, scriptSnapshot, this.byteOrderMark, version, isOpen, newSyntaxTree, null);
        };

        Document.create = function (compiler, semanticInfoChain, fileName, scriptSnapshot, byteOrderMark, version, isOpen, referencedFiles) {
            return new Document(compiler, semanticInfoChain, fileName, referencedFiles, scriptSnapshot, byteOrderMark, version, isOpen, null, null);
        };

        Document.prototype.topLevelDecl = function () {
            if (this._topLevelDecl === null) {
                this._topLevelDecl = TypeScript.DeclarationCreator.create(this, this._semanticInfoChain, this._compiler.compilationSettings());
            }

            return this._topLevelDecl;
        };

        Document.prototype._getDeclForAST = function (ast) {
            this.topLevelDecl();
            return this._astDeclMap[ast.syntaxID()];
        };

        Document.prototype.getEnclosingDecl = function (ast) {
            if (ast.kind() === 120 /* SourceUnit */) {
                return this._getDeclForAST(ast);
            }

            ast = ast.parent;
            var decl = null;
            while (ast) {
                decl = this._getDeclForAST(ast);

                if (decl) {
                    break;
                }

                ast = ast.parent;
            }

            return decl._getEnclosingDeclFromParentDecl();
        };

        Document.prototype._setDeclForAST = function (ast, decl) {
            TypeScript.Debug.assert(decl.fileName() === this.fileName);
            this._astDeclMap[ast.syntaxID()] = decl;
        };

        Document.prototype._getASTForDecl = function (decl) {
            return this._declASTMap[decl.declID];
        };

        Document.prototype._setASTForDecl = function (decl, ast) {
            TypeScript.Debug.assert(decl.fileName() === this.fileName);
            this._declASTMap[decl.declID] = ast;
        };
        return Document;
    })();
    TypeScript.Document = Document;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    function hasFlag(val, flag) {
        return (val & flag) !== 0;
    }
    TypeScript.hasFlag = hasFlag;

    (function (TypeRelationshipFlags) {
        TypeRelationshipFlags[TypeRelationshipFlags["SuccessfulComparison"] = 0] = "SuccessfulComparison";
        TypeRelationshipFlags[TypeRelationshipFlags["RequiredPropertyIsMissing"] = 1 << 1] = "RequiredPropertyIsMissing";
        TypeRelationshipFlags[TypeRelationshipFlags["IncompatibleSignatures"] = 1 << 2] = "IncompatibleSignatures";
        TypeRelationshipFlags[TypeRelationshipFlags["SourceSignatureHasTooManyParameters"] = 3] = "SourceSignatureHasTooManyParameters";
        TypeRelationshipFlags[TypeRelationshipFlags["IncompatibleReturnTypes"] = 1 << 4] = "IncompatibleReturnTypes";
        TypeRelationshipFlags[TypeRelationshipFlags["IncompatiblePropertyTypes"] = 1 << 5] = "IncompatiblePropertyTypes";
        TypeRelationshipFlags[TypeRelationshipFlags["IncompatibleParameterTypes"] = 1 << 6] = "IncompatibleParameterTypes";
        TypeRelationshipFlags[TypeRelationshipFlags["InconsistantPropertyAccesibility"] = 1 << 7] = "InconsistantPropertyAccesibility";
    })(TypeScript.TypeRelationshipFlags || (TypeScript.TypeRelationshipFlags = {}));
    var TypeRelationshipFlags = TypeScript.TypeRelationshipFlags;

    (function (ModuleGenTarget) {
        ModuleGenTarget[ModuleGenTarget["Unspecified"] = 0] = "Unspecified";
        ModuleGenTarget[ModuleGenTarget["Synchronous"] = 1] = "Synchronous";
        ModuleGenTarget[ModuleGenTarget["Asynchronous"] = 2] = "Asynchronous";
    })(TypeScript.ModuleGenTarget || (TypeScript.ModuleGenTarget = {}));
    var ModuleGenTarget = TypeScript.ModuleGenTarget;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var proto = "__proto__";

    var BlockIntrinsics = (function () {
        function BlockIntrinsics() {
            this.prototype = undefined;
            this.toString = undefined;
            this.toLocaleString = undefined;
            this.valueOf = undefined;
            this.hasOwnProperty = undefined;
            this.propertyIsEnumerable = undefined;
            this.isPrototypeOf = undefined;
            this["constructor"] = undefined;

            this[proto] = null;
            this[proto] = undefined;
        }
        return BlockIntrinsics;
    })();

    function createIntrinsicsObject() {
        return new BlockIntrinsics();
    }
    TypeScript.createIntrinsicsObject = createIntrinsicsObject;

    var StringHashTable = (function () {
        function StringHashTable() {
            this.itemCount = 0;
            this.table = createIntrinsicsObject();
        }
        StringHashTable.prototype.getAllKeys = function () {
            var result = [];

            for (var k in this.table) {
                if (this.table[k] !== undefined) {
                    result.push(k);
                }
            }

            return result;
        };

        StringHashTable.prototype.add = function (key, data) {
            if (this.table[key] !== undefined) {
                return false;
            }

            this.table[key] = data;
            this.itemCount++;
            return true;
        };

        StringHashTable.prototype.addOrUpdate = function (key, data) {
            if (this.table[key] !== undefined) {
                this.table[key] = data;
                return false;
            }

            this.table[key] = data;
            this.itemCount++;
            return true;
        };

        StringHashTable.prototype.map = function (fn, context) {
            for (var k in this.table) {
                var data = this.table[k];

                if (data !== undefined) {
                    fn(k, this.table[k], context);
                }
            }
        };

        StringHashTable.prototype.every = function (fn, context) {
            for (var k in this.table) {
                var data = this.table[k];

                if (data !== undefined) {
                    if (!fn(k, this.table[k], context)) {
                        return false;
                    }
                }
            }

            return true;
        };

        StringHashTable.prototype.some = function (fn, context) {
            for (var k in this.table) {
                var data = this.table[k];

                if (data !== undefined) {
                    if (fn(k, this.table[k], context)) {
                        return true;
                    }
                }
            }

            return false;
        };

        StringHashTable.prototype.count = function () {
            return this.itemCount;
        };

        StringHashTable.prototype.lookup = function (key) {
            var data = this.table[key];
            return data === undefined ? null : data;
        };

        StringHashTable.prototype.remove = function (key) {
            if (this.table[key] !== undefined) {
                this.table[key] = undefined;
                this.itemCount--;
            }
        };
        return StringHashTable;
    })();
    TypeScript.StringHashTable = StringHashTable;

    var IdentiferNameHashTable = (function (_super) {
        __extends(IdentiferNameHashTable, _super);
        function IdentiferNameHashTable() {
            _super.apply(this, arguments);
        }
        IdentiferNameHashTable.prototype.getAllKeys = function () {
            var result = [];

            _super.prototype.map.call(this, function (k, v, c) {
                if (v !== undefined) {
                    result.push(k.substring(1));
                }
            }, null);

            return result;
        };

        IdentiferNameHashTable.prototype.add = function (key, data) {
            return _super.prototype.add.call(this, "#" + key, data);
        };

        IdentiferNameHashTable.prototype.addOrUpdate = function (key, data) {
            return _super.prototype.addOrUpdate.call(this, "#" + key, data);
        };

        IdentiferNameHashTable.prototype.map = function (fn, context) {
            return _super.prototype.map.call(this, function (k, v, c) {
                return fn(k.substring(1), v, c);
            }, context);
        };

        IdentiferNameHashTable.prototype.every = function (fn, context) {
            return _super.prototype.every.call(this, function (k, v, c) {
                return fn(k.substring(1), v, c);
            }, context);
        };

        IdentiferNameHashTable.prototype.some = function (fn, context) {
            return _super.prototype.some.call(this, function (k, v, c) {
                return fn(k.substring(1), v, c);
            }, context);
        };

        IdentiferNameHashTable.prototype.lookup = function (key) {
            return _super.prototype.lookup.call(this, "#" + key);
        };
        return IdentiferNameHashTable;
    })(StringHashTable);
    TypeScript.IdentiferNameHashTable = IdentiferNameHashTable;
})(TypeScript || (TypeScript = {}));

var TypeScript;
(function (TypeScript) {
    (function (ASTHelpers) {
        function scriptIsElided(sourceUnit) {
            return TypeScript.isDTSFile(sourceUnit.fileName()) || moduleMembersAreElided(sourceUnit.moduleElements);
        }
        ASTHelpers.scriptIsElided = scriptIsElided;

        function moduleIsElided(declaration) {
            return TypeScript.hasModifier(declaration.modifiers, 8 /* Ambient */) || moduleMembersAreElided(declaration.moduleElements);
        }
        ASTHelpers.moduleIsElided = moduleIsElided;

        function moduleMembersAreElided(members) {
            for (var i = 0, n = members.childCount(); i < n; i++) {
                var member = members.childAt(i);

                if (member.kind() === 130 /* ModuleDeclaration */) {
                    if (!moduleIsElided(member)) {
                        return false;
                    }
                } else if (member.kind() !== 128 /* InterfaceDeclaration */) {
                    return false;
                }
            }

            return true;
        }

        function enumIsElided(declaration) {
            if (TypeScript.hasModifier(declaration.modifiers, 8 /* Ambient */)) {
                return true;
            }

            return false;
        }
        ASTHelpers.enumIsElided = enumIsElided;

        function isValidAstNode(ast) {
            if (!ast)
                return false;

            if (ast.start() === -1 || ast.end() === -1)
                return false;

            return true;
        }
        ASTHelpers.isValidAstNode = isValidAstNode;

        function getAstAtPosition(script, pos, useTrailingTriviaAsLimChar, forceInclusive) {
            if (typeof useTrailingTriviaAsLimChar === "undefined") { useTrailingTriviaAsLimChar = true; }
            if (typeof forceInclusive === "undefined") { forceInclusive = false; }
            var top = null;

            var pre = function (cur, walker) {
                if (isValidAstNode(cur)) {
                    var isInvalid1 = cur.kind() === 149 /* ExpressionStatement */ && cur.width() === 0;

                    if (isInvalid1) {
                        walker.options.goChildren = false;
                    } else {
                        var inclusive = forceInclusive || cur.kind() === 11 /* IdentifierName */ || cur.kind() === 212 /* MemberAccessExpression */ || cur.kind() === 121 /* QualifiedName */ || cur.kind() === 224 /* VariableDeclaration */ || cur.kind() === 225 /* VariableDeclarator */ || cur.kind() === 213 /* InvocationExpression */ || pos === script.end() + script.trailingTriviaWidth();

                        var minChar = cur.start();
                        var limChar = cur.end() + (useTrailingTriviaAsLimChar ? cur.trailingTriviaWidth() : 0) + (inclusive ? 1 : 0);
                        if (pos >= minChar && pos < limChar) {
                            if ((cur.kind() !== 1 /* List */ && cur.kind() !== 2 /* SeparatedList */) || cur.end() > cur.start()) {
                                if (top === null) {
                                    top = cur;
                                } else if (cur.start() >= top.start() && (cur.end() + (useTrailingTriviaAsLimChar ? cur.trailingTriviaWidth() : 0)) <= (top.end() + (useTrailingTriviaAsLimChar ? top.trailingTriviaWidth() : 0))) {
                                    if (top.width() !== 0 || cur.width() !== 0) {
                                        top = cur;
                                    }
                                }
                            }
                        }

                        walker.options.goChildren = (minChar <= pos && pos <= limChar);
                    }
                }
            };

            TypeScript.getAstWalkerFactory().walk(script, pre);
            return top;
        }
        ASTHelpers.getAstAtPosition = getAstAtPosition;

        function getExtendsHeritageClause(clauses) {
            if (!clauses) {
                return null;
            }

            return clauses.firstOrDefault(function (c) {
                return c.typeNames.nonSeparatorCount() > 0 && c.kind() === 230 /* ExtendsHeritageClause */;
            });
        }
        ASTHelpers.getExtendsHeritageClause = getExtendsHeritageClause;

        function getImplementsHeritageClause(clauses) {
            if (!clauses) {
                return null;
            }

            return clauses.firstOrDefault(function (c) {
                return c.typeNames.nonSeparatorCount() > 0 && c.kind() === 231 /* ImplementsHeritageClause */;
            });
        }
        ASTHelpers.getImplementsHeritageClause = getImplementsHeritageClause;

        function isCallExpression(ast) {
            return (ast && ast.kind() === 213 /* InvocationExpression */) || (ast && ast.kind() === 216 /* ObjectCreationExpression */);
        }
        ASTHelpers.isCallExpression = isCallExpression;

        function isCallExpressionTarget(ast) {
            if (!ast) {
                return false;
            }

            var current = ast;

            while (current && current.parent) {
                if (current.parent.kind() === 212 /* MemberAccessExpression */ && current.parent.name === current) {
                    current = current.parent;
                    continue;
                }

                break;
            }

            if (current && current.parent) {
                if (current.parent.kind() === 213 /* InvocationExpression */ || current.parent.kind() === 216 /* ObjectCreationExpression */) {
                    return current === current.parent.expression;
                }
            }

            return false;
        }
        ASTHelpers.isCallExpressionTarget = isCallExpressionTarget;

        function isNameOfSomeDeclaration(ast) {
            if (ast === null || ast.parent === null) {
                return false;
            }
            if (ast.kind() !== 11 /* IdentifierName */) {
                return false;
            }

            switch (ast.parent.kind()) {
                case 131 /* ClassDeclaration */:
                    return ast.parent.identifier === ast;
                case 128 /* InterfaceDeclaration */:
                    return ast.parent.identifier === ast;
                case 132 /* EnumDeclaration */:
                    return ast.parent.identifier === ast;
                case 130 /* ModuleDeclaration */:
                    return ast.parent.name === ast || ast.parent.stringLiteral === ast;
                case 225 /* VariableDeclarator */:
                    return ast.parent.propertyName === ast;
                case 129 /* FunctionDeclaration */:
                    return ast.parent.identifier === ast;
                case 135 /* MemberFunctionDeclaration */:
                    return ast.parent.propertyName === ast;
                case 242 /* Parameter */:
                    return ast.parent.identifier === ast;
                case 238 /* TypeParameter */:
                    return ast.parent.identifier === ast;
                case 240 /* SimplePropertyAssignment */:
                    return ast.parent.propertyName === ast;
                case 241 /* FunctionPropertyAssignment */:
                    return ast.parent.propertyName === ast;
                case 243 /* EnumElement */:
                    return ast.parent.propertyName === ast;
                case 133 /* ImportDeclaration */:
                    return ast.parent.identifier === ast;
            }

            return false;
        }

        function isDeclarationASTOrDeclarationNameAST(ast) {
            return isNameOfSomeDeclaration(ast) || isDeclarationAST(ast);
        }
        ASTHelpers.isDeclarationASTOrDeclarationNameAST = isDeclarationASTOrDeclarationNameAST;

        function getEnclosingParameterForInitializer(ast) {
            var current = ast;
            while (current) {
                switch (current.kind()) {
                    case 232 /* EqualsValueClause */:
                        if (current.parent && current.parent.kind() === 242 /* Parameter */) {
                            return current.parent;
                        }
                        break;
                    case 131 /* ClassDeclaration */:
                    case 128 /* InterfaceDeclaration */:
                    case 130 /* ModuleDeclaration */:
                        return null;
                }

                current = current.parent;
            }
            return null;
        }
        ASTHelpers.getEnclosingParameterForInitializer = getEnclosingParameterForInitializer;

        function getEnclosingMemberVariableDeclaration(ast) {
            var current = ast;

            while (current) {
                switch (current.kind()) {
                    case 136 /* MemberVariableDeclaration */:
                        return current;
                    case 131 /* ClassDeclaration */:
                    case 128 /* InterfaceDeclaration */:
                    case 130 /* ModuleDeclaration */:
                        return null;
                }
                current = current.parent;
            }

            return null;
        }
        ASTHelpers.getEnclosingMemberVariableDeclaration = getEnclosingMemberVariableDeclaration;

        function isNameOfFunction(ast) {
            return ast && ast.parent && ast.kind() === 11 /* IdentifierName */ && ast.parent.kind() === 129 /* FunctionDeclaration */ && ast.parent.identifier === ast;
        }
        ASTHelpers.isNameOfFunction = isNameOfFunction;

        function isNameOfMemberFunction(ast) {
            return ast && ast.parent && ast.kind() === 11 /* IdentifierName */ && ast.parent.kind() === 135 /* MemberFunctionDeclaration */ && ast.parent.propertyName === ast;
        }
        ASTHelpers.isNameOfMemberFunction = isNameOfMemberFunction;

        function isNameOfMemberAccessExpression(ast) {
            if (ast && ast.parent && ast.parent.kind() === 212 /* MemberAccessExpression */ && ast.parent.name === ast) {
                return true;
            }

            return false;
        }
        ASTHelpers.isNameOfMemberAccessExpression = isNameOfMemberAccessExpression;

        function isRightSideOfQualifiedName(ast) {
            if (ast && ast.parent && ast.parent.kind() === 121 /* QualifiedName */ && ast.parent.right === ast) {
                return true;
            }

            return false;
        }
        ASTHelpers.isRightSideOfQualifiedName = isRightSideOfQualifiedName;

        function parentIsModuleDeclaration(ast) {
            return ast.parent && ast.parent.kind() === 130 /* ModuleDeclaration */;
        }
        ASTHelpers.parentIsModuleDeclaration = parentIsModuleDeclaration;

        function parametersFromIdentifier(id) {
            return {
                length: 1,
                lastParameterIsRest: function () {
                    return false;
                },
                ast: id,
                astAt: function (index) {
                    return id;
                },
                identifierAt: function (index) {
                    return id;
                },
                typeAt: function (index) {
                    return null;
                },
                initializerAt: function (index) {
                    return null;
                },
                isOptionalAt: function (index) {
                    return false;
                }
            };
        }
        ASTHelpers.parametersFromIdentifier = parametersFromIdentifier;

        function parametersFromParameter(parameter) {
            return {
                length: 1,
                lastParameterIsRest: function () {
                    return parameter.dotDotDotToken !== null;
                },
                ast: parameter,
                astAt: function (index) {
                    return parameter;
                },
                identifierAt: function (index) {
                    return parameter.identifier;
                },
                typeAt: function (index) {
                    return getType(parameter);
                },
                initializerAt: function (index) {
                    return parameter.equalsValueClause;
                },
                isOptionalAt: function (index) {
                    return parameterIsOptional(parameter);
                }
            };
        }
        ASTHelpers.parametersFromParameter = parametersFromParameter;

        function parameterIsOptional(parameter) {
            return parameter.questionToken !== null || parameter.equalsValueClause !== null;
        }

        function parametersFromParameterList(list) {
            return {
                length: list.parameters.nonSeparatorCount(),
                lastParameterIsRest: function () {
                    return TypeScript.lastParameterIsRest(list);
                },
                ast: list.parameters,
                astAt: function (index) {
                    return list.parameters.nonSeparatorAt(index);
                },
                identifierAt: function (index) {
                    return list.parameters.nonSeparatorAt(index).identifier;
                },
                typeAt: function (index) {
                    return getType(list.parameters.nonSeparatorAt(index));
                },
                initializerAt: function (index) {
                    return list.parameters.nonSeparatorAt(index).equalsValueClause;
                },
                isOptionalAt: function (index) {
                    return parameterIsOptional(list.parameters.nonSeparatorAt(index));
                }
            };
        }
        ASTHelpers.parametersFromParameterList = parametersFromParameterList;

        function isDeclarationAST(ast) {
            switch (ast.kind()) {
                case 225 /* VariableDeclarator */:
                    return getVariableStatement(ast) !== null;

                case 133 /* ImportDeclaration */:
                case 131 /* ClassDeclaration */:
                case 128 /* InterfaceDeclaration */:
                case 242 /* Parameter */:
                case 219 /* SimpleArrowFunctionExpression */:
                case 218 /* ParenthesizedArrowFunctionExpression */:
                case 144 /* IndexSignature */:
                case 129 /* FunctionDeclaration */:
                case 130 /* ModuleDeclaration */:
                case 124 /* ArrayType */:
                case 122 /* ObjectType */:
                case 238 /* TypeParameter */:
                case 137 /* ConstructorDeclaration */:
                case 135 /* MemberFunctionDeclaration */:
                case 139 /* GetAccessor */:
                case 140 /* SetAccessor */:
                case 136 /* MemberVariableDeclaration */:
                case 138 /* IndexMemberDeclaration */:
                case 132 /* EnumDeclaration */:
                case 243 /* EnumElement */:
                case 240 /* SimplePropertyAssignment */:
                case 241 /* FunctionPropertyAssignment */:
                case 222 /* FunctionExpression */:
                case 142 /* CallSignature */:
                case 143 /* ConstructSignature */:
                case 145 /* MethodSignature */:
                case 141 /* PropertySignature */:
                    return true;
                default:
                    return false;
            }
        }
        ASTHelpers.isDeclarationAST = isDeclarationAST;

        function docComments(ast) {
            if (isDeclarationAST(ast)) {
                var preComments = ast.kind() === 225 /* VariableDeclarator */ ? getVariableStatement(ast).preComments() : ast.preComments();

                if (preComments && preComments.length > 0) {
                    var preCommentsLength = preComments.length;
                    var docComments = new Array();
                    for (var i = preCommentsLength - 1; i >= 0; i--) {
                        if (isDocComment(preComments[i])) {
                            docComments.push(preComments[i]);
                            continue;
                        }

                        break;
                    }

                    return docComments.reverse();
                }
            }

            return TypeScript.sentinelEmptyArray;
        }
        ASTHelpers.docComments = docComments;

        function isDocComment(comment) {
            if (comment.kind() === 6 /* MultiLineCommentTrivia */) {
                var fullText = comment.fullText();
                return fullText.charAt(2) === "*" && fullText.charAt(3) !== "/";
            }

            return false;
        }

        function getParameterList(ast) {
            if (ast) {
                switch (ast.kind()) {
                    case 137 /* ConstructorDeclaration */:
                        return getParameterList(ast.callSignature);
                    case 129 /* FunctionDeclaration */:
                        return getParameterList(ast.callSignature);
                    case 218 /* ParenthesizedArrowFunctionExpression */:
                        return getParameterList(ast.callSignature);
                    case 143 /* ConstructSignature */:
                        return getParameterList(ast.callSignature);
                    case 135 /* MemberFunctionDeclaration */:
                        return getParameterList(ast.callSignature);
                    case 241 /* FunctionPropertyAssignment */:
                        return getParameterList(ast.callSignature);
                    case 222 /* FunctionExpression */:
                        return getParameterList(ast.callSignature);
                    case 145 /* MethodSignature */:
                        return getParameterList(ast.callSignature);
                    case 125 /* ConstructorType */:
                        return ast.parameterList;
                    case 123 /* FunctionType */:
                        return ast.parameterList;
                    case 142 /* CallSignature */:
                        return ast.parameterList;
                    case 139 /* GetAccessor */:
                        return ast.parameterList;
                    case 140 /* SetAccessor */:
                        return ast.parameterList;
                }
            }

            return null;
        }
        ASTHelpers.getParameterList = getParameterList;

        function getType(ast) {
            if (ast) {
                switch (ast.kind()) {
                    case 129 /* FunctionDeclaration */:
                        return getType(ast.callSignature);
                    case 218 /* ParenthesizedArrowFunctionExpression */:
                        return getType(ast.callSignature);
                    case 143 /* ConstructSignature */:
                        return getType(ast.callSignature);
                    case 135 /* MemberFunctionDeclaration */:
                        return getType(ast.callSignature);
                    case 241 /* FunctionPropertyAssignment */:
                        return getType(ast.callSignature);
                    case 222 /* FunctionExpression */:
                        return getType(ast.callSignature);
                    case 145 /* MethodSignature */:
                        return getType(ast.callSignature);
                    case 142 /* CallSignature */:
                        return getType(ast.typeAnnotation);
                    case 144 /* IndexSignature */:
                        return getType(ast.typeAnnotation);
                    case 141 /* PropertySignature */:
                        return getType(ast.typeAnnotation);
                    case 139 /* GetAccessor */:
                        return getType(ast.typeAnnotation);
                    case 242 /* Parameter */:
                        return getType(ast.typeAnnotation);
                    case 136 /* MemberVariableDeclaration */:
                        return getType(ast.variableDeclarator);
                    case 225 /* VariableDeclarator */:
                        return getType(ast.typeAnnotation);
                    case 236 /* CatchClause */:
                        return getType(ast.typeAnnotation);
                    case 125 /* ConstructorType */:
                        return ast.type;
                    case 123 /* FunctionType */:
                        return ast.type;
                    case 244 /* TypeAnnotation */:
                        return ast.type;
                }
            }

            return null;
        }
        ASTHelpers.getType = getType;

        function getVariableStatement(variableDeclarator) {
            if (variableDeclarator && variableDeclarator.parent && variableDeclarator.parent.parent && variableDeclarator.parent.parent.parent && variableDeclarator.parent.kind() === 2 /* SeparatedList */ && variableDeclarator.parent.parent.kind() === 224 /* VariableDeclaration */ && variableDeclarator.parent.parent.parent.kind() === 148 /* VariableStatement */) {
                return variableDeclarator.parent.parent.parent;
            }

            return null;
        }

        function getVariableDeclaratorModifiers(variableDeclarator) {
            var variableStatement = getVariableStatement(variableDeclarator);
            return variableStatement ? variableStatement.modifiers : TypeScript.sentinelEmptyArray;
        }
        ASTHelpers.getVariableDeclaratorModifiers = getVariableDeclaratorModifiers;

        function isIntegerLiteralAST(expression) {
            if (expression) {
                switch (expression.kind()) {
                    case 164 /* PlusExpression */:
                    case 165 /* NegateExpression */:
                        expression = expression.operand;
                        return expression.kind() === 13 /* NumericLiteral */ && TypeScript.IntegerUtilities.isInteger(expression.text());

                    case 13 /* NumericLiteral */:
                        var text = expression.text();
                        return TypeScript.IntegerUtilities.isInteger(text) || TypeScript.IntegerUtilities.isHexInteger(text);
                }
            }

            return false;
        }
        ASTHelpers.isIntegerLiteralAST = isIntegerLiteralAST;

        function getEnclosingModuleDeclaration(ast) {
            while (ast) {
                if (ast.kind() === 130 /* ModuleDeclaration */) {
                    return ast;
                }

                ast = ast.parent;
            }

            return null;
        }
        ASTHelpers.getEnclosingModuleDeclaration = getEnclosingModuleDeclaration;

        function isEntireNameOfModuleDeclaration(nameAST) {
            return parentIsModuleDeclaration(nameAST) && nameAST.parent.name === nameAST;
        }

        function getModuleDeclarationFromNameAST(ast) {
            if (ast) {
                switch (ast.kind()) {
                    case 14 /* StringLiteral */:
                        if (parentIsModuleDeclaration(ast) && ast.parent.stringLiteral === ast) {
                            return ast.parent;
                        }
                        return null;

                    case 11 /* IdentifierName */:
                    case 121 /* QualifiedName */:
                        if (isEntireNameOfModuleDeclaration(ast)) {
                            return ast.parent;
                        }
                        break;

                    default:
                        return null;
                }

                for (ast = ast.parent; ast && ast.kind() === 121 /* QualifiedName */; ast = ast.parent) {
                    if (isEntireNameOfModuleDeclaration(ast)) {
                        return ast.parent;
                    }
                }
            }

            return null;
        }
        ASTHelpers.getModuleDeclarationFromNameAST = getModuleDeclarationFromNameAST;

        function isLastNameOfModule(ast, astName) {
            if (ast) {
                if (ast.stringLiteral) {
                    return astName === ast.stringLiteral;
                } else if (ast.name.kind() === 121 /* QualifiedName */) {
                    return astName === ast.name.right;
                } else {
                    return astName === ast.name;
                }
            }

            return false;
        }
        ASTHelpers.isLastNameOfModule = isLastNameOfModule;

        function getNameOfIdenfierOrQualifiedName(name) {
            if (name.kind() === 11 /* IdentifierName */) {
                return name.text();
            } else {
                TypeScript.Debug.assert(name.kind() == 121 /* QualifiedName */);
                var dotExpr = name;
                return getNameOfIdenfierOrQualifiedName(dotExpr.left) + "." + getNameOfIdenfierOrQualifiedName(dotExpr.right);
            }
        }
        ASTHelpers.getNameOfIdenfierOrQualifiedName = getNameOfIdenfierOrQualifiedName;

        function getModuleNames(name, result) {
            result = result || [];

            if (name.kind() === 121 /* QualifiedName */) {
                getModuleNames(name.left, result);
                result.push(name.right);
            } else {
                result.push(name);
            }

            return result;
        }
        ASTHelpers.getModuleNames = getModuleNames;
    })(TypeScript.ASTHelpers || (TypeScript.ASTHelpers = {}));
    var ASTHelpers = TypeScript.ASTHelpers;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    function walkListChildren(preAst, walker) {
        for (var i = 0, n = preAst.childCount(); i < n; i++) {
            walker.walk(preAst.childAt(i));
        }
    }

    function walkThrowStatementChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkPrefixUnaryExpressionChildren(preAst, walker) {
        walker.walk(preAst.operand);
    }

    function walkPostfixUnaryExpressionChildren(preAst, walker) {
        walker.walk(preAst.operand);
    }

    function walkDeleteExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkTypeArgumentListChildren(preAst, walker) {
        walker.walk(preAst.typeArguments);
    }

    function walkTypeOfExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkVoidExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkArgumentListChildren(preAst, walker) {
        walker.walk(preAst.typeArgumentList);
        walker.walk(preAst.arguments);
    }

    function walkArrayLiteralExpressionChildren(preAst, walker) {
        walker.walk(preAst.expressions);
    }

    function walkSimplePropertyAssignmentChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.expression);
    }

    function walkFunctionPropertyAssignmentChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.callSignature);
        walker.walk(preAst.block);
    }

    function walkGetAccessorChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.parameterList);
        walker.walk(preAst.typeAnnotation);
        walker.walk(preAst.block);
    }

    function walkSeparatedListChildren(preAst, walker) {
        for (var i = 0, n = preAst.nonSeparatorCount(); i < n; i++) {
            walker.walk(preAst.nonSeparatorAt(i));
        }
    }

    function walkSetAccessorChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.parameterList);
        walker.walk(preAst.block);
    }

    function walkObjectLiteralExpressionChildren(preAst, walker) {
        walker.walk(preAst.propertyAssignments);
    }

    function walkCastExpressionChildren(preAst, walker) {
        walker.walk(preAst.type);
        walker.walk(preAst.expression);
    }

    function walkParenthesizedExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkElementAccessExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
        walker.walk(preAst.argumentExpression);
    }

    function walkMemberAccessExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
        walker.walk(preAst.name);
    }

    function walkQualifiedNameChildren(preAst, walker) {
        walker.walk(preAst.left);
        walker.walk(preAst.right);
    }

    function walkBinaryExpressionChildren(preAst, walker) {
        walker.walk(preAst.left);
        walker.walk(preAst.right);
    }

    function walkEqualsValueClauseChildren(preAst, walker) {
        walker.walk(preAst.value);
    }

    function walkTypeParameterChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.constraint);
    }

    function walkTypeParameterListChildren(preAst, walker) {
        walker.walk(preAst.typeParameters);
    }

    function walkGenericTypeChildren(preAst, walker) {
        walker.walk(preAst.name);
        walker.walk(preAst.typeArgumentList);
    }

    function walkTypeAnnotationChildren(preAst, walker) {
        walker.walk(preAst.type);
    }

    function walkTypeQueryChildren(preAst, walker) {
        walker.walk(preAst.name);
    }

    function walkInvocationExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
        walker.walk(preAst.argumentList);
    }

    function walkObjectCreationExpressionChildren(preAst, walker) {
        walker.walk(preAst.expression);
        walker.walk(preAst.argumentList);
    }

    function walkTrinaryExpressionChildren(preAst, walker) {
        walker.walk(preAst.condition);
        walker.walk(preAst.whenTrue);
        walker.walk(preAst.whenFalse);
    }

    function walkFunctionExpressionChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.callSignature);
        walker.walk(preAst.block);
    }

    function walkFunctionTypeChildren(preAst, walker) {
        walker.walk(preAst.typeParameterList);
        walker.walk(preAst.parameterList);
        walker.walk(preAst.type);
    }

    function walkParenthesizedArrowFunctionExpressionChildren(preAst, walker) {
        walker.walk(preAst.callSignature);
        walker.walk(preAst.block);
        walker.walk(preAst.expression);
    }

    function walkSimpleArrowFunctionExpressionChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.block);
        walker.walk(preAst.expression);
    }

    function walkMemberFunctionDeclarationChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.callSignature);
        walker.walk(preAst.block);
    }

    function walkFuncDeclChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.callSignature);
        walker.walk(preAst.block);
    }

    function walkIndexMemberDeclarationChildren(preAst, walker) {
        walker.walk(preAst.indexSignature);
    }

    function walkIndexSignatureChildren(preAst, walker) {
        walker.walk(preAst.parameter);
        walker.walk(preAst.typeAnnotation);
    }

    function walkCallSignatureChildren(preAst, walker) {
        walker.walk(preAst.typeParameterList);
        walker.walk(preAst.parameterList);
        walker.walk(preAst.typeAnnotation);
    }

    function walkConstraintChildren(preAst, walker) {
        walker.walk(preAst.type);
    }

    function walkConstructorDeclarationChildren(preAst, walker) {
        walker.walk(preAst.callSignature);
        walker.walk(preAst.block);
    }

    function walkConstructorTypeChildren(preAst, walker) {
        walker.walk(preAst.typeParameterList);
        walker.walk(preAst.parameterList);
        walker.walk(preAst.type);
    }

    function walkConstructSignatureChildren(preAst, walker) {
        walker.walk(preAst.callSignature);
    }

    function walkParameterChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.typeAnnotation);
        walker.walk(preAst.equalsValueClause);
    }

    function walkParameterListChildren(preAst, walker) {
        walker.walk(preAst.parameters);
    }

    function walkPropertySignatureChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.typeAnnotation);
    }

    function walkVariableDeclaratorChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.typeAnnotation);
        walker.walk(preAst.equalsValueClause);
    }

    function walkMemberVariableDeclarationChildren(preAst, walker) {
        walker.walk(preAst.variableDeclarator);
    }

    function walkMethodSignatureChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.callSignature);
    }

    function walkReturnStatementChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkForStatementChildren(preAst, walker) {
        walker.walk(preAst.variableDeclaration);
        walker.walk(preAst.initializer);
        walker.walk(preAst.condition);
        walker.walk(preAst.incrementor);
        walker.walk(preAst.statement);
    }

    function walkForInStatementChildren(preAst, walker) {
        walker.walk(preAst.variableDeclaration);
        walker.walk(preAst.left);
        walker.walk(preAst.expression);
        walker.walk(preAst.statement);
    }

    function walkIfStatementChildren(preAst, walker) {
        walker.walk(preAst.condition);
        walker.walk(preAst.statement);
        walker.walk(preAst.elseClause);
    }

    function walkElseClauseChildren(preAst, walker) {
        walker.walk(preAst.statement);
    }

    function walkWhileStatementChildren(preAst, walker) {
        walker.walk(preAst.condition);
        walker.walk(preAst.statement);
    }

    function walkDoStatementChildren(preAst, walker) {
        walker.walk(preAst.condition);
        walker.walk(preAst.statement);
    }

    function walkBlockChildren(preAst, walker) {
        walker.walk(preAst.statements);
    }

    function walkVariableDeclarationChildren(preAst, walker) {
        walker.walk(preAst.declarators);
    }

    function walkCaseSwitchClauseChildren(preAst, walker) {
        walker.walk(preAst.expression);
        walker.walk(preAst.statements);
    }

    function walkDefaultSwitchClauseChildren(preAst, walker) {
        walker.walk(preAst.statements);
    }

    function walkSwitchStatementChildren(preAst, walker) {
        walker.walk(preAst.expression);
        walker.walk(preAst.switchClauses);
    }

    function walkTryStatementChildren(preAst, walker) {
        walker.walk(preAst.block);
        walker.walk(preAst.catchClause);
        walker.walk(preAst.finallyClause);
    }

    function walkCatchClauseChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.typeAnnotation);
        walker.walk(preAst.block);
    }

    function walkExternalModuleReferenceChildren(preAst, walker) {
        walker.walk(preAst.stringLiteral);
    }

    function walkFinallyClauseChildren(preAst, walker) {
        walker.walk(preAst.block);
    }

    function walkClassDeclChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.typeParameterList);
        walker.walk(preAst.heritageClauses);
        walker.walk(preAst.classElements);
    }

    function walkScriptChildren(preAst, walker) {
        walker.walk(preAst.moduleElements);
    }

    function walkHeritageClauseChildren(preAst, walker) {
        walker.walk(preAst.typeNames);
    }

    function walkInterfaceDeclerationChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.typeParameterList);
        walker.walk(preAst.heritageClauses);
        walker.walk(preAst.body);
    }

    function walkObjectTypeChildren(preAst, walker) {
        walker.walk(preAst.typeMembers);
    }

    function walkArrayTypeChildren(preAst, walker) {
        walker.walk(preAst.type);
    }

    function walkModuleDeclarationChildren(preAst, walker) {
        walker.walk(preAst.name);
        walker.walk(preAst.stringLiteral);
        walker.walk(preAst.moduleElements);
    }

    function walkModuleNameModuleReferenceChildren(preAst, walker) {
        walker.walk(preAst.moduleName);
    }

    function walkEnumDeclarationChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.enumElements);
    }

    function walkEnumElementChildren(preAst, walker) {
        walker.walk(preAst.propertyName);
        walker.walk(preAst.equalsValueClause);
    }

    function walkImportDeclarationChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.moduleReference);
    }

    function walkExportAssignmentChildren(preAst, walker) {
        walker.walk(preAst.identifier);
    }

    function walkWithStatementChildren(preAst, walker) {
        walker.walk(preAst.condition);
        walker.walk(preAst.statement);
    }

    function walkExpressionStatementChildren(preAst, walker) {
        walker.walk(preAst.expression);
    }

    function walkLabeledStatementChildren(preAst, walker) {
        walker.walk(preAst.identifier);
        walker.walk(preAst.statement);
    }

    function walkVariableStatementChildren(preAst, walker) {
        walker.walk(preAst.declaration);
    }

    var childrenWalkers = new Array(246 /* Last */ + 1);

    for (var i = 9 /* FirstToken */, n = 119 /* LastToken */; i <= n; i++) {
        childrenWalkers[i] = null;
    }
    for (var i = 4 /* FirstTrivia */, n = 8 /* LastTrivia */; i <= n; i++) {
        childrenWalkers[i] = null;
    }

    childrenWalkers[175 /* AddAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[208 /* AddExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[180 /* AndAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[60 /* AnyKeyword */] = null;
    childrenWalkers[226 /* ArgumentList */] = walkArgumentListChildren;
    childrenWalkers[214 /* ArrayLiteralExpression */] = walkArrayLiteralExpressionChildren;
    childrenWalkers[124 /* ArrayType */] = walkArrayTypeChildren;
    childrenWalkers[219 /* SimpleArrowFunctionExpression */] = walkSimpleArrowFunctionExpressionChildren;
    childrenWalkers[218 /* ParenthesizedArrowFunctionExpression */] = walkParenthesizedArrowFunctionExpressionChildren;
    childrenWalkers[174 /* AssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[191 /* BitwiseAndExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[190 /* BitwiseExclusiveOrExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[166 /* BitwiseNotExpression */] = walkPrefixUnaryExpressionChildren;
    childrenWalkers[189 /* BitwiseOrExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[146 /* Block */] = walkBlockChildren;
    childrenWalkers[61 /* BooleanKeyword */] = null;
    childrenWalkers[152 /* BreakStatement */] = null;
    childrenWalkers[142 /* CallSignature */] = walkCallSignatureChildren;
    childrenWalkers[233 /* CaseSwitchClause */] = walkCaseSwitchClauseChildren;
    childrenWalkers[220 /* CastExpression */] = walkCastExpressionChildren;
    childrenWalkers[236 /* CatchClause */] = walkCatchClauseChildren;
    childrenWalkers[131 /* ClassDeclaration */] = walkClassDeclChildren;
    childrenWalkers[173 /* CommaExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[186 /* ConditionalExpression */] = walkTrinaryExpressionChildren;
    childrenWalkers[239 /* Constraint */] = walkConstraintChildren;
    childrenWalkers[137 /* ConstructorDeclaration */] = walkConstructorDeclarationChildren;
    childrenWalkers[143 /* ConstructSignature */] = walkConstructSignatureChildren;
    childrenWalkers[153 /* ContinueStatement */] = null;
    childrenWalkers[125 /* ConstructorType */] = walkConstructorTypeChildren;
    childrenWalkers[162 /* DebuggerStatement */] = null;
    childrenWalkers[234 /* DefaultSwitchClause */] = walkDefaultSwitchClauseChildren;
    childrenWalkers[170 /* DeleteExpression */] = walkDeleteExpressionChildren;
    childrenWalkers[178 /* DivideAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[206 /* DivideExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[161 /* DoStatement */] = walkDoStatementChildren;
    childrenWalkers[221 /* ElementAccessExpression */] = walkElementAccessExpressionChildren;
    childrenWalkers[235 /* ElseClause */] = walkElseClauseChildren;
    childrenWalkers[156 /* EmptyStatement */] = null;
    childrenWalkers[132 /* EnumDeclaration */] = walkEnumDeclarationChildren;
    childrenWalkers[243 /* EnumElement */] = walkEnumElementChildren;
    childrenWalkers[194 /* EqualsExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[232 /* EqualsValueClause */] = walkEqualsValueClauseChildren;
    childrenWalkers[192 /* EqualsWithTypeConversionExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[181 /* ExclusiveOrAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[134 /* ExportAssignment */] = walkExportAssignmentChildren;
    childrenWalkers[149 /* ExpressionStatement */] = walkExpressionStatementChildren;
    childrenWalkers[230 /* ExtendsHeritageClause */] = walkHeritageClauseChildren;
    childrenWalkers[245 /* ExternalModuleReference */] = walkExternalModuleReferenceChildren;
    childrenWalkers[24 /* FalseKeyword */] = null;
    childrenWalkers[237 /* FinallyClause */] = walkFinallyClauseChildren;
    childrenWalkers[155 /* ForInStatement */] = walkForInStatementChildren;
    childrenWalkers[154 /* ForStatement */] = walkForStatementChildren;
    childrenWalkers[129 /* FunctionDeclaration */] = walkFuncDeclChildren;
    childrenWalkers[222 /* FunctionExpression */] = walkFunctionExpressionChildren;
    childrenWalkers[241 /* FunctionPropertyAssignment */] = walkFunctionPropertyAssignmentChildren;
    childrenWalkers[123 /* FunctionType */] = walkFunctionTypeChildren;
    childrenWalkers[126 /* GenericType */] = walkGenericTypeChildren;
    childrenWalkers[139 /* GetAccessor */] = walkGetAccessorChildren;
    childrenWalkers[197 /* GreaterThanExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[199 /* GreaterThanOrEqualExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[147 /* IfStatement */] = walkIfStatementChildren;
    childrenWalkers[231 /* ImplementsHeritageClause */] = walkHeritageClauseChildren;
    childrenWalkers[133 /* ImportDeclaration */] = walkImportDeclarationChildren;
    childrenWalkers[138 /* IndexMemberDeclaration */] = walkIndexMemberDeclarationChildren;
    childrenWalkers[144 /* IndexSignature */] = walkIndexSignatureChildren;
    childrenWalkers[201 /* InExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[200 /* InstanceOfExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[128 /* InterfaceDeclaration */] = walkInterfaceDeclerationChildren;
    childrenWalkers[213 /* InvocationExpression */] = walkInvocationExpressionChildren;
    childrenWalkers[160 /* LabeledStatement */] = walkLabeledStatementChildren;
    childrenWalkers[183 /* LeftShiftAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[202 /* LeftShiftExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[196 /* LessThanExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[198 /* LessThanOrEqualExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[1 /* List */] = walkListChildren;
    childrenWalkers[188 /* LogicalAndExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[167 /* LogicalNotExpression */] = walkPrefixUnaryExpressionChildren;
    childrenWalkers[187 /* LogicalOrExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[212 /* MemberAccessExpression */] = walkMemberAccessExpressionChildren;
    childrenWalkers[135 /* MemberFunctionDeclaration */] = walkMemberFunctionDeclarationChildren;
    childrenWalkers[136 /* MemberVariableDeclaration */] = walkMemberVariableDeclarationChildren;
    childrenWalkers[145 /* MethodSignature */] = walkMethodSignatureChildren;
    childrenWalkers[130 /* ModuleDeclaration */] = walkModuleDeclarationChildren;
    childrenWalkers[246 /* ModuleNameModuleReference */] = walkModuleNameModuleReferenceChildren;
    childrenWalkers[179 /* ModuloAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[207 /* ModuloExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[177 /* MultiplyAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[205 /* MultiplyExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[11 /* IdentifierName */] = null;
    childrenWalkers[165 /* NegateExpression */] = walkPrefixUnaryExpressionChildren;
    childrenWalkers[0 /* None */] = null;
    childrenWalkers[195 /* NotEqualsExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[193 /* NotEqualsWithTypeConversionExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[32 /* NullKeyword */] = null;
    childrenWalkers[67 /* NumberKeyword */] = null;
    childrenWalkers[13 /* NumericLiteral */] = null;
    childrenWalkers[216 /* ObjectCreationExpression */] = walkObjectCreationExpressionChildren;
    childrenWalkers[215 /* ObjectLiteralExpression */] = walkObjectLiteralExpressionChildren;
    childrenWalkers[122 /* ObjectType */] = walkObjectTypeChildren;
    childrenWalkers[223 /* OmittedExpression */] = null;
    childrenWalkers[182 /* OrAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[242 /* Parameter */] = walkParameterChildren;
    childrenWalkers[227 /* ParameterList */] = walkParameterListChildren;
    childrenWalkers[217 /* ParenthesizedExpression */] = walkParenthesizedExpressionChildren;
    childrenWalkers[164 /* PlusExpression */] = walkPrefixUnaryExpressionChildren;
    childrenWalkers[211 /* PostDecrementExpression */] = walkPostfixUnaryExpressionChildren;
    childrenWalkers[210 /* PostIncrementExpression */] = walkPostfixUnaryExpressionChildren;
    childrenWalkers[169 /* PreDecrementExpression */] = walkPrefixUnaryExpressionChildren;
    childrenWalkers[168 /* PreIncrementExpression */] = walkPrefixUnaryExpressionChildren;
    childrenWalkers[141 /* PropertySignature */] = walkPropertySignatureChildren;
    childrenWalkers[121 /* QualifiedName */] = walkQualifiedNameChildren;
    childrenWalkers[12 /* RegularExpressionLiteral */] = null;
    childrenWalkers[150 /* ReturnStatement */] = walkReturnStatementChildren;
    childrenWalkers[120 /* SourceUnit */] = walkScriptChildren;
    childrenWalkers[2 /* SeparatedList */] = walkSeparatedListChildren;
    childrenWalkers[140 /* SetAccessor */] = walkSetAccessorChildren;
    childrenWalkers[184 /* SignedRightShiftAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[203 /* SignedRightShiftExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[240 /* SimplePropertyAssignment */] = walkSimplePropertyAssignmentChildren;
    childrenWalkers[14 /* StringLiteral */] = null;
    childrenWalkers[69 /* StringKeyword */] = null;
    childrenWalkers[176 /* SubtractAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[209 /* SubtractExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[50 /* SuperKeyword */] = null;
    childrenWalkers[151 /* SwitchStatement */] = walkSwitchStatementChildren;
    childrenWalkers[35 /* ThisKeyword */] = null;
    childrenWalkers[157 /* ThrowStatement */] = walkThrowStatementChildren;
    childrenWalkers[3 /* TriviaList */] = null;
    childrenWalkers[37 /* TrueKeyword */] = null;
    childrenWalkers[159 /* TryStatement */] = walkTryStatementChildren;
    childrenWalkers[244 /* TypeAnnotation */] = walkTypeAnnotationChildren;
    childrenWalkers[228 /* TypeArgumentList */] = walkTypeArgumentListChildren;
    childrenWalkers[171 /* TypeOfExpression */] = walkTypeOfExpressionChildren;
    childrenWalkers[238 /* TypeParameter */] = walkTypeParameterChildren;
    childrenWalkers[229 /* TypeParameterList */] = walkTypeParameterListChildren;
    childrenWalkers[127 /* TypeQuery */] = walkTypeQueryChildren;
    childrenWalkers[185 /* UnsignedRightShiftAssignmentExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[204 /* UnsignedRightShiftExpression */] = walkBinaryExpressionChildren;
    childrenWalkers[224 /* VariableDeclaration */] = walkVariableDeclarationChildren;
    childrenWalkers[225 /* VariableDeclarator */] = walkVariableDeclaratorChildren;
    childrenWalkers[148 /* VariableStatement */] = walkVariableStatementChildren;
    childrenWalkers[172 /* VoidExpression */] = walkVoidExpressionChildren;
    childrenWalkers[41 /* VoidKeyword */] = null;
    childrenWalkers[158 /* WhileStatement */] = walkWhileStatementChildren;
    childrenWalkers[163 /* WithStatement */] = walkWithStatementChildren;

    for (var e in TypeScript.SyntaxKind) {
        if (TypeScript.SyntaxKind.hasOwnProperty(e) && TypeScript.StringUtilities.isString(TypeScript.SyntaxKind[e])) {
            TypeScript.Debug.assert(childrenWalkers[e] !== undefined, "Fix initWalkers: " + TypeScript.SyntaxKind[e]);
        }
    }

    var AstWalkOptions = (function () {
        function AstWalkOptions() {
            this.goChildren = true;
            this.stopWalking = false;
        }
        return AstWalkOptions;
    })();
    TypeScript.AstWalkOptions = AstWalkOptions;

    var SimplePreAstWalker = (function () {
        function SimplePreAstWalker(pre, state) {
            this.pre = pre;
            this.state = state;
            this.options = new AstWalkOptions();
        }
        SimplePreAstWalker.prototype.walk = function (ast) {
            if (!ast) {
                return;
            }

            this.pre(ast, this.state);

            var walker = childrenWalkers[ast.kind()];
            if (walker) {
                walker(ast, this);
            }
        };
        return SimplePreAstWalker;
    })();

    var SimplePrePostAstWalker = (function () {
        function SimplePrePostAstWalker(pre, post, state) {
            this.pre = pre;
            this.post = post;
            this.state = state;
            this.options = new AstWalkOptions();
        }
        SimplePrePostAstWalker.prototype.walk = function (ast) {
            if (!ast) {
                return;
            }

            this.pre(ast, this.state);

            var walker = childrenWalkers[ast.kind()];
            if (walker) {
                walker(ast, this);
            }

            this.post(ast, this.state);
        };
        return SimplePrePostAstWalker;
    })();

    var NormalAstWalker = (function () {
        function NormalAstWalker(pre, post, state) {
            this.pre = pre;
            this.post = post;
            this.state = state;
            this.options = new AstWalkOptions();
        }
        NormalAstWalker.prototype.walk = function (ast) {
            if (!ast) {
                return;
            }

            if (this.options.stopWalking) {
                return;
            }

            this.pre(ast, this);

            if (this.options.stopWalking) {
                return;
            }

            if (this.options.goChildren) {
                var walker = childrenWalkers[ast.kind()];
                if (walker) {
                    walker(ast, this);
                }
            } else {
                this.options.goChildren = true;
            }

            if (this.post) {
                this.post(ast, this);
            }
        };
        return NormalAstWalker;
    })();

    var AstWalkerFactory = (function () {
        function AstWalkerFactory() {
        }
        AstWalkerFactory.prototype.walk = function (ast, pre, post, state) {
            new NormalAstWalker(pre, post, state).walk(ast);
        };

        AstWalkerFactory.prototype.simpleWalk = function (ast, pre, post, state) {
            if (post) {
                new SimplePrePostAstWalker(pre, post, state).walk(ast);
            } else {
                new SimplePreAstWalker(pre, state).walk(ast);
            }
        };
        return AstWalkerFactory;
    })();
    TypeScript.AstWalkerFactory = AstWalkerFactory;

    var globalAstWalkerFactory = new AstWalkerFactory();

    function getAstWalkerFactory() {
        return globalAstWalkerFactory;
    }
    TypeScript.getAstWalkerFactory = getAstWalkerFactory;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var Base64Format = (function () {
        function Base64Format() {
        }
        Base64Format.encode = function (inValue) {
            if (inValue < 64) {
                return Base64Format.encodedValues.charAt(inValue);
            }
            throw TypeError(inValue + ": not a 64 based value");
        };

        Base64Format.decodeChar = function (inChar) {
            if (inChar.length === 1) {
                return Base64Format.encodedValues.indexOf(inChar);
            } else {
                throw TypeError('"' + inChar + '" must have length 1');
            }
        };
        Base64Format.encodedValues = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
        return Base64Format;
    })();

    var Base64VLQFormat = (function () {
        function Base64VLQFormat() {
        }
        Base64VLQFormat.encode = function (inValue) {
            if (inValue < 0) {
                inValue = ((-inValue) << 1) + 1;
            } else {
                inValue = inValue << 1;
            }

            var encodedStr = "";
            do {
                var currentDigit = inValue & 31;
                inValue = inValue >> 5;
                if (inValue > 0) {
                    currentDigit = currentDigit | 32;
                }
                encodedStr = encodedStr + Base64Format.encode(currentDigit);
            } while(inValue > 0);

            return encodedStr;
        };

        Base64VLQFormat.decode = function (inString) {
            var result = 0;
            var negative = false;

            var shift = 0;
            for (var i = 0; i < inString.length; i++) {
                var byte = Base64Format.decodeChar(inString[i]);
                if (i === 0) {
                    if ((byte & 1) === 1) {
                        negative = true;
                    }
                    result = (byte >> 1) & 15;
                } else {
                    result = result | ((byte & 31) << shift);
                }

                shift += (i === 0) ? 4 : 5;

                if ((byte & 32) === 32) {
                } else {
                    return { value: negative ? -(result) : result, rest: inString.substr(i + 1) };
                }
            }

            throw new Error(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Base64_value_0_finished_with_a_continuation_bit, [inString]));
        };
        return Base64VLQFormat;
    })();
    TypeScript.Base64VLQFormat = Base64VLQFormat;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SourceMapPosition = (function () {
        function SourceMapPosition() {
        }
        return SourceMapPosition;
    })();
    TypeScript.SourceMapPosition = SourceMapPosition;

    var SourceMapping = (function () {
        function SourceMapping() {
            this.start = new SourceMapPosition();
            this.end = new SourceMapPosition();
            this.nameIndex = -1;
            this.childMappings = [];
        }
        return SourceMapping;
    })();
    TypeScript.SourceMapping = SourceMapping;

    var SourceMapEntry = (function () {
        function SourceMapEntry(emittedFile, emittedLine, emittedColumn, sourceFile, sourceLine, sourceColumn, sourceName) {
            this.emittedFile = emittedFile;
            this.emittedLine = emittedLine;
            this.emittedColumn = emittedColumn;
            this.sourceFile = sourceFile;
            this.sourceLine = sourceLine;
            this.sourceColumn = sourceColumn;
            this.sourceName = sourceName;
            TypeScript.Debug.assert(isFinite(emittedLine));
            TypeScript.Debug.assert(isFinite(emittedColumn));
            TypeScript.Debug.assert(isFinite(sourceColumn));
            TypeScript.Debug.assert(isFinite(sourceLine));
        }
        return SourceMapEntry;
    })();
    TypeScript.SourceMapEntry = SourceMapEntry;

    var SourceMapper = (function () {
        function SourceMapper(jsFile, sourceMapOut, document, jsFilePath, emitOptions, resolvePath) {
            this.jsFile = jsFile;
            this.sourceMapOut = sourceMapOut;
            this.names = [];
            this.mappingLevel = [];
            this.tsFilePaths = [];
            this.allSourceMappings = [];
            this.sourceMapEntries = [];
            this.setSourceMapOptions(document, jsFilePath, emitOptions, resolvePath);
            this.setNewSourceFile(document, emitOptions);
        }
        SourceMapper.prototype.getOutputFile = function () {
            var result = this.sourceMapOut.getOutputFile();
            result.sourceMapEntries = this.sourceMapEntries;

            return result;
        };

        SourceMapper.prototype.increaseMappingLevel = function (ast) {
            this.mappingLevel.push(ast);
        };

        SourceMapper.prototype.decreaseMappingLevel = function (ast) {
            TypeScript.Debug.assert(this.mappingLevel.length > 0, "Mapping level should never be less than 0. This suggests a missing start call.");
            var expectedAst = this.mappingLevel.pop();
            var expectedAstInfo = expectedAst.kind ? TypeScript.SyntaxKind[expectedAst.kind()] : [expectedAst.start(), expectedAst.end()];
            var astInfo = ast.kind ? TypeScript.SyntaxKind[ast.kind()] : [ast.start(), ast.end()];
            TypeScript.Debug.assert(ast === expectedAst, "Provided ast is not the expected AST, Expected: " + expectedAstInfo + " Given: " + astInfo);
        };

        SourceMapper.prototype.setNewSourceFile = function (document, emitOptions) {
            var sourceMappings = [];
            this.allSourceMappings.push(sourceMappings);
            this.currentMappings = [sourceMappings];
            this.currentNameIndex = [];

            this.setNewSourceFilePath(document, emitOptions);
        };

        SourceMapper.prototype.setSourceMapOptions = function (document, jsFilePath, emitOptions, resolvePath) {
            var prettyJsFileName = TypeScript.getPrettyName(jsFilePath, false, true);
            var prettyMapFileName = prettyJsFileName + SourceMapper.MapFileExtension;
            this.jsFileName = prettyJsFileName;

            if (emitOptions.sourceMapRootDirectory()) {
                this.sourceMapDirectory = emitOptions.sourceMapRootDirectory();
                if (document.emitToOwnOutputFile()) {
                    this.sourceMapDirectory = this.sourceMapDirectory + TypeScript.switchToForwardSlashes(TypeScript.getRootFilePath((document.fileName)).replace(emitOptions.commonDirectoryPath(), ""));
                }

                if (TypeScript.isRelative(this.sourceMapDirectory)) {
                    this.sourceMapDirectory = emitOptions.commonDirectoryPath() + this.sourceMapDirectory;
                    this.sourceMapDirectory = TypeScript.convertToDirectoryPath(TypeScript.switchToForwardSlashes(resolvePath(this.sourceMapDirectory)));
                    this.sourceMapPath = TypeScript.getRelativePathToFixedPath(TypeScript.getRootFilePath(jsFilePath), this.sourceMapDirectory + prettyMapFileName);
                } else {
                    this.sourceMapPath = this.sourceMapDirectory + prettyMapFileName;
                }
            } else {
                this.sourceMapPath = prettyMapFileName;
                this.sourceMapDirectory = TypeScript.getRootFilePath(jsFilePath);
            }
            this.sourceRoot = emitOptions.sourceRootDirectory();
        };

        SourceMapper.prototype.setNewSourceFilePath = function (document, emitOptions) {
            var tsFilePath = TypeScript.switchToForwardSlashes(document.fileName);
            if (emitOptions.sourceRootDirectory()) {
                tsFilePath = TypeScript.getRelativePathToFixedPath(emitOptions.commonDirectoryPath(), tsFilePath);
            } else {
                tsFilePath = TypeScript.getRelativePathToFixedPath(this.sourceMapDirectory, tsFilePath);
            }
            this.tsFilePaths.push(tsFilePath);
        };

        SourceMapper.prototype.emitSourceMapping = function () {
            var _this = this;
            TypeScript.Debug.assert(this.mappingLevel.length === 0, "Mapping level is not 0. This suggest a missing end call. Value: " + this.mappingLevel.map(function (item) {
                return ['Node of type', TypeScript.SyntaxKind[item.kind()], 'at', item.start(), 'to', item.end()].join(' ');
            }).join(', '));

            this.jsFile.WriteLine("//# sourceMappingURL=" + this.sourceMapPath);

            var mappingsString = "";

            var prevEmittedColumn = 0;
            var prevEmittedLine = 0;
            var prevSourceColumn = 0;
            var prevSourceLine = 0;
            var prevSourceIndex = 0;
            var prevNameIndex = 0;
            var emitComma = false;

            var recordedPosition = null;
            for (var sourceIndex = 0; sourceIndex < this.tsFilePaths.length; sourceIndex++) {
                var recordSourceMapping = function (mappedPosition, nameIndex) {
                    if (recordedPosition !== null && recordedPosition.emittedColumn === mappedPosition.emittedColumn && recordedPosition.emittedLine === mappedPosition.emittedLine) {
                        return;
                    }

                    if (prevEmittedLine !== mappedPosition.emittedLine) {
                        while (prevEmittedLine < mappedPosition.emittedLine) {
                            prevEmittedColumn = 0;
                            mappingsString = mappingsString + ";";
                            prevEmittedLine++;
                        }
                        emitComma = false;
                    } else if (emitComma) {
                        mappingsString = mappingsString + ",";
                    }

                    _this.sourceMapEntries.push(new SourceMapEntry(_this.jsFileName, mappedPosition.emittedLine + 1, mappedPosition.emittedColumn + 1, _this.tsFilePaths[sourceIndex], mappedPosition.sourceLine, mappedPosition.sourceColumn + 1, nameIndex >= 0 ? _this.names[nameIndex] : undefined));

                    mappingsString = mappingsString + TypeScript.Base64VLQFormat.encode(mappedPosition.emittedColumn - prevEmittedColumn);
                    prevEmittedColumn = mappedPosition.emittedColumn;

                    mappingsString = mappingsString + TypeScript.Base64VLQFormat.encode(sourceIndex - prevSourceIndex);
                    prevSourceIndex = sourceIndex;

                    mappingsString = mappingsString + TypeScript.Base64VLQFormat.encode(mappedPosition.sourceLine - 1 - prevSourceLine);
                    prevSourceLine = mappedPosition.sourceLine - 1;

                    mappingsString = mappingsString + TypeScript.Base64VLQFormat.encode(mappedPosition.sourceColumn - prevSourceColumn);
                    prevSourceColumn = mappedPosition.sourceColumn;

                    if (nameIndex >= 0) {
                        mappingsString = mappingsString + TypeScript.Base64VLQFormat.encode(nameIndex - prevNameIndex);
                        prevNameIndex = nameIndex;
                    }

                    emitComma = true;
                    recordedPosition = mappedPosition;
                };

                var recordSourceMappingSiblings = function (sourceMappings) {
                    for (var i = 0; i < sourceMappings.length; i++) {
                        var sourceMapping = sourceMappings[i];
                        recordSourceMapping(sourceMapping.start, sourceMapping.nameIndex);
                        recordSourceMappingSiblings(sourceMapping.childMappings);
                        recordSourceMapping(sourceMapping.end, sourceMapping.nameIndex);
                    }
                };

                recordSourceMappingSiblings(this.allSourceMappings[sourceIndex]);
            }

            this.sourceMapOut.Write(JSON.stringify({
                version: 3,
                file: this.jsFileName,
                sourceRoot: this.sourceRoot,
                sources: this.tsFilePaths,
                names: this.names,
                mappings: mappingsString
            }));

            this.sourceMapOut.Close();
        };
        SourceMapper.MapFileExtension = ".map";
        return SourceMapper;
    })();
    TypeScript.SourceMapper = SourceMapper;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (EmitContainer) {
        EmitContainer[EmitContainer["Prog"] = 0] = "Prog";
        EmitContainer[EmitContainer["Module"] = 1] = "Module";
        EmitContainer[EmitContainer["DynamicModule"] = 2] = "DynamicModule";
        EmitContainer[EmitContainer["Class"] = 3] = "Class";
        EmitContainer[EmitContainer["Constructor"] = 4] = "Constructor";
        EmitContainer[EmitContainer["Function"] = 5] = "Function";
        EmitContainer[EmitContainer["Args"] = 6] = "Args";
        EmitContainer[EmitContainer["Interface"] = 7] = "Interface";
    })(TypeScript.EmitContainer || (TypeScript.EmitContainer = {}));
    var EmitContainer = TypeScript.EmitContainer;

    var EmitState = (function () {
        function EmitState() {
            this.column = 0;
            this.line = 0;
            this.container = 0 /* Prog */;
        }
        return EmitState;
    })();
    TypeScript.EmitState = EmitState;

    var EmitOptions = (function () {
        function EmitOptions(compiler, resolvePath) {
            this.resolvePath = resolvePath;
            this._diagnostic = null;
            this._settings = null;
            this._commonDirectoryPath = "";
            this._sharedOutputFile = "";
            this._sourceRootDirectory = "";
            this._sourceMapRootDirectory = "";
            this._outputDirectory = "";
            var settings = compiler.compilationSettings();
            this._settings = settings;

            if (settings.moduleGenTarget() === 0 /* Unspecified */) {
                var fileNames = compiler.fileNames();
                for (var i = 0, n = fileNames.length; i < n; i++) {
                    var document = compiler.getDocument(fileNames[i]);
                    if (!document.isDeclareFile() && document.isExternalModule()) {
                        var errorSpan = document.externalModuleIndicatorSpan();
                        this._diagnostic = new TypeScript.Diagnostic(document.fileName, document.lineMap(), errorSpan.start(), errorSpan.length(), TypeScript.DiagnosticCode.Cannot_compile_external_modules_unless_the_module_flag_is_provided);

                        return;
                    }
                }
            }

            if (!settings.mapSourceFiles()) {
                if (settings.mapRoot()) {
                    if (settings.sourceRoot()) {
                        this._diagnostic = new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Options_mapRoot_and_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option, null);
                        return;
                    } else {
                        this._diagnostic = new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option, null);
                        return;
                    }
                } else if (settings.sourceRoot()) {
                    this._diagnostic = new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option, null);
                    return;
                }
            }

            this._sourceMapRootDirectory = TypeScript.convertToDirectoryPath(TypeScript.switchToForwardSlashes(settings.mapRoot()));
            this._sourceRootDirectory = TypeScript.convertToDirectoryPath(TypeScript.switchToForwardSlashes(settings.sourceRoot()));

            if (settings.outFileOption() || settings.outDirOption() || settings.mapRoot() || settings.sourceRoot()) {
                if (settings.outFileOption()) {
                    this._sharedOutputFile = TypeScript.switchToForwardSlashes(resolvePath(settings.outFileOption()));
                }

                if (settings.outDirOption()) {
                    this._outputDirectory = TypeScript.convertToDirectoryPath(TypeScript.switchToForwardSlashes(resolvePath(settings.outDirOption())));
                }

                if (this._outputDirectory || this._sourceMapRootDirectory || this.sourceRootDirectory) {
                    this.determineCommonDirectoryPath(compiler);
                }
            }
        }
        EmitOptions.prototype.diagnostic = function () {
            return this._diagnostic;
        };

        EmitOptions.prototype.commonDirectoryPath = function () {
            return this._commonDirectoryPath;
        };
        EmitOptions.prototype.sharedOutputFile = function () {
            return this._sharedOutputFile;
        };
        EmitOptions.prototype.sourceRootDirectory = function () {
            return this._sourceRootDirectory;
        };
        EmitOptions.prototype.sourceMapRootDirectory = function () {
            return this._sourceMapRootDirectory;
        };
        EmitOptions.prototype.outputDirectory = function () {
            return this._outputDirectory;
        };

        EmitOptions.prototype.compilationSettings = function () {
            return this._settings;
        };

        EmitOptions.prototype.determineCommonDirectoryPath = function (compiler) {
            var commonComponents = [];
            var commonComponentsLength = -1;

            var fileNames = compiler.fileNames();
            for (var i = 0, len = fileNames.length; i < len; i++) {
                var fileName = fileNames[i];
                var document = compiler.getDocument(fileNames[i]);
                var sourceUnit = document.sourceUnit();

                if (!document.isDeclareFile()) {
                    var fileComponents = TypeScript.filePathComponents(fileName);
                    if (commonComponentsLength === -1) {
                        commonComponents = fileComponents;
                        commonComponentsLength = commonComponents.length;
                    } else {
                        var updatedPath = false;
                        for (var j = 0; j < commonComponentsLength && j < fileComponents.length; j++) {
                            if (commonComponents[j] !== fileComponents[j]) {
                                commonComponentsLength = j;
                                updatedPath = true;

                                if (j === 0) {
                                    var isDynamicModuleCompilation = TypeScript.ArrayUtilities.any(fileNames, function (fileName) {
                                        document = compiler.getDocument(fileName);
                                        return !document.isDeclareFile() && document.isExternalModule();
                                    });

                                    if (this._outputDirectory || this._sourceRootDirectory || (this._sourceMapRootDirectory && (!this._sharedOutputFile || isDynamicModuleCompilation))) {
                                        this._diagnostic = new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Cannot_find_the_common_subdirectory_path_for_the_input_files, null);
                                        return;
                                    }

                                    return;
                                }

                                break;
                            }
                        }

                        if (!updatedPath && fileComponents.length < commonComponentsLength) {
                            commonComponentsLength = fileComponents.length;
                        }
                    }
                }
            }

            this._commonDirectoryPath = commonComponents.slice(0, commonComponentsLength).join("/") + "/";
        };
        return EmitOptions;
    })();
    TypeScript.EmitOptions = EmitOptions;

    var Indenter = (function () {
        function Indenter() {
            this.indentAmt = 0;
        }
        Indenter.prototype.increaseIndent = function () {
            this.indentAmt += Indenter.indentStep;
        };

        Indenter.prototype.decreaseIndent = function () {
            this.indentAmt -= Indenter.indentStep;
        };

        Indenter.prototype.getIndent = function () {
            var indentString = Indenter.indentStrings[this.indentAmt];
            if (indentString === undefined) {
                indentString = "";
                for (var i = 0; i < this.indentAmt; i = i + Indenter.indentStep) {
                    indentString += Indenter.indentStepString;
                }
                Indenter.indentStrings[this.indentAmt] = indentString;
            }
            return indentString;
        };
        Indenter.indentStep = 4;
        Indenter.indentStepString = "    ";
        Indenter.indentStrings = [];
        return Indenter;
    })();
    TypeScript.Indenter = Indenter;

    function lastParameterIsRest(parameterList) {
        var parameters = parameterList.parameters;
        return parameters.nonSeparatorCount() > 0 && parameters.nonSeparatorAt(parameters.nonSeparatorCount() - 1).dotDotDotToken !== null;
    }
    TypeScript.lastParameterIsRest = lastParameterIsRest;

    var Emitter = (function () {
        function Emitter(emittingFileName, outfile, emitOptions, semanticInfoChain) {
            this.emittingFileName = emittingFileName;
            this.outfile = outfile;
            this.emitOptions = emitOptions;
            this.semanticInfoChain = semanticInfoChain;
            this.globalThisCapturePrologueEmitted = false;
            this.extendsPrologueEmitted = false;
            this.thisClassNode = null;
            this.inArrowFunction = false;
            this.moduleName = "";
            this.emitState = new EmitState();
            this.indenter = new Indenter();
            this.sourceMapper = null;
            this.captureThisStmtString = "var _this = this;";
            this.declStack = [];
            this.exportAssignment = null;
            this.inWithBlock = false;
            this.document = null;
            this.detachedCommentsElement = null;
        }
        Emitter.prototype.pushDecl = function (decl) {
            if (decl) {
                this.declStack[this.declStack.length] = decl;
            }
        };

        Emitter.prototype.popDecl = function (decl) {
            if (decl) {
                this.declStack.length--;
            }
        };

        Emitter.prototype.getEnclosingDecl = function () {
            var declStackLen = this.declStack.length;
            var enclosingDecl = declStackLen > 0 ? this.declStack[declStackLen - 1] : null;
            return enclosingDecl;
        };

        Emitter.prototype.setExportAssignment = function (exportAssignment) {
            this.exportAssignment = exportAssignment;
        };

        Emitter.prototype.getExportAssignment = function () {
            return this.exportAssignment;
        };

        Emitter.prototype.setDocument = function (document) {
            this.document = document;
        };

        Emitter.prototype.shouldEmitImportDeclaration = function (importDeclAST) {
            var isExternalModuleReference = importDeclAST.moduleReference.kind() === 245 /* ExternalModuleReference */;
            var importDecl = this.semanticInfoChain.getDeclForAST(importDeclAST);
            var isExported = TypeScript.hasFlag(importDecl.flags, 1 /* Exported */);
            var isAmdCodeGen = this.emitOptions.compilationSettings().moduleGenTarget() === 2 /* Asynchronous */;

            if (isExternalModuleReference && !isExported && isAmdCodeGen) {
                return false;
            }

            var importSymbol = importDecl.getSymbol();
            if (importSymbol.isUsedAsValue()) {
                return true;
            }

            if (importDeclAST.moduleReference.kind() !== 245 /* ExternalModuleReference */) {
                var canBeUsedExternally = isExported || importSymbol.typeUsedExternally() || importSymbol.isUsedInExportedAlias();
                if (!canBeUsedExternally && !this.document.isExternalModule()) {
                    canBeUsedExternally = TypeScript.hasFlag(importDecl.getParentDecl().kind, 1 /* Script */ | 32 /* DynamicModule */);
                }

                if (canBeUsedExternally) {
                    if (importSymbol.getExportAssignedValueSymbol()) {
                        return true;
                    }

                    var containerSymbol = importSymbol.getExportAssignedContainerSymbol();
                    if (containerSymbol && containerSymbol.getInstanceSymbol()) {
                        return true;
                    }
                }
            }

            return false;
        };

        Emitter.prototype.emitImportDeclaration = function (importDeclAST) {
            var isExternalModuleReference = importDeclAST.moduleReference.kind() === 245 /* ExternalModuleReference */;
            var importDecl = this.semanticInfoChain.getDeclForAST(importDeclAST);
            var isExported = TypeScript.hasFlag(importDecl.flags, 1 /* Exported */);
            var isAmdCodeGen = this.emitOptions.compilationSettings().moduleGenTarget() === 2 /* Asynchronous */;

            this.emitComments(importDeclAST, true);

            var importSymbol = importDecl.getSymbol();

            var parentSymbol = importSymbol.getContainer();
            var parentKind = parentSymbol ? parentSymbol.kind : 0 /* None */;
            var associatedParentSymbol = parentSymbol ? parentSymbol.getAssociatedContainerType() : null;
            var associatedParentSymbolKind = associatedParentSymbol ? associatedParentSymbol.kind : 0 /* None */;

            var needsPropertyAssignment = false;
            var usePropertyAssignmentInsteadOfVarDecl = false;
            var moduleNamePrefix;

            if (isExported && (parentKind === 4 /* Container */ || parentKind === 32 /* DynamicModule */ || associatedParentSymbolKind === 4 /* Container */ || associatedParentSymbolKind === 32 /* DynamicModule */)) {
                if (importSymbol.getExportAssignedTypeSymbol() || importSymbol.getExportAssignedContainerSymbol()) {
                    needsPropertyAssignment = true;
                } else {
                    var valueSymbol = importSymbol.getExportAssignedValueSymbol();
                    if (valueSymbol && (valueSymbol.kind === 65536 /* Method */ || valueSymbol.kind === 16384 /* Function */)) {
                        needsPropertyAssignment = true;
                    } else {
                        usePropertyAssignmentInsteadOfVarDecl = true;
                    }
                }

                if (this.emitState.container === 2 /* DynamicModule */) {
                    moduleNamePrefix = "exports.";
                } else {
                    moduleNamePrefix = this.moduleName + ".";
                }
            }

            if (isAmdCodeGen && isExternalModuleReference) {
                needsPropertyAssignment = true;
            } else {
                this.recordSourceMappingStart(importDeclAST);
                if (usePropertyAssignmentInsteadOfVarDecl) {
                    this.writeToOutput(moduleNamePrefix);
                } else {
                    this.writeToOutput("var ");
                }
                this.writeToOutput(importDeclAST.identifier.text() + " = ");
                var aliasAST = importDeclAST.moduleReference;

                if (isExternalModuleReference) {
                    this.writeToOutput("require(" + aliasAST.stringLiteral.text() + ")");
                } else {
                    this.emitJavascript(aliasAST.moduleName, false);
                }

                this.recordSourceMappingEnd(importDeclAST);
                this.writeToOutput(";");

                if (needsPropertyAssignment) {
                    this.writeLineToOutput("");
                    this.emitIndent();
                }
            }

            if (needsPropertyAssignment) {
                this.writeToOutputWithSourceMapRecord(moduleNamePrefix + importDeclAST.identifier.text() + " = " + importDeclAST.identifier.text(), importDeclAST);
                this.writeToOutput(";");
            }
            this.emitComments(importDeclAST, false);
        };

        Emitter.prototype.createSourceMapper = function (document, jsFileName, jsFile, sourceMapOut, resolvePath) {
            this.sourceMapper = new TypeScript.SourceMapper(jsFile, sourceMapOut, document, jsFileName, this.emitOptions, resolvePath);
        };

        Emitter.prototype.setSourceMapperNewSourceFile = function (document) {
            this.sourceMapper.setNewSourceFile(document, this.emitOptions);
        };

        Emitter.prototype.updateLineAndColumn = function (s) {
            var lineNumbers = TypeScript.TextUtilities.parseLineStarts(s);
            if (lineNumbers.length > 1) {
                this.emitState.line += lineNumbers.length - 1;
                this.emitState.column = s.length - lineNumbers[lineNumbers.length - 1];
            } else {
                this.emitState.column += s.length;
            }
        };

        Emitter.prototype.writeToOutputWithSourceMapRecord = function (s, astSpan) {
            this.recordSourceMappingStart(astSpan);
            this.writeToOutput(s);
            this.recordSourceMappingEnd(astSpan);
        };

        Emitter.prototype.writeToOutput = function (s) {
            this.outfile.Write(s);
            this.updateLineAndColumn(s);
        };

        Emitter.prototype.writeLineToOutput = function (s, force) {
            if (typeof force === "undefined") { force = false; }
            if (!force && s === "" && this.emitState.column === 0) {
                return;
            }

            this.outfile.WriteLine(s);
            this.updateLineAndColumn(s);
            this.emitState.column = 0;
            this.emitState.line++;
        };

        Emitter.prototype.writeCaptureThisStatement = function (ast) {
            this.emitIndent();
            this.writeToOutputWithSourceMapRecord(this.captureThisStmtString, ast);
            this.writeLineToOutput("");
        };

        Emitter.prototype.setContainer = function (c) {
            var temp = this.emitState.container;
            this.emitState.container = c;
            return temp;
        };

        Emitter.prototype.getIndentString = function () {
            return this.indenter.getIndent();
        };

        Emitter.prototype.emitIndent = function () {
            this.writeToOutput(this.getIndentString());
        };

        Emitter.prototype.emitComment = function (comment, trailing, first) {
            if (this.emitOptions.compilationSettings().removeComments()) {
                return;
            }

            var text = getTrimmedTextLines(comment);
            var emitColumn = this.emitState.column;

            if (emitColumn === 0) {
                this.emitIndent();
            } else if (trailing && first) {
                this.writeToOutput(" ");
            }

            if (comment.kind() === 6 /* MultiLineCommentTrivia */) {
                this.recordSourceMappingStart(comment);
                this.writeToOutput(text[0]);

                if (text.length > 1 || comment.endsLine) {
                    for (var i = 1; i < text.length; i++) {
                        this.writeLineToOutput("");
                        this.emitIndent();
                        this.writeToOutput(text[i]);
                    }
                    this.recordSourceMappingEnd(comment);
                    this.writeLineToOutput("");
                } else {
                    this.recordSourceMappingEnd(comment);
                    this.writeToOutput(" ");
                    return;
                }
            } else {
                this.recordSourceMappingStart(comment);
                this.writeToOutput(text[0]);
                this.recordSourceMappingEnd(comment);
                this.writeLineToOutput("");
            }

            if (!trailing && emitColumn !== 0) {
                this.emitIndent();
            }
        };

        Emitter.prototype.emitComments = function (ast, pre, onlyPinnedOrTripleSlashComments) {
            var _this = this;
            if (typeof onlyPinnedOrTripleSlashComments === "undefined") { onlyPinnedOrTripleSlashComments = false; }
            if (ast && ast.kind() !== 146 /* Block */) {
                if (ast.parent.kind() === 219 /* SimpleArrowFunctionExpression */ || ast.parent.kind() === 218 /* ParenthesizedArrowFunctionExpression */) {
                    return;
                }
            }

            if (pre) {
                var preComments = ast.preComments();

                if (preComments && ast === this.detachedCommentsElement) {
                    var detachedComments = this.getDetachedComments(ast);
                    preComments = preComments.slice(detachedComments.length);
                    this.detachedCommentsElement = null;
                }

                if (preComments && onlyPinnedOrTripleSlashComments) {
                    preComments = TypeScript.ArrayUtilities.where(preComments, function (c) {
                        return _this.isPinnedOrTripleSlash(c);
                    });
                }

                this.emitCommentsArray(preComments, false);
            } else {
                this.emitCommentsArray(ast.postComments(), true);
            }
        };

        Emitter.prototype.isPinnedOrTripleSlash = function (comment) {
            var fullText = comment.fullText();
            if (fullText.match(TypeScript.tripleSlashReferenceRegExp)) {
                return true;
            } else {
                return fullText.indexOf("/*!") === 0;
            }
        };

        Emitter.prototype.emitCommentsArray = function (comments, trailing) {
            if (!this.emitOptions.compilationSettings().removeComments() && comments) {
                for (var i = 0, n = comments.length; i < n; i++) {
                    this.emitComment(comments[i], trailing, i === 0);
                }
            }
        };

        Emitter.prototype.emitObjectLiteralExpression = function (objectLiteral) {
            this.recordSourceMappingStart(objectLiteral);

            this.writeToOutput("{");
            this.emitCommaSeparatedList(objectLiteral, objectLiteral.propertyAssignments, " ", true);
            this.writeToOutput("}");

            this.recordSourceMappingEnd(objectLiteral);
        };

        Emitter.prototype.emitArrayLiteralExpression = function (arrayLiteral) {
            this.recordSourceMappingStart(arrayLiteral);

            this.writeToOutput("[");
            this.emitCommaSeparatedList(arrayLiteral, arrayLiteral.expressions, "", true);
            this.writeToOutput("]");

            this.recordSourceMappingEnd(arrayLiteral);
        };

        Emitter.prototype.emitObjectCreationExpression = function (objectCreationExpression) {
            this.recordSourceMappingStart(objectCreationExpression);
            this.writeToOutput("new ");
            var target = objectCreationExpression.expression;

            this.emit(target);
            if (objectCreationExpression.argumentList) {
                this.recordSourceMappingStart(objectCreationExpression.argumentList);
                this.writeToOutput("(");
                this.emitCommaSeparatedList(objectCreationExpression.argumentList, objectCreationExpression.argumentList.arguments, "", false);
                this.writeToOutputWithSourceMapRecord(")", objectCreationExpression.argumentList.closeParenToken);
                this.recordSourceMappingEnd(objectCreationExpression.argumentList);
            }

            this.recordSourceMappingEnd(objectCreationExpression);
        };

        Emitter.prototype.getConstantDecl = function (dotExpr) {
            var pullSymbol = this.semanticInfoChain.getSymbolForAST(dotExpr);
            if (pullSymbol && pullSymbol.kind === 67108864 /* EnumMember */) {
                var pullDecls = pullSymbol.getDeclarations();
                if (pullDecls.length === 1) {
                    var pullDecl = pullDecls[0];
                    if (pullDecl.kind === 67108864 /* EnumMember */) {
                        return pullDecl;
                    }
                }
            }

            return null;
        };

        Emitter.prototype.tryEmitConstant = function (dotExpr) {
            var propertyName = dotExpr.name;
            var boundDecl = this.getConstantDecl(dotExpr);
            if (boundDecl) {
                var value = boundDecl.constantValue;
                if (value !== null) {
                    this.recordSourceMappingStart(dotExpr);
                    this.writeToOutput(value.toString());
                    var comment = " /* ";
                    comment += propertyName.text();
                    comment += " */";
                    this.writeToOutput(comment);
                    this.recordSourceMappingEnd(dotExpr);
                    return true;
                }
            }

            return false;
        };

        Emitter.prototype.emitInvocationExpression = function (callNode) {
            this.recordSourceMappingStart(callNode);
            var target = callNode.expression;
            var args = callNode.argumentList.arguments;

            if (target.kind() === 212 /* MemberAccessExpression */ && target.expression.kind() === 50 /* SuperKeyword */) {
                this.emit(target);
                this.writeToOutput(".call");
                this.recordSourceMappingStart(args);
                this.writeToOutput("(");
                this.emitThis();
                if (args && args.nonSeparatorCount() > 0) {
                    this.writeToOutput(", ");
                    this.emitCommaSeparatedList(callNode.argumentList, args, "", false);
                }
            } else {
                if (callNode.expression.kind() === 50 /* SuperKeyword */ && this.emitState.container === 4 /* Constructor */) {
                    this.writeToOutput("_super.call");
                } else {
                    this.emitJavascript(target, false);
                }
                this.recordSourceMappingStart(args);
                this.writeToOutput("(");
                if (callNode.expression.kind() === 50 /* SuperKeyword */ && this.emitState.container === 4 /* Constructor */) {
                    this.writeToOutput("this");
                    if (args && args.nonSeparatorCount() > 0) {
                        this.writeToOutput(", ");
                    }
                }
                this.emitCommaSeparatedList(callNode.argumentList, args, "", false);
            }

            this.writeToOutputWithSourceMapRecord(")", callNode.argumentList.closeParenToken);
            this.recordSourceMappingEnd(args);
            this.recordSourceMappingEnd(callNode);
        };

        Emitter.prototype.emitParameterList = function (list) {
            this.writeToOutput("(");
            this.emitCommentsArray(list.openParenTrailingComments, true);
            this.emitFunctionParameters(TypeScript.ASTHelpers.parametersFromParameterList(list));
            this.writeToOutput(")");
        };

        Emitter.prototype.emitFunctionParameters = function (parameters) {
            var argsLen = 0;

            if (parameters) {
                this.emitComments(parameters.ast, true);

                var tempContainer = this.setContainer(6 /* Args */);
                argsLen = parameters.length;
                var printLen = argsLen;
                if (parameters.lastParameterIsRest()) {
                    printLen--;
                }
                for (var i = 0; i < printLen; i++) {
                    var arg = parameters.astAt(i);
                    this.emit(arg);

                    if (i < (printLen - 1)) {
                        this.writeToOutput(", ");
                    }
                }
                this.setContainer(tempContainer);

                this.emitComments(parameters.ast, false);
            }
        };

        Emitter.prototype.emitFunctionBodyStatements = function (name, funcDecl, parameterList, block, bodyExpression) {
            this.writeLineToOutput(" {");
            if (name) {
                this.recordSourceMappingNameStart(name);
            }

            this.indenter.increaseIndent();

            if (block) {
                this.emitDetachedComments(block.statements);
            }

            if (this.shouldCaptureThis(funcDecl)) {
                this.writeCaptureThisStatement(funcDecl);
            }

            if (parameterList) {
                this.emitDefaultValueAssignments(parameterList);
                this.emitRestParameterInitializer(parameterList);
            }

            if (block) {
                this.emitList(block.statements);
                this.emitCommentsArray(block.closeBraceLeadingComments, false);
            } else {
                this.emitIndent();
                this.emitCommentsArray(bodyExpression.preComments(), false);
                this.writeToOutput("return ");
                this.emit(bodyExpression);
                this.writeLineToOutput(";");
                this.emitCommentsArray(bodyExpression.postComments(), true);
            }

            this.indenter.decreaseIndent();
            this.emitIndent();

            if (block) {
                this.writeToOutputWithSourceMapRecord("}", block.closeBraceToken);
            } else {
                this.writeToOutputWithSourceMapRecord("}", bodyExpression);
            }

            if (name) {
                this.recordSourceMappingNameEnd();
            }
        };

        Emitter.prototype.emitDefaultValueAssignments = function (parameters) {
            var n = parameters.length;
            if (parameters.lastParameterIsRest()) {
                n--;
            }

            for (var i = 0; i < n; i++) {
                var arg = parameters.astAt(i);
                var id = parameters.identifierAt(i);
                var equalsValueClause = parameters.initializerAt(i);
                if (equalsValueClause) {
                    this.emitIndent();
                    this.recordSourceMappingStart(arg);
                    this.writeToOutput("if (typeof " + id.text() + " === \"undefined\") { ");
                    this.writeToOutputWithSourceMapRecord(id.text(), id);
                    this.emitJavascript(equalsValueClause, false);
                    this.writeLineToOutput("; }");
                    this.recordSourceMappingEnd(arg);
                }
            }
        };

        Emitter.prototype.emitRestParameterInitializer = function (parameters) {
            if (parameters.lastParameterIsRest()) {
                var n = parameters.length;
                var lastArg = parameters.astAt(n - 1);
                var id = parameters.identifierAt(n - 1);
                this.emitIndent();
                this.recordSourceMappingStart(lastArg);
                this.writeToOutput("var ");
                this.writeToOutputWithSourceMapRecord(id.text(), id);
                this.writeLineToOutput(" = [];");
                this.recordSourceMappingEnd(lastArg);
                this.emitIndent();
                this.writeToOutput("for (");
                this.writeToOutputWithSourceMapRecord("var _i = 0;", lastArg);
                this.writeToOutput(" ");
                this.writeToOutputWithSourceMapRecord("_i < (arguments.length - " + (n - 1) + ")", lastArg);
                this.writeToOutput("; ");
                this.writeToOutputWithSourceMapRecord("_i++", lastArg);
                this.writeLineToOutput(") {");
                this.indenter.increaseIndent();
                this.emitIndent();

                this.writeToOutputWithSourceMapRecord(id.text() + "[_i] = arguments[_i + " + (n - 1) + "];", lastArg);
                this.writeLineToOutput("");
                this.indenter.decreaseIndent();
                this.emitIndent();
                this.writeLineToOutput("}");
            }
        };

        Emitter.prototype.getImportDecls = function (fileName) {
            var topLevelDecl = this.semanticInfoChain.topLevelDecl(this.document.fileName);
            var result = [];

            var dynamicModuleDecl = topLevelDecl.getChildDecls()[0];
            var queue = dynamicModuleDecl.getChildDecls();

            for (var i = 0, n = queue.length; i < n; i++) {
                var decl = queue[i];

                if (decl.kind & 128 /* TypeAlias */) {
                    var importStatementAST = this.semanticInfoChain.getASTForDecl(decl);
                    if (importStatementAST.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                        var symbol = decl.getSymbol();
                        var typeSymbol = symbol && symbol.type;
                        if (typeSymbol && typeSymbol !== this.semanticInfoChain.anyTypeSymbol && !typeSymbol.isError()) {
                            result.push(decl);
                        }
                    }
                }
            }

            return result;
        };

        Emitter.prototype.getModuleImportAndDependencyList = function (sourceUnit) {
            var importList = "";
            var dependencyList = "";

            var importDecls = this.getImportDecls(this.document.fileName);

            if (importDecls.length) {
                for (var i = 0; i < importDecls.length; i++) {
                    var importStatementDecl = importDecls[i];
                    var importStatementSymbol = importStatementDecl.getSymbol();
                    var importStatementAST = this.semanticInfoChain.getASTForDecl(importStatementDecl);

                    if (importStatementSymbol.isUsedAsValue()) {
                        if (i <= importDecls.length - 1) {
                            dependencyList += ", ";
                            importList += ", ";
                        }

                        importList += importStatementDecl.name;
                        dependencyList += importStatementAST.moduleReference.stringLiteral.text();
                    }
                }
            }

            var amdDependencies = this.document.amdDependencies();
            for (var i = 0; i < amdDependencies.length; i++) {
                dependencyList += ", \"" + amdDependencies[i] + "\"";
            }

            return {
                importList: importList,
                dependencyList: dependencyList
            };
        };

        Emitter.prototype.shouldCaptureThis = function (ast) {
            if (ast.kind() === 120 /* SourceUnit */) {
                var scriptDecl = this.semanticInfoChain.topLevelDecl(this.document.fileName);
                return TypeScript.hasFlag(scriptDecl.flags, 262144 /* MustCaptureThis */);
            }

            var decl = this.semanticInfoChain.getDeclForAST(ast);
            if (decl) {
                return TypeScript.hasFlag(decl.flags, 262144 /* MustCaptureThis */);
            }

            return false;
        };

        Emitter.prototype.emitEnum = function (moduleDecl) {
            var pullDecl = this.semanticInfoChain.getDeclForAST(moduleDecl);
            this.pushDecl(pullDecl);

            var svModuleName = this.moduleName;
            this.moduleName = moduleDecl.identifier.text();

            var temp = this.setContainer(1 /* Module */);
            var isExported = TypeScript.hasFlag(pullDecl.flags, 1 /* Exported */);

            if (!isExported) {
                this.recordSourceMappingStart(moduleDecl);
                this.writeToOutput("var ");
                this.recordSourceMappingStart(moduleDecl.identifier);
                this.writeToOutput(this.moduleName);
                this.recordSourceMappingEnd(moduleDecl.identifier);
                this.writeLineToOutput(";");
                this.recordSourceMappingEnd(moduleDecl);
                this.emitIndent();
            }

            this.writeToOutput("(");
            this.recordSourceMappingStart(moduleDecl);
            this.writeToOutput("function (");
            this.writeToOutputWithSourceMapRecord(this.moduleName, moduleDecl.identifier);
            this.writeLineToOutput(") {");

            this.recordSourceMappingNameStart(this.moduleName);

            this.indenter.increaseIndent();

            if (this.shouldCaptureThis(moduleDecl)) {
                this.writeCaptureThisStatement(moduleDecl);
            }

            this.emitSeparatedList(moduleDecl.enumElements);
            this.indenter.decreaseIndent();
            this.emitIndent();

            var parentIsDynamic = temp === 2 /* DynamicModule */;
            if (temp === 0 /* Prog */ && isExported) {
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.writeToOutput(")(this." + this.moduleName + " || (this." + this.moduleName + " = {}));");
            } else if (isExported || temp === 0 /* Prog */) {
                var dotMod = svModuleName !== "" ? (parentIsDynamic ? "exports" : svModuleName) + "." : svModuleName;
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.writeToOutput(")(" + dotMod + this.moduleName + " || (" + dotMod + this.moduleName + " = {}));");
            } else if (!isExported && temp !== 0 /* Prog */) {
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.writeToOutput(")(" + this.moduleName + " || (" + this.moduleName + " = {}));");
            } else {
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.writeToOutput(")();");
            }

            this.recordSourceMappingEnd(moduleDecl);
            if (temp !== 0 /* Prog */ && isExported) {
                this.recordSourceMappingStart(moduleDecl);
                if (parentIsDynamic) {
                    this.writeLineToOutput("");
                    this.emitIndent();
                    this.writeToOutput("var " + this.moduleName + " = exports." + this.moduleName + ";");
                } else {
                    this.writeLineToOutput("");
                    this.emitIndent();
                    this.writeToOutput("var " + this.moduleName + " = " + svModuleName + "." + this.moduleName + ";");
                }
                this.recordSourceMappingEnd(moduleDecl);
            }

            this.setContainer(temp);
            this.moduleName = svModuleName;

            this.popDecl(pullDecl);
        };

        Emitter.prototype.getModuleDeclToVerifyChildNameCollision = function (moduleDecl, changeNameIfAnyDeclarationInContext) {
            if (TypeScript.ArrayUtilities.contains(this.declStack, moduleDecl)) {
                return moduleDecl;
            } else if (changeNameIfAnyDeclarationInContext) {
                var symbol = moduleDecl.getSymbol();
                if (symbol) {
                    var otherDecls = symbol.getDeclarations();
                    for (var i = 0; i < otherDecls.length; i++) {
                        if (TypeScript.ArrayUtilities.contains(this.declStack, otherDecls[i])) {
                            return otherDecls[i];
                        }
                    }
                }
            }

            return null;
        };

        Emitter.prototype.hasChildNameCollision = function (moduleName, parentDecl) {
            var _this = this;
            var childDecls = parentDecl.getChildDecls();
            return TypeScript.ArrayUtilities.any(childDecls, function (childDecl) {
                var childAST = _this.semanticInfoChain.getASTForDecl(childDecl);

                if (childDecl.kind != 67108864 /* EnumMember */ && _this.shouldEmit(childAST)) {
                    if (childDecl.name === moduleName) {
                        if (parentDecl.kind != 8 /* Class */) {
                            return true;
                        }

                        if (!(childDecl.kind == 65536 /* Method */ || childDecl.kind == 4096 /* Property */ || childDecl.kind == 524288 /* SetAccessor */ || childDecl.kind == 262144 /* GetAccessor */)) {
                            return true;
                        }
                    }

                    if (_this.hasChildNameCollision(moduleName, childDecl)) {
                        return true;
                    }
                }
                return false;
            });
        };

        Emitter.prototype.getModuleName = function (moduleDecl, changeNameIfAnyDeclarationInContext) {
            var moduleName = moduleDecl.name;
            var moduleDisplayName = moduleDecl.getDisplayName();

            moduleDecl = this.getModuleDeclToVerifyChildNameCollision(moduleDecl, changeNameIfAnyDeclarationInContext);
            if (moduleDecl && moduleDecl.kind != 64 /* Enum */) {
                while (this.hasChildNameCollision(moduleName, moduleDecl)) {
                    moduleName = "_" + moduleName;
                    moduleDisplayName = "_" + moduleDisplayName;
                }
            }

            return moduleDisplayName;
        };

        Emitter.prototype.emitModuleDeclarationWorker = function (moduleDecl) {
            if (moduleDecl.stringLiteral) {
                this.emitSingleModuleDeclaration(moduleDecl, moduleDecl.stringLiteral);
            } else {
                var moduleNames = TypeScript.ASTHelpers.getModuleNames(moduleDecl.name);
                this.emitSingleModuleDeclaration(moduleDecl, moduleNames[0]);
            }
        };

        Emitter.prototype.emitSingleModuleDeclaration = function (moduleDecl, moduleName) {
            var isLastName = TypeScript.ASTHelpers.isLastNameOfModule(moduleDecl, moduleName);

            if (isLastName) {
                this.emitComments(moduleDecl, true);
            }

            var pullDecl = this.semanticInfoChain.getDeclForAST(moduleName);
            this.pushDecl(pullDecl);

            var svModuleName = this.moduleName;

            if (moduleDecl.stringLiteral) {
                this.moduleName = moduleDecl.stringLiteral.valueText();
                if (TypeScript.isTSFile(this.moduleName)) {
                    this.moduleName = this.moduleName.substring(0, this.moduleName.length - ".ts".length);
                }
            } else {
                this.moduleName = moduleName.text();
            }

            var temp = this.setContainer(1 /* Module */);
            var isExported = TypeScript.hasFlag(pullDecl.flags, 1 /* Exported */);

            if (!isExported) {
                this.recordSourceMappingStart(moduleDecl);
                this.writeToOutput("var ");
                this.recordSourceMappingStart(moduleName);
                this.writeToOutput(this.moduleName);
                this.recordSourceMappingEnd(moduleName);
                this.writeLineToOutput(";");
                this.recordSourceMappingEnd(moduleDecl);
                this.emitIndent();
            }

            this.writeToOutput("(");
            this.recordSourceMappingStart(moduleDecl);
            this.writeToOutput("function (");

            this.moduleName = this.getModuleName(pullDecl);
            this.writeToOutputWithSourceMapRecord(this.moduleName, moduleName);
            this.writeLineToOutput(") {");

            this.recordSourceMappingNameStart(moduleName.text());

            this.indenter.increaseIndent();

            if (this.shouldCaptureThis(moduleDecl)) {
                this.writeCaptureThisStatement(moduleDecl);
            }

            if (moduleName === moduleDecl.stringLiteral) {
                this.emitList(moduleDecl.moduleElements);
            } else {
                var moduleNames = TypeScript.ASTHelpers.getModuleNames(moduleDecl.name);
                var nameIndex = moduleNames.indexOf(moduleName);
                TypeScript.Debug.assert(nameIndex >= 0);

                if (isLastName) {
                    this.emitList(moduleDecl.moduleElements);
                } else {
                    this.emitIndent();
                    this.emitSingleModuleDeclaration(moduleDecl, moduleNames[nameIndex + 1]);
                    this.writeLineToOutput("");
                }
            }

            this.moduleName = moduleName.text();
            this.indenter.decreaseIndent();
            this.emitIndent();

            var parentIsDynamic = temp === 2 /* DynamicModule */;
            this.recordSourceMappingStart(moduleDecl.endingToken);
            if (temp === 0 /* Prog */ && isExported) {
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.recordSourceMappingEnd(moduleDecl.endingToken);
                this.writeToOutput(")(this." + this.moduleName + " || (this." + this.moduleName + " = {}));");
            } else if (isExported || temp === 0 /* Prog */) {
                var dotMod = svModuleName !== "" ? (parentIsDynamic ? "exports" : svModuleName) + "." : svModuleName;
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.recordSourceMappingEnd(moduleDecl.endingToken);
                this.writeToOutput(")(" + dotMod + this.moduleName + " || (" + dotMod + this.moduleName + " = {}));");
            } else if (!isExported && temp !== 0 /* Prog */) {
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.recordSourceMappingEnd(moduleDecl.endingToken);
                this.writeToOutput(")(" + this.moduleName + " || (" + this.moduleName + " = {}));");
            } else {
                this.writeToOutput("}");
                this.recordSourceMappingNameEnd();
                this.recordSourceMappingEnd(moduleDecl.endingToken);
                this.writeToOutput(")();");
            }

            this.recordSourceMappingEnd(moduleDecl);
            if (temp !== 0 /* Prog */ && isExported) {
                this.recordSourceMappingStart(moduleDecl);
                if (parentIsDynamic) {
                    this.writeLineToOutput("");
                    this.emitIndent();
                    this.writeToOutput("var " + this.moduleName + " = exports." + this.moduleName + ";");
                } else {
                    this.writeLineToOutput("");
                    this.emitIndent();
                    this.writeToOutput("var " + this.moduleName + " = " + svModuleName + "." + this.moduleName + ";");
                }
                this.recordSourceMappingEnd(moduleDecl);
            }

            this.setContainer(temp);
            this.moduleName = svModuleName;

            this.popDecl(pullDecl);

            if (isLastName) {
                this.emitComments(moduleDecl, false);
            }
        };

        Emitter.prototype.emitEnumElement = function (varDecl) {
            var pullDecl = this.semanticInfoChain.getDeclForAST(varDecl);
            TypeScript.Debug.assert(pullDecl && pullDecl.kind === 67108864 /* EnumMember */);

            this.emitComments(varDecl, true);
            this.recordSourceMappingStart(varDecl);
            var name = varDecl.propertyName.text();
            var quoted = TypeScript.isQuoted(name);
            this.writeToOutput(this.moduleName);
            this.writeToOutput('[');
            this.writeToOutput(this.moduleName);
            this.writeToOutput('[');
            this.writeToOutput(quoted ? name : '"' + name + '"');
            this.writeToOutput(']');

            if (varDecl.equalsValueClause) {
                this.emit(varDecl.equalsValueClause);
            } else if (pullDecl.constantValue !== null) {
                this.writeToOutput(' = ');
                this.writeToOutput(pullDecl.constantValue.toString());
            } else {
                this.writeToOutput(' = null');
            }

            this.writeToOutput('] = ');
            this.writeToOutput(quoted ? name : '"' + name + '"');
            this.recordSourceMappingEnd(varDecl);
            this.emitComments(varDecl, false);
            this.writeToOutput(';');
        };

        Emitter.prototype.emitElementAccessExpression = function (expression) {
            this.recordSourceMappingStart(expression);
            this.emit(expression.expression);
            this.writeToOutput("[");
            this.emit(expression.argumentExpression);
            this.writeToOutput("]");
            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitSimpleArrowFunctionExpression = function (arrowFunction) {
            this.emitAnyArrowFunctionExpression(arrowFunction, null, TypeScript.ASTHelpers.parametersFromIdentifier(arrowFunction.identifier), arrowFunction.block, arrowFunction.expression);
        };

        Emitter.prototype.emitParenthesizedArrowFunctionExpression = function (arrowFunction) {
            this.emitAnyArrowFunctionExpression(arrowFunction, null, TypeScript.ASTHelpers.parametersFromParameterList(arrowFunction.callSignature.parameterList), arrowFunction.block, arrowFunction.expression);
        };

        Emitter.prototype.emitAnyArrowFunctionExpression = function (arrowFunction, funcName, parameters, block, expression) {
            var savedInArrowFunction = this.inArrowFunction;
            this.inArrowFunction = true;

            var temp = this.setContainer(5 /* Function */);

            this.recordSourceMappingStart(arrowFunction);

            var pullDecl = this.semanticInfoChain.getDeclForAST(arrowFunction);
            this.pushDecl(pullDecl);

            this.emitComments(arrowFunction, true);

            this.recordSourceMappingStart(arrowFunction);
            this.writeToOutput("function ");
            this.writeToOutput("(");
            this.emitFunctionParameters(parameters);
            this.writeToOutput(")");

            this.emitFunctionBodyStatements(funcName, arrowFunction, parameters, block, expression);

            this.recordSourceMappingEnd(arrowFunction);

            this.recordSourceMappingEnd(arrowFunction);

            this.emitComments(arrowFunction, false);

            this.popDecl(pullDecl);
            this.setContainer(temp);
            this.inArrowFunction = savedInArrowFunction;
        };

        Emitter.prototype.emitConstructor = function (funcDecl) {
            if (!funcDecl.block) {
                return;
            }
            var temp = this.setContainer(4 /* Constructor */);

            this.recordSourceMappingStart(funcDecl);

            var pullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            this.pushDecl(pullDecl);

            this.emitComments(funcDecl, true);

            this.recordSourceMappingStart(funcDecl);
            this.writeToOutput("function ");
            this.writeToOutput(this.thisClassNode.identifier.text());
            this.writeToOutput("(");
            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList);
            this.emitFunctionParameters(parameters);
            this.writeLineToOutput(") {");

            this.recordSourceMappingNameStart("constructor");
            this.indenter.increaseIndent();

            this.emitDefaultValueAssignments(parameters);
            this.emitRestParameterInitializer(parameters);

            if (this.shouldCaptureThis(funcDecl)) {
                this.writeCaptureThisStatement(funcDecl);
            }

            this.emitConstructorStatements(funcDecl);
            this.emitCommentsArray(funcDecl.block.closeBraceLeadingComments, false);

            this.indenter.decreaseIndent();
            this.emitIndent();
            this.writeToOutputWithSourceMapRecord("}", funcDecl.block.closeBraceToken);

            this.recordSourceMappingNameEnd();
            this.recordSourceMappingEnd(funcDecl);

            this.recordSourceMappingEnd(funcDecl);

            this.emitComments(funcDecl, false);

            this.popDecl(pullDecl);
            this.setContainer(temp);
        };

        Emitter.prototype.emitGetAccessor = function (accessor) {
            this.recordSourceMappingStart(accessor);
            this.writeToOutput("get ");

            var temp = this.setContainer(5 /* Function */);

            this.recordSourceMappingStart(accessor);

            var pullDecl = this.semanticInfoChain.getDeclForAST(accessor);
            this.pushDecl(pullDecl);

            this.recordSourceMappingStart(accessor);

            var accessorSymbol = TypeScript.PullHelpers.getAccessorSymbol(accessor, this.semanticInfoChain);
            var container = accessorSymbol.getContainer();
            var containerKind = container.kind;

            this.recordSourceMappingNameStart(accessor.propertyName.text());
            this.writeToOutput(accessor.propertyName.text());
            this.writeToOutput("(");
            this.writeToOutput(")");

            this.emitFunctionBodyStatements(null, accessor, TypeScript.ASTHelpers.parametersFromParameterList(accessor.parameterList), accessor.block, null);

            this.recordSourceMappingEnd(accessor);

            this.recordSourceMappingEnd(accessor);

            this.popDecl(pullDecl);
            this.setContainer(temp);
            this.recordSourceMappingEnd(accessor);
        };

        Emitter.prototype.emitSetAccessor = function (accessor) {
            this.recordSourceMappingStart(accessor);
            this.writeToOutput("set ");

            var temp = this.setContainer(5 /* Function */);

            this.recordSourceMappingStart(accessor);

            var pullDecl = this.semanticInfoChain.getDeclForAST(accessor);
            this.pushDecl(pullDecl);

            this.recordSourceMappingStart(accessor);

            var accessorSymbol = TypeScript.PullHelpers.getAccessorSymbol(accessor, this.semanticInfoChain);
            var container = accessorSymbol.getContainer();
            var containerKind = container.kind;

            this.recordSourceMappingNameStart(accessor.propertyName.text());
            this.writeToOutput(accessor.propertyName.text());
            this.writeToOutput("(");

            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(accessor.parameterList);
            this.emitFunctionParameters(parameters);
            this.writeToOutput(")");

            this.emitFunctionBodyStatements(null, accessor, parameters, accessor.block, null);

            this.recordSourceMappingEnd(accessor);

            this.recordSourceMappingEnd(accessor);

            this.popDecl(pullDecl);
            this.setContainer(temp);
            this.recordSourceMappingEnd(accessor);
        };

        Emitter.prototype.emitFunctionExpression = function (funcDecl) {
            var savedInArrowFunction = this.inArrowFunction;
            this.inArrowFunction = false;

            var temp = this.setContainer(5 /* Function */);

            var funcName = funcDecl.identifier ? funcDecl.identifier.text() : null;

            this.recordSourceMappingStart(funcDecl);

            var pullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            this.pushDecl(pullDecl);

            this.recordSourceMappingStart(funcDecl);
            this.writeToOutput("function ");

            if (funcDecl.identifier) {
                this.recordSourceMappingStart(funcDecl.identifier);
                this.writeToOutput(funcDecl.identifier.text());
                this.recordSourceMappingEnd(funcDecl.identifier);
            }

            this.writeToOutput("(");

            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList);
            this.emitFunctionParameters(parameters);
            this.writeToOutput(")");

            this.emitFunctionBodyStatements(funcName, funcDecl, parameters, funcDecl.block, null);

            this.recordSourceMappingEnd(funcDecl);

            this.recordSourceMappingEnd(funcDecl);

            this.emitComments(funcDecl, false);

            this.popDecl(pullDecl);

            this.setContainer(temp);
            this.inArrowFunction = savedInArrowFunction;
        };

        Emitter.prototype.emitFunction = function (funcDecl) {
            if (funcDecl.block === null) {
                return;
            }
            var savedInArrowFunction = this.inArrowFunction;
            this.inArrowFunction = false;

            var temp = this.setContainer(5 /* Function */);

            var funcName = funcDecl.identifier.text();

            this.recordSourceMappingStart(funcDecl);

            var printName = funcDecl.identifier !== null;
            var pullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            this.pushDecl(pullDecl);

            this.emitComments(funcDecl, true);

            this.recordSourceMappingStart(funcDecl);
            this.writeToOutput("function ");

            if (printName) {
                var id = funcDecl.identifier.text();
                if (id) {
                    if (funcDecl.identifier) {
                        this.recordSourceMappingStart(funcDecl.identifier);
                    }
                    this.writeToOutput(id);
                    if (funcDecl.identifier) {
                        this.recordSourceMappingEnd(funcDecl.identifier);
                    }
                }
            }

            this.emitParameterList(funcDecl.callSignature.parameterList);

            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList);
            this.emitFunctionBodyStatements(funcDecl.identifier.text(), funcDecl, parameters, funcDecl.block, null);

            this.recordSourceMappingEnd(funcDecl);

            this.recordSourceMappingEnd(funcDecl);

            this.emitComments(funcDecl, false);

            this.popDecl(pullDecl);

            this.setContainer(temp);
            this.inArrowFunction = savedInArrowFunction;

            if (funcDecl.block) {
                var pullFunctionDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
                if ((this.emitState.container === 1 /* Module */ || this.emitState.container === 2 /* DynamicModule */) && pullFunctionDecl && TypeScript.hasFlag(pullFunctionDecl.flags, 1 /* Exported */)) {
                    this.writeLineToOutput("");
                    this.emitIndent();
                    var modName = this.emitState.container === 1 /* Module */ ? this.moduleName : "exports";
                    this.recordSourceMappingStart(funcDecl);
                    this.writeToOutput(modName + "." + funcName + " = " + funcName + ";");
                    this.recordSourceMappingEnd(funcDecl);
                }
            }
        };

        Emitter.prototype.emitAmbientVarDecl = function (varDecl) {
            this.recordSourceMappingStart(this.currentVariableDeclaration);
            if (varDecl.equalsValueClause) {
                this.emitComments(varDecl, true);
                this.recordSourceMappingStart(varDecl);
                this.writeToOutputWithSourceMapRecord(varDecl.propertyName.text(), varDecl.propertyName);
                this.emitJavascript(varDecl.equalsValueClause, false);
                this.recordSourceMappingEnd(varDecl);
                this.emitComments(varDecl, false);
            }
        };

        Emitter.prototype.emitVarDeclVar = function () {
            if (this.currentVariableDeclaration) {
                this.writeToOutput("var ");
            }
        };

        Emitter.prototype.emitVariableDeclaration = function (declaration) {
            var varDecl = declaration.declarators.nonSeparatorAt(0);

            var symbol = this.semanticInfoChain.getSymbolForAST(varDecl);

            var parentSymbol = symbol ? symbol.getContainer() : null;
            var parentKind = parentSymbol ? parentSymbol.kind : 0 /* None */;

            this.emitComments(declaration, true);

            var pullVarDecl = this.semanticInfoChain.getDeclForAST(varDecl);
            var isAmbientWithoutInit = pullVarDecl && TypeScript.hasFlag(pullVarDecl.flags, 8 /* Ambient */) && varDecl.equalsValueClause === null;
            if (!isAmbientWithoutInit) {
                var prevVariableDeclaration = this.currentVariableDeclaration;
                this.currentVariableDeclaration = declaration;

                for (var i = 0, n = declaration.declarators.nonSeparatorCount(); i < n; i++) {
                    var declarator = declaration.declarators.nonSeparatorAt(i);

                    if (i > 0) {
                        this.writeToOutput(", ");
                    }

                    this.emit(declarator);
                }
                this.currentVariableDeclaration = prevVariableDeclaration;

                this.recordSourceMappingEnd(declaration);
            }

            this.emitComments(declaration, false);
        };

        Emitter.prototype.emitMemberVariableDeclaration = function (varDecl) {
            TypeScript.Debug.assert(!TypeScript.hasModifier(varDecl.modifiers, 16 /* Static */) && varDecl.variableDeclarator.equalsValueClause);

            var pullDecl = this.semanticInfoChain.getDeclForAST(varDecl);
            this.pushDecl(pullDecl);

            this.emitComments(varDecl, true);
            this.recordSourceMappingStart(varDecl);

            var varDeclName = varDecl.variableDeclarator.propertyName.text();
            var quotedOrNumber = TypeScript.isQuoted(varDeclName) || varDecl.variableDeclarator.propertyName.kind() !== 11 /* IdentifierName */;

            var symbol = this.semanticInfoChain.getSymbolForAST(varDecl);
            var parentSymbol = symbol ? symbol.getContainer() : null;
            var parentDecl = pullDecl && pullDecl.getParentDecl();

            if (quotedOrNumber) {
                this.writeToOutput("this[");
            } else {
                this.writeToOutput("this.");
            }

            this.writeToOutputWithSourceMapRecord(varDecl.variableDeclarator.propertyName.text(), varDecl.variableDeclarator.propertyName);

            if (quotedOrNumber) {
                this.writeToOutput("]");
            }

            if (varDecl.variableDeclarator.equalsValueClause) {
                var prevVariableDeclaration = this.currentVariableDeclaration;
                this.emit(varDecl.variableDeclarator.equalsValueClause);
                this.currentVariableDeclaration = prevVariableDeclaration;
            }

            if (this.emitState.container !== 6 /* Args */) {
                this.writeToOutput(";");
            }

            this.recordSourceMappingEnd(varDecl);
            this.emitComments(varDecl, false);

            this.popDecl(pullDecl);
        };

        Emitter.prototype.emitVariableDeclarator = function (varDecl) {
            var pullDecl = this.semanticInfoChain.getDeclForAST(varDecl);
            this.pushDecl(pullDecl);
            if (pullDecl && (pullDecl.flags & 8 /* Ambient */) === 8 /* Ambient */) {
                this.emitAmbientVarDecl(varDecl);
            } else {
                this.emitComments(varDecl, true);
                this.recordSourceMappingStart(this.currentVariableDeclaration);
                this.recordSourceMappingStart(varDecl);

                var varDeclName = varDecl.propertyName.text();

                var symbol = this.semanticInfoChain.getSymbolForAST(varDecl);
                var parentSymbol = symbol ? symbol.getContainer() : null;
                var parentDecl = pullDecl && pullDecl.getParentDecl();
                var parentIsModule = parentDecl && (parentDecl.flags & 102400 /* SomeInitializedModule */);

                if (parentIsModule) {
                    if (!TypeScript.hasFlag(pullDecl.flags, 1 /* Exported */)) {
                        this.emitVarDeclVar();
                    } else {
                        if (this.emitState.container === 2 /* DynamicModule */) {
                            this.writeToOutput("exports.");
                        } else {
                            this.writeToOutput(this.moduleName + ".");
                        }
                    }
                } else {
                    this.emitVarDeclVar();
                }

                this.writeToOutputWithSourceMapRecord(varDecl.propertyName.text(), varDecl.propertyName);

                if (varDecl.equalsValueClause) {
                    var prevVariableDeclaration = this.currentVariableDeclaration;
                    this.emit(varDecl.equalsValueClause);
                    this.currentVariableDeclaration = prevVariableDeclaration;
                }

                this.recordSourceMappingEnd(varDecl);
                this.emitComments(varDecl, false);
            }
            this.currentVariableDeclaration = undefined;
            this.popDecl(pullDecl);
        };

        Emitter.prototype.symbolIsUsedInItsEnclosingContainer = function (symbol, dynamic) {
            if (typeof dynamic === "undefined") { dynamic = false; }
            var symDecls = symbol.getDeclarations();

            if (symDecls.length) {
                var enclosingDecl = this.getEnclosingDecl();
                if (enclosingDecl) {
                    var parentDecl = symDecls[0].getParentDecl();
                    if (parentDecl) {
                        var symbolDeclarationEnclosingContainer = parentDecl;
                        var enclosingContainer = enclosingDecl;

                        while (symbolDeclarationEnclosingContainer) {
                            if (symbolDeclarationEnclosingContainer.kind === (dynamic ? 32 /* DynamicModule */ : 4 /* Container */)) {
                                break;
                            }
                            symbolDeclarationEnclosingContainer = symbolDeclarationEnclosingContainer.getParentDecl();
                        }

                        if (symbolDeclarationEnclosingContainer) {
                            while (enclosingContainer) {
                                if (enclosingContainer.kind === (dynamic ? 32 /* DynamicModule */ : 4 /* Container */)) {
                                    break;
                                }

                                enclosingContainer = enclosingContainer.getParentDecl();
                            }
                        }

                        if (symbolDeclarationEnclosingContainer && enclosingContainer) {
                            var same = symbolDeclarationEnclosingContainer === enclosingContainer;

                            if (!same && symbol.anyDeclHasFlag(32768 /* InitializedModule */)) {
                                same = symbolDeclarationEnclosingContainer === enclosingContainer.getParentDecl();
                            }

                            return same;
                        }
                    }
                }
            }

            return false;
        };

        Emitter.prototype.shouldQualifySymbolNameWithParentName = function (symbol) {
            var enclosingContextDeclPath = this.declStack;
            var symbolDeclarations = symbol.getDeclarations();
            for (var i = 0; i < symbolDeclarations.length; i++) {
                var currentDecl = symbolDeclarations[i];
                var declParent = currentDecl.getParentDecl();

                if (currentDecl.kind === 67108864 /* EnumMember */) {
                    return true;
                }

                if (!TypeScript.hasFlag(currentDecl.flags, 1 /* Exported */)) {
                    return false;
                }

                if (currentDecl.kind === 512 /* Variable */ && !TypeScript.hasFlag(currentDecl.flags, 118784 /* ImplicitVariable */)) {
                    return true;
                }

                if (TypeScript.ArrayUtilities.contains(this.declStack, declParent)) {
                    return false;
                }
            }

            return true;
        };

        Emitter.prototype.getSymbolForEmit = function (ast) {
            var pullSymbol = this.semanticInfoChain.getSymbolForAST(ast);
            var pullSymbolAlias = this.semanticInfoChain.getAliasSymbolForAST(ast);
            if (pullSymbol && pullSymbolAlias) {
                var symbolToCompare = TypeScript.isTypesOnlyLocation(ast) ? pullSymbolAlias.getExportAssignedTypeSymbol() : pullSymbolAlias.getExportAssignedValueSymbol();

                if (pullSymbol === symbolToCompare) {
                    pullSymbol = pullSymbolAlias;
                    pullSymbolAlias = null;
                }
            }
            return { symbol: pullSymbol, aliasSymbol: pullSymbolAlias };
        };

        Emitter.prototype.emitName = function (name, addThis) {
            this.emitComments(name, true);
            this.recordSourceMappingStart(name);
            if (name.text().length > 0) {
                var symbolForEmit = this.getSymbolForEmit(name);
                var pullSymbol = symbolForEmit.symbol;
                if (!pullSymbol) {
                    pullSymbol = this.semanticInfoChain.anyTypeSymbol;
                }
                var pullSymbolAlias = symbolForEmit.aliasSymbol;
                var pullSymbolKind = pullSymbol.kind;
                var isLocalAlias = pullSymbolAlias && (pullSymbolAlias.getDeclarations()[0].getParentDecl() === this.getEnclosingDecl());
                if (addThis && (this.emitState.container !== 6 /* Args */) && pullSymbol) {
                    var pullSymbolContainer = pullSymbol.getContainer();

                    if (pullSymbolContainer) {
                        var pullSymbolContainerKind = pullSymbolContainer.kind;

                        if (TypeScript.PullHelpers.symbolIsModule(pullSymbolContainer) || pullSymbolContainerKind === 64 /* Enum */ || pullSymbolContainer.anyDeclHasFlag(32768 /* InitializedModule */ | 4096 /* Enum */)) {
                            var needToEmitParentName = this.shouldQualifySymbolNameWithParentName(pullSymbol);
                            if (needToEmitParentName) {
                                var parentDecl = pullSymbol.getDeclarations()[0].getParentDecl();
                                TypeScript.Debug.assert(parentDecl && !parentDecl.isRootDecl());
                                this.writeToOutput(this.getModuleName(parentDecl, true) + ".");
                            }
                        } else if (pullSymbolContainerKind === 32 /* DynamicModule */ || pullSymbolContainer.anyDeclHasFlag(65536 /* InitializedDynamicModule */)) {
                            if (pullSymbolKind === 4096 /* Property */) {
                                this.writeToOutput("exports.");
                            } else if (pullSymbol.anyDeclHasFlag(1 /* Exported */) && !isLocalAlias && !pullSymbol.anyDeclHasFlag(118784 /* ImplicitVariable */) && pullSymbol.kind !== 32768 /* ConstructorMethod */ && pullSymbol.kind !== 8 /* Class */ && pullSymbol.kind !== 64 /* Enum */) {
                                this.writeToOutput("exports.");
                            }
                        }
                    }
                }

                this.writeToOutput(name.text());
            }

            this.recordSourceMappingEnd(name);
            this.emitComments(name, false);
        };

        Emitter.prototype.recordSourceMappingNameStart = function (name) {
            if (this.sourceMapper) {
                var nameIndex = -1;
                if (name) {
                    if (this.sourceMapper.currentNameIndex.length > 0) {
                        var parentNameIndex = this.sourceMapper.currentNameIndex[this.sourceMapper.currentNameIndex.length - 1];
                        if (parentNameIndex !== -1) {
                            name = this.sourceMapper.names[parentNameIndex] + "." + name;
                        }
                    }

                    var nameIndex = this.sourceMapper.names.length - 1;
                    for (nameIndex; nameIndex >= 0; nameIndex--) {
                        if (this.sourceMapper.names[nameIndex] === name) {
                            break;
                        }
                    }

                    if (nameIndex === -1) {
                        nameIndex = this.sourceMapper.names.length;
                        this.sourceMapper.names.push(name);
                    }
                }
                this.sourceMapper.currentNameIndex.push(nameIndex);
            }
        };

        Emitter.prototype.recordSourceMappingNameEnd = function () {
            if (this.sourceMapper) {
                this.sourceMapper.currentNameIndex.pop();
            }
        };

        Emitter.prototype.recordSourceMappingStart = function (ast) {
            if (this.sourceMapper && TypeScript.ASTHelpers.isValidAstNode(ast)) {
                var lineCol = { line: -1, character: -1 };
                var sourceMapping = new TypeScript.SourceMapping();
                sourceMapping.start.emittedColumn = this.emitState.column;
                sourceMapping.start.emittedLine = this.emitState.line;

                var lineMap = this.document.lineMap();
                lineMap.fillLineAndCharacterFromPosition(ast.start(), lineCol);
                sourceMapping.start.sourceColumn = lineCol.character;
                sourceMapping.start.sourceLine = lineCol.line + 1;
                lineMap.fillLineAndCharacterFromPosition(ast.end(), lineCol);
                sourceMapping.end.sourceColumn = lineCol.character;
                sourceMapping.end.sourceLine = lineCol.line + 1;

                TypeScript.Debug.assert(!isNaN(sourceMapping.start.emittedColumn));
                TypeScript.Debug.assert(!isNaN(sourceMapping.start.emittedLine));
                TypeScript.Debug.assert(!isNaN(sourceMapping.start.sourceColumn));
                TypeScript.Debug.assert(!isNaN(sourceMapping.start.sourceLine));
                TypeScript.Debug.assert(!isNaN(sourceMapping.end.sourceColumn));
                TypeScript.Debug.assert(!isNaN(sourceMapping.end.sourceLine));

                if (this.sourceMapper.currentNameIndex.length > 0) {
                    sourceMapping.nameIndex = this.sourceMapper.currentNameIndex[this.sourceMapper.currentNameIndex.length - 1];
                }

                var siblings = this.sourceMapper.currentMappings[this.sourceMapper.currentMappings.length - 1];
                siblings.push(sourceMapping);
                this.sourceMapper.currentMappings.push(sourceMapping.childMappings);
                this.sourceMapper.increaseMappingLevel(ast);
            }
        };

        Emitter.prototype.recordSourceMappingEnd = function (ast) {
            if (this.sourceMapper && TypeScript.ASTHelpers.isValidAstNode(ast)) {
                this.sourceMapper.currentMappings.pop();

                var siblings = this.sourceMapper.currentMappings[this.sourceMapper.currentMappings.length - 1];
                var sourceMapping = siblings[siblings.length - 1];

                sourceMapping.end.emittedColumn = this.emitState.column;
                sourceMapping.end.emittedLine = this.emitState.line;

                TypeScript.Debug.assert(!isNaN(sourceMapping.end.emittedColumn));
                TypeScript.Debug.assert(!isNaN(sourceMapping.end.emittedLine));

                this.sourceMapper.decreaseMappingLevel(ast);
            }
        };

        Emitter.prototype.getOutputFiles = function () {
            var result = [];
            if (this.sourceMapper !== null) {
                this.sourceMapper.emitSourceMapping();
                result.push(this.sourceMapper.getOutputFile());
            }

            result.push(this.outfile.getOutputFile());
            return result;
        };

        Emitter.prototype.emitParameterPropertyAndMemberVariableAssignments = function () {
            var constructorDecl = getLastConstructor(this.thisClassNode);

            if (constructorDecl) {
                for (var i = 0, n = constructorDecl.callSignature.parameterList.parameters.nonSeparatorCount(); i < n; i++) {
                    var parameter = constructorDecl.callSignature.parameterList.parameters.nonSeparatorAt(i);
                    var parameterDecl = this.semanticInfoChain.getDeclForAST(parameter);
                    if (TypeScript.hasFlag(parameterDecl.flags, 8388608 /* PropertyParameter */)) {
                        this.emitIndent();
                        this.recordSourceMappingStart(parameter);
                        this.writeToOutputWithSourceMapRecord("this." + parameter.identifier.text(), parameter.identifier);
                        this.writeToOutput(" = ");
                        this.writeToOutputWithSourceMapRecord(parameter.identifier.text(), parameter.identifier);
                        this.writeLineToOutput(";");
                        this.recordSourceMappingEnd(parameter);
                    }
                }
            }

            for (var i = 0, n = this.thisClassNode.classElements.childCount(); i < n; i++) {
                if (this.thisClassNode.classElements.childAt(i).kind() === 136 /* MemberVariableDeclaration */) {
                    var varDecl = this.thisClassNode.classElements.childAt(i);
                    if (!TypeScript.hasModifier(varDecl.modifiers, 16 /* Static */) && varDecl.variableDeclarator.equalsValueClause) {
                        this.emitIndent();
                        this.emitMemberVariableDeclaration(varDecl);
                        this.writeLineToOutput("");
                    }
                }
            }
        };

        Emitter.prototype.isOnSameLine = function (pos1, pos2) {
            var lineMap = this.document.lineMap();
            return lineMap.getLineNumberFromPosition(pos1) === lineMap.getLineNumberFromPosition(pos2);
        };

        Emitter.prototype.emitCommaSeparatedList = function (parent, list, buffer, preserveNewLines) {
            if (list === null || list.nonSeparatorCount() === 0) {
                return;
            }

            var startLine = preserveNewLines && !this.isOnSameLine(parent.end(), list.nonSeparatorAt(0).end());

            if (preserveNewLines) {
                this.indenter.increaseIndent();
            }

            if (startLine) {
                this.writeLineToOutput("");
            } else {
                this.writeToOutput(buffer);
            }

            for (var i = 0, n = list.nonSeparatorCount(); i < n; i++) {
                var emitNode = list.nonSeparatorAt(i);

                this.emitJavascript(emitNode, startLine);

                if (i < (n - 1)) {
                    startLine = preserveNewLines && !this.isOnSameLine(emitNode.end(), list.nonSeparatorAt(i + 1).start());
                    if (startLine) {
                        this.writeLineToOutput(",");
                    } else {
                        this.writeToOutput(", ");
                    }
                }
            }

            if (preserveNewLines) {
                this.indenter.decreaseIndent();
            }

            if (preserveNewLines && !this.isOnSameLine(parent.end(), list.nonSeparatorAt(list.nonSeparatorCount() - 1).end())) {
                this.writeLineToOutput("");
                this.emitIndent();
            } else {
                this.writeToOutput(buffer);
            }
        };

        Emitter.prototype.emitList = function (list, useNewLineSeparator, startInclusive, endExclusive) {
            if (typeof useNewLineSeparator === "undefined") { useNewLineSeparator = true; }
            if (typeof startInclusive === "undefined") { startInclusive = 0; }
            if (typeof endExclusive === "undefined") { endExclusive = list.childCount(); }
            if (list === null) {
                return;
            }

            this.emitComments(list, true);
            var lastEmittedNode = null;

            for (var i = startInclusive; i < endExclusive; i++) {
                var node = list.childAt(i);

                if (this.shouldEmit(node)) {
                    this.emitSpaceBetweenConstructs(lastEmittedNode, node);

                    this.emitJavascript(node, true);
                    if (useNewLineSeparator) {
                        this.writeLineToOutput("");
                    }

                    lastEmittedNode = node;
                }
            }

            this.emitComments(list, false);
        };

        Emitter.prototype.emitSeparatedList = function (list, useNewLineSeparator, startInclusive, endExclusive) {
            if (typeof useNewLineSeparator === "undefined") { useNewLineSeparator = true; }
            if (typeof startInclusive === "undefined") { startInclusive = 0; }
            if (typeof endExclusive === "undefined") { endExclusive = list.nonSeparatorCount(); }
            if (list === null) {
                return;
            }

            this.emitComments(list, true);
            var lastEmittedNode = null;

            for (var i = startInclusive; i < endExclusive; i++) {
                var node = list.nonSeparatorAt(i);

                if (this.shouldEmit(node)) {
                    this.emitSpaceBetweenConstructs(lastEmittedNode, node);

                    this.emitJavascript(node, true);
                    if (useNewLineSeparator) {
                        this.writeLineToOutput("");
                    }

                    lastEmittedNode = node;
                }
            }

            this.emitComments(list, false);
        };

        Emitter.prototype.isDirectivePrologueElement = function (node) {
            if (node.kind() === 149 /* ExpressionStatement */) {
                var exprStatement = node;
                return exprStatement.expression.kind() === 14 /* StringLiteral */;
            }

            return false;
        };

        Emitter.prototype.emitSpaceBetweenConstructs = function (node1, node2) {
            if (node1 === null || node2 === null) {
                return;
            }

            if (node1.start() === -1 || node1.end() === -1 || node2.start() === -1 || node2.end() === -1) {
                return;
            }

            var lineMap = this.document.lineMap();
            var node1EndLine = lineMap.getLineNumberFromPosition(node1.end());
            var node2StartLine = lineMap.getLineNumberFromPosition(node2.start());

            if ((node2StartLine - node1EndLine) > 1) {
                this.writeLineToOutput("", true);
            }
        };

        Emitter.prototype.getDetachedComments = function (element) {
            var preComments = element.preComments();
            if (preComments) {
                var lineMap = this.document.lineMap();

                var detachedComments = [];
                var lastComment = null;

                for (var i = 0, n = preComments.length; i < n; i++) {
                    var comment = preComments[i];

                    if (lastComment) {
                        var lastCommentLine = lineMap.getLineNumberFromPosition(lastComment.end());
                        var commentLine = lineMap.getLineNumberFromPosition(comment.start());

                        if (commentLine >= lastCommentLine + 2) {
                            return detachedComments;
                        }
                    }

                    detachedComments.push(comment);
                    lastComment = comment;
                }

                var lastCommentLine = lineMap.getLineNumberFromPosition(TypeScript.ArrayUtilities.last(detachedComments).end());
                var astLine = lineMap.getLineNumberFromPosition(element.start());
                if (astLine >= lastCommentLine + 2) {
                    return detachedComments;
                }
            }

            return [];
        };

        Emitter.prototype.emitPossibleCopyrightHeaders = function (script) {
            this.emitDetachedComments(script.moduleElements);
        };

        Emitter.prototype.emitDetachedComments = function (list) {
            if (list.childCount() > 0) {
                var firstElement = list.childAt(0);

                this.detachedCommentsElement = firstElement;
                this.emitCommentsArray(this.getDetachedComments(this.detachedCommentsElement), false);
            }
        };

        Emitter.prototype.emitScriptElements = function (sourceUnit) {
            var list = sourceUnit.moduleElements;

            this.emitPossibleCopyrightHeaders(sourceUnit);

            for (var i = 0, n = list.childCount(); i < n; i++) {
                var node = list.childAt(i);

                if (!this.isDirectivePrologueElement(node)) {
                    break;
                }

                this.emitJavascript(node, true);
                this.writeLineToOutput("");
            }

            this.emitPrologue(sourceUnit);

            var isExternalModule = this.document.isExternalModule();
            var isNonElidedExternalModule = isExternalModule && !TypeScript.ASTHelpers.scriptIsElided(sourceUnit);
            if (isNonElidedExternalModule) {
                this.recordSourceMappingStart(sourceUnit);

                if (this.emitOptions.compilationSettings().moduleGenTarget() === 2 /* Asynchronous */) {
                    var dependencyList = "[\"require\", \"exports\"";
                    var importList = "require, exports";

                    var importAndDependencyList = this.getModuleImportAndDependencyList(sourceUnit);
                    importList += importAndDependencyList.importList;
                    dependencyList += importAndDependencyList.dependencyList + "]";

                    this.writeLineToOutput("define(" + dependencyList + "," + " function(" + importList + ") {");
                }
            }

            if (isExternalModule) {
                var temp = this.setContainer(2 /* DynamicModule */);

                var svModuleName = this.moduleName;
                this.moduleName = sourceUnit.fileName();
                if (TypeScript.isTSFile(this.moduleName)) {
                    this.moduleName = this.moduleName.substring(0, this.moduleName.length - ".ts".length);
                }

                this.setExportAssignment(null);

                if (this.emitOptions.compilationSettings().moduleGenTarget() === 2 /* Asynchronous */) {
                    this.indenter.increaseIndent();
                }

                var externalModule = this.semanticInfoChain.getDeclForAST(this.document.sourceUnit());

                if (TypeScript.hasFlag(externalModule.flags, 262144 /* MustCaptureThis */)) {
                    this.writeCaptureThisStatement(sourceUnit);
                }

                this.pushDecl(externalModule);
            }

            this.emitList(list, true, i, n);

            if (isExternalModule) {
                if (this.emitOptions.compilationSettings().moduleGenTarget() === 2 /* Asynchronous */) {
                    this.indenter.decreaseIndent();
                }

                if (isNonElidedExternalModule) {
                    var exportAssignment = this.getExportAssignment();
                    var exportAssignmentIdentifierText = exportAssignment ? exportAssignment.identifier.text() : null;
                    var exportAssignmentValueSymbol = externalModule.getSymbol().getExportAssignedValueSymbol();

                    if (this.emitOptions.compilationSettings().moduleGenTarget() === 2 /* Asynchronous */) {
                        if (exportAssignmentIdentifierText && exportAssignmentValueSymbol && !(exportAssignmentValueSymbol.kind & 58720272 /* SomeTypeReference */)) {
                            this.indenter.increaseIndent();
                            this.emitIndent();
                            this.writeToOutputWithSourceMapRecord("return " + exportAssignmentIdentifierText, exportAssignment);
                            this.writeLineToOutput(";");
                            this.indenter.decreaseIndent();
                        }
                        this.writeToOutput("});");
                    } else if (exportAssignmentIdentifierText && exportAssignmentValueSymbol && !(exportAssignmentValueSymbol.kind & 58720272 /* SomeTypeReference */)) {
                        this.emitIndent();
                        this.writeToOutputWithSourceMapRecord("module.exports = " + exportAssignmentIdentifierText, exportAssignment);
                        this.writeToOutput(";");
                    }

                    this.recordSourceMappingEnd(sourceUnit);
                    this.writeLineToOutput("");
                }

                this.setContainer(temp);
                this.moduleName = svModuleName;
                this.popDecl(externalModule);
            }
        };

        Emitter.prototype.emitConstructorStatements = function (funcDecl) {
            var list = funcDecl.block.statements;

            if (list === null) {
                return;
            }

            this.emitComments(list, true);

            var emitPropertyAssignmentsAfterSuperCall = TypeScript.ASTHelpers.getExtendsHeritageClause(this.thisClassNode.heritageClauses) !== null;
            var propertyAssignmentIndex = emitPropertyAssignmentsAfterSuperCall ? 1 : 0;
            var lastEmittedNode = null;

            for (var i = 0, n = list.childCount(); i < n; i++) {
                if (i === propertyAssignmentIndex) {
                    this.emitParameterPropertyAndMemberVariableAssignments();
                }

                var node = list.childAt(i);

                if (this.shouldEmit(node)) {
                    this.emitSpaceBetweenConstructs(lastEmittedNode, node);

                    this.emitJavascript(node, true);
                    this.writeLineToOutput("");

                    lastEmittedNode = node;
                }
            }

            if (i === propertyAssignmentIndex) {
                this.emitParameterPropertyAndMemberVariableAssignments();
            }

            this.emitComments(list, false);
        };

        Emitter.prototype.emitJavascript = function (ast, startLine) {
            if (ast === null) {
                return;
            }

            if (startLine && this.indenter.indentAmt > 0) {
                this.emitIndent();
            }

            this.emit(ast);
        };

        Emitter.prototype.emitAccessorMemberDeclaration = function (funcDecl, name, className, isProto) {
            if (funcDecl.kind() !== 139 /* GetAccessor */) {
                var accessorSymbol = TypeScript.PullHelpers.getAccessorSymbol(funcDecl, this.semanticInfoChain);
                if (accessorSymbol.getGetter()) {
                    return;
                }
            }

            this.emitIndent();
            this.recordSourceMappingStart(funcDecl);

            this.writeToOutput("Object.defineProperty(" + className);
            if (isProto) {
                this.writeToOutput(".prototype, ");
            } else {
                this.writeToOutput(", ");
            }

            var functionName = name.text();
            if (TypeScript.isQuoted(functionName)) {
                this.writeToOutput(functionName);
            } else {
                this.writeToOutput('"' + functionName + '"');
            }

            this.writeLineToOutput(", {");

            this.indenter.increaseIndent();

            var accessors = TypeScript.PullHelpers.getGetterAndSetterFunction(funcDecl, this.semanticInfoChain);
            if (accessors.getter) {
                this.emitIndent();
                this.recordSourceMappingStart(accessors.getter);
                this.emitComments(accessors.getter, true);
                this.writeToOutput("get: ");
                this.emitAccessorBody(accessors.getter, accessors.getter.parameterList, accessors.getter.block);
                this.writeLineToOutput(",");
            }

            if (accessors.setter) {
                this.emitIndent();
                this.recordSourceMappingStart(accessors.setter);
                this.emitComments(accessors.setter, true);
                this.writeToOutput("set: ");
                this.emitAccessorBody(accessors.setter, accessors.setter.parameterList, accessors.setter.block);
                this.writeLineToOutput(",");
            }

            this.emitIndent();
            this.writeLineToOutput("enumerable: true,");
            this.emitIndent();
            this.writeLineToOutput("configurable: true");
            this.indenter.decreaseIndent();
            this.emitIndent();
            this.writeLineToOutput("});");
            this.recordSourceMappingEnd(funcDecl);
        };

        Emitter.prototype.emitAccessorBody = function (funcDecl, parameterList, block) {
            var pullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            this.pushDecl(pullDecl);

            this.recordSourceMappingStart(funcDecl);
            this.writeToOutput("function ");

            this.writeToOutput("(");

            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(parameterList);
            this.emitFunctionParameters(parameters);
            this.writeToOutput(")");

            this.emitFunctionBodyStatements(null, funcDecl, parameters, block, null);

            this.recordSourceMappingEnd(funcDecl);

            this.recordSourceMappingEnd(funcDecl);
            this.popDecl(pullDecl);
        };

        Emitter.prototype.emitClass = function (classDecl) {
            var pullDecl = this.semanticInfoChain.getDeclForAST(classDecl);
            this.pushDecl(pullDecl);

            var svClassNode = this.thisClassNode;
            this.thisClassNode = classDecl;
            var className = classDecl.identifier.text();
            this.emitComments(classDecl, true);
            var temp = this.setContainer(3 /* Class */);

            this.recordSourceMappingStart(classDecl);
            this.writeToOutput("var " + className);

            var hasBaseClass = TypeScript.ASTHelpers.getExtendsHeritageClause(classDecl.heritageClauses) !== null;
            var baseTypeReference = null;
            var varDecl = null;

            if (hasBaseClass) {
                this.writeLineToOutput(" = (function (_super) {");
            } else {
                this.writeLineToOutput(" = (function () {");
            }

            this.recordSourceMappingNameStart(className);
            this.indenter.increaseIndent();

            if (hasBaseClass) {
                baseTypeReference = TypeScript.ASTHelpers.getExtendsHeritageClause(classDecl.heritageClauses).typeNames.nonSeparatorAt(0);
                this.emitIndent();
                this.writeToOutputWithSourceMapRecord("__extends(" + className + ", _super)", baseTypeReference);
                this.writeLineToOutput(";");
            }

            this.emitIndent();

            var constrDecl = getLastConstructor(classDecl);

            if (constrDecl) {
                this.emit(constrDecl);
                this.writeLineToOutput("");
            } else {
                this.recordSourceMappingStart(classDecl);

                this.indenter.increaseIndent();
                this.writeLineToOutput("function " + classDecl.identifier.text() + "() {");
                this.recordSourceMappingNameStart("constructor");
                if (hasBaseClass) {
                    this.emitIndent();
                    this.writeToOutputWithSourceMapRecord("_super.apply(this, arguments)", baseTypeReference);
                    this.writeLineToOutput(";");
                }

                if (this.shouldCaptureThis(classDecl)) {
                    this.writeCaptureThisStatement(classDecl);
                }

                this.emitParameterPropertyAndMemberVariableAssignments();

                this.indenter.decreaseIndent();
                this.emitIndent();
                this.writeToOutputWithSourceMapRecord("}", classDecl.closeBraceToken);
                this.writeLineToOutput("");

                this.recordSourceMappingNameEnd();
                this.recordSourceMappingEnd(classDecl);
            }

            this.emitClassMembers(classDecl);

            this.emitIndent();
            this.writeToOutputWithSourceMapRecord("return " + className + ";", classDecl.closeBraceToken);
            this.writeLineToOutput("");
            this.indenter.decreaseIndent();
            this.emitIndent();
            this.writeToOutputWithSourceMapRecord("}", classDecl.closeBraceToken);
            this.recordSourceMappingNameEnd();
            this.recordSourceMappingStart(classDecl);
            this.writeToOutput(")(");
            if (hasBaseClass) {
                this.emitJavascript(baseTypeReference, false);
            }
            this.writeToOutput(");");
            this.recordSourceMappingEnd(classDecl);

            if ((temp === 1 /* Module */ || temp === 2 /* DynamicModule */) && TypeScript.hasFlag(pullDecl.flags, 1 /* Exported */)) {
                this.writeLineToOutput("");
                this.emitIndent();
                var modName = temp === 1 /* Module */ ? this.moduleName : "exports";
                this.writeToOutputWithSourceMapRecord(modName + "." + className + " = " + className + ";", classDecl);
            }

            this.recordSourceMappingEnd(classDecl);
            this.emitComments(classDecl, false);
            this.setContainer(temp);
            this.thisClassNode = svClassNode;

            this.popDecl(pullDecl);
        };

        Emitter.prototype.emitClassMembers = function (classDecl) {
            var lastEmittedMember = null;

            for (var i = 0, n = classDecl.classElements.childCount(); i < n; i++) {
                var memberDecl = classDecl.classElements.childAt(i);

                if (memberDecl.kind() === 139 /* GetAccessor */) {
                    this.emitSpaceBetweenConstructs(lastEmittedMember, memberDecl);
                    var getter = memberDecl;
                    this.emitAccessorMemberDeclaration(getter, getter.propertyName, classDecl.identifier.text(), !TypeScript.hasModifier(getter.modifiers, 16 /* Static */));
                    lastEmittedMember = memberDecl;
                } else if (memberDecl.kind() === 140 /* SetAccessor */) {
                    this.emitSpaceBetweenConstructs(lastEmittedMember, memberDecl);
                    var setter = memberDecl;
                    this.emitAccessorMemberDeclaration(setter, setter.propertyName, classDecl.identifier.text(), !TypeScript.hasModifier(setter.modifiers, 16 /* Static */));
                    lastEmittedMember = memberDecl;
                } else if (memberDecl.kind() === 135 /* MemberFunctionDeclaration */) {
                    var memberFunction = memberDecl;

                    if (memberFunction.block) {
                        this.emitSpaceBetweenConstructs(lastEmittedMember, memberDecl);

                        this.emitClassMemberFunctionDeclaration(classDecl, memberFunction);
                        lastEmittedMember = memberDecl;
                    }
                }
            }

            for (var i = 0, n = classDecl.classElements.childCount(); i < n; i++) {
                var memberDecl = classDecl.classElements.childAt(i);

                if (memberDecl.kind() === 136 /* MemberVariableDeclaration */) {
                    var varDecl = memberDecl;

                    if (TypeScript.hasModifier(varDecl.modifiers, 16 /* Static */) && varDecl.variableDeclarator.equalsValueClause) {
                        this.emitSpaceBetweenConstructs(lastEmittedMember, varDecl);

                        this.emitIndent();
                        this.recordSourceMappingStart(varDecl);

                        var varDeclName = varDecl.variableDeclarator.propertyName.text();
                        if (TypeScript.isQuoted(varDeclName) || varDecl.variableDeclarator.propertyName.kind() !== 11 /* IdentifierName */) {
                            this.writeToOutput(classDecl.identifier.text() + "[" + varDeclName + "]");
                        } else {
                            this.writeToOutput(classDecl.identifier.text() + "." + varDeclName);
                        }

                        this.emit(varDecl.variableDeclarator.equalsValueClause);

                        this.recordSourceMappingEnd(varDecl);
                        this.writeLineToOutput(";");

                        lastEmittedMember = varDecl;
                    }
                }
            }
        };

        Emitter.prototype.emitClassMemberFunctionDeclaration = function (classDecl, funcDecl) {
            this.emitIndent();
            this.recordSourceMappingStart(funcDecl);
            this.emitComments(funcDecl, true);
            var functionName = funcDecl.propertyName.text();

            this.writeToOutput(classDecl.identifier.text());

            if (!TypeScript.hasModifier(funcDecl.modifiers, 16 /* Static */)) {
                this.writeToOutput(".prototype");
            }

            if (TypeScript.isQuoted(functionName) || funcDecl.propertyName.kind() !== 11 /* IdentifierName */) {
                this.writeToOutput("[" + functionName + "] = ");
            } else {
                this.writeToOutput("." + functionName + " = ");
            }

            var pullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            this.pushDecl(pullDecl);

            this.recordSourceMappingStart(funcDecl);
            this.writeToOutput("function ");

            this.emitParameterList(funcDecl.callSignature.parameterList);

            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList);
            this.emitFunctionBodyStatements(funcDecl.propertyName.text(), funcDecl, parameters, funcDecl.block, null);

            this.recordSourceMappingEnd(funcDecl);

            this.emitComments(funcDecl, false);

            this.recordSourceMappingEnd(funcDecl);
            this.popDecl(pullDecl);

            this.writeLineToOutput(";");
        };

        Emitter.prototype.requiresExtendsBlock = function (moduleElements) {
            for (var i = 0, n = moduleElements.childCount(); i < n; i++) {
                var moduleElement = moduleElements.childAt(i);

                if (moduleElement.kind() === 130 /* ModuleDeclaration */) {
                    var moduleAST = moduleElement;

                    if (!TypeScript.hasModifier(moduleAST.modifiers, 8 /* Ambient */) && this.requiresExtendsBlock(moduleAST.moduleElements)) {
                        return true;
                    }
                } else if (moduleElement.kind() === 131 /* ClassDeclaration */) {
                    var classDeclaration = moduleElement;

                    if (!TypeScript.hasModifier(classDeclaration.modifiers, 8 /* Ambient */) && TypeScript.ASTHelpers.getExtendsHeritageClause(classDeclaration.heritageClauses) !== null) {
                        return true;
                    }
                }
            }

            return false;
        };

        Emitter.prototype.emitPrologue = function (sourceUnit) {
            if (!this.extendsPrologueEmitted) {
                if (this.requiresExtendsBlock(sourceUnit.moduleElements)) {
                    this.extendsPrologueEmitted = true;
                    this.writeLineToOutput("var __extends = this.__extends || function (d, b) {");
                    this.writeLineToOutput("    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];");
                    this.writeLineToOutput("    function __() { this.constructor = d; }");
                    this.writeLineToOutput("    __.prototype = b.prototype;");
                    this.writeLineToOutput("    d.prototype = new __();");
                    this.writeLineToOutput("};");
                }
            }

            if (!this.globalThisCapturePrologueEmitted) {
                if (this.shouldCaptureThis(sourceUnit)) {
                    this.globalThisCapturePrologueEmitted = true;
                    this.writeLineToOutput(this.captureThisStmtString);
                }
            }
        };

        Emitter.prototype.emitThis = function () {
            if (!this.inWithBlock && this.inArrowFunction) {
                this.writeToOutput("_this");
            } else {
                this.writeToOutput("this");
            }
        };

        Emitter.prototype.emitBlockOrStatement = function (node) {
            if (node.kind() === 146 /* Block */) {
                this.emit(node);
            } else {
                this.writeLineToOutput("");
                this.indenter.increaseIndent();
                this.emitJavascript(node, true);
                this.indenter.decreaseIndent();
            }
        };

        Emitter.prototype.emitLiteralExpression = function (expression) {
            switch (expression.kind()) {
                case 32 /* NullKeyword */:
                    this.writeToOutputWithSourceMapRecord("null", expression);
                    break;
                case 24 /* FalseKeyword */:
                    this.writeToOutputWithSourceMapRecord("false", expression);
                    break;
                case 37 /* TrueKeyword */:
                    this.writeToOutputWithSourceMapRecord("true", expression);
                    break;
                default:
                    throw TypeScript.Errors.abstract();
            }
        };

        Emitter.prototype.emitThisExpression = function (expression) {
            if (!this.inWithBlock && this.inArrowFunction) {
                this.writeToOutputWithSourceMapRecord("_this", expression);
            } else {
                this.writeToOutputWithSourceMapRecord("this", expression);
            }
        };

        Emitter.prototype.emitSuperExpression = function (expression) {
            this.writeToOutputWithSourceMapRecord("_super.prototype", expression);
        };

        Emitter.prototype.emitParenthesizedExpression = function (parenthesizedExpression) {
            var omitParentheses = false;

            if (parenthesizedExpression.expression.kind() === 220 /* CastExpression */ && parenthesizedExpression.openParenTrailingComments === null) {
                var castedExpression = parenthesizedExpression.expression.expression;

                while (castedExpression.kind() == 220 /* CastExpression */) {
                    castedExpression = castedExpression.expression;
                }

                switch (castedExpression.kind()) {
                    case 217 /* ParenthesizedExpression */:
                    case 11 /* IdentifierName */:
                    case 32 /* NullKeyword */:
                    case 35 /* ThisKeyword */:
                    case 14 /* StringLiteral */:
                    case 13 /* NumericLiteral */:
                    case 12 /* RegularExpressionLiteral */:
                    case 37 /* TrueKeyword */:
                    case 24 /* FalseKeyword */:
                    case 214 /* ArrayLiteralExpression */:
                    case 215 /* ObjectLiteralExpression */:
                    case 212 /* MemberAccessExpression */:
                    case 221 /* ElementAccessExpression */:
                        omitParentheses = true;
                        break;

                    case 213 /* InvocationExpression */:
                        if (parenthesizedExpression.parent.kind() !== 216 /* ObjectCreationExpression */) {
                            omitParentheses = true;
                        }

                        break;
                }
            }

            if (omitParentheses) {
                this.emit(parenthesizedExpression.expression);
            } else {
                this.recordSourceMappingStart(parenthesizedExpression);
                this.writeToOutput("(");
                this.emitCommentsArray(parenthesizedExpression.openParenTrailingComments, false);
                this.emit(parenthesizedExpression.expression);
                this.writeToOutput(")");
                this.recordSourceMappingEnd(parenthesizedExpression);
            }
        };

        Emitter.prototype.emitCastExpression = function (expression) {
            this.emit(expression.expression);
        };

        Emitter.prototype.emitPrefixUnaryExpression = function (expression) {
            var nodeType = expression.kind();

            this.recordSourceMappingStart(expression);
            switch (nodeType) {
                case 167 /* LogicalNotExpression */:
                    this.writeToOutput("!");
                    this.emit(expression.operand);
                    break;
                case 166 /* BitwiseNotExpression */:
                    this.writeToOutput("~");
                    this.emit(expression.operand);
                    break;
                case 165 /* NegateExpression */:
                    this.writeToOutput("-");
                    if (expression.operand.kind() === 165 /* NegateExpression */ || expression.operand.kind() === 169 /* PreDecrementExpression */) {
                        this.writeToOutput(" ");
                    }
                    this.emit(expression.operand);
                    break;
                case 164 /* PlusExpression */:
                    this.writeToOutput("+");
                    if (expression.operand.kind() === 164 /* PlusExpression */ || expression.operand.kind() === 168 /* PreIncrementExpression */) {
                        this.writeToOutput(" ");
                    }
                    this.emit(expression.operand);
                    break;
                case 168 /* PreIncrementExpression */:
                    this.writeToOutput("++");
                    this.emit(expression.operand);
                    break;
                case 169 /* PreDecrementExpression */:
                    this.writeToOutput("--");
                    this.emit(expression.operand);
                    break;
                default:
                    throw TypeScript.Errors.abstract();
            }

            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitPostfixUnaryExpression = function (expression) {
            var nodeType = expression.kind();

            this.recordSourceMappingStart(expression);
            switch (nodeType) {
                case 210 /* PostIncrementExpression */:
                    this.emit(expression.operand);
                    this.writeToOutput("++");
                    break;
                case 211 /* PostDecrementExpression */:
                    this.emit(expression.operand);
                    this.writeToOutput("--");
                    break;
                default:
                    throw TypeScript.Errors.abstract();
            }

            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitTypeOfExpression = function (expression) {
            this.recordSourceMappingStart(expression);
            this.writeToOutput("typeof ");
            this.emit(expression.expression);
            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitDeleteExpression = function (expression) {
            this.recordSourceMappingStart(expression);
            this.writeToOutput("delete ");
            this.emit(expression.expression);
            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitVoidExpression = function (expression) {
            this.recordSourceMappingStart(expression);
            this.writeToOutput("void ");
            this.emit(expression.expression);
            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.canEmitDottedNameMemberAccessExpression = function (expression) {
            var memberExpressionNodeType = expression.expression.kind();

            if (memberExpressionNodeType === 11 /* IdentifierName */ || memberExpressionNodeType == 212 /* MemberAccessExpression */) {
                var memberAccessSymbol = this.getSymbolForEmit(expression).symbol;
                var memberAccessExpressionSymbol = this.getSymbolForEmit(expression.expression).symbol;
                if (memberAccessSymbol && memberAccessExpressionSymbol && !this.semanticInfoChain.getAliasSymbolForAST(expression.expression) && (TypeScript.PullHelpers.symbolIsModule(memberAccessExpressionSymbol) || memberAccessExpressionSymbol.kind === 64 /* Enum */ || memberAccessExpressionSymbol.anyDeclHasFlag(32768 /* InitializedModule */ | 4096 /* Enum */))) {
                    var memberAccessSymbolKind = memberAccessSymbol.kind;
                    if (memberAccessSymbolKind === 4096 /* Property */ || memberAccessSymbolKind === 67108864 /* EnumMember */ || (memberAccessSymbol.anyDeclHasFlag(1 /* Exported */) && memberAccessSymbolKind === 512 /* Variable */ && !memberAccessSymbol.anyDeclHasFlag(32768 /* InitializedModule */ | 4096 /* Enum */)) || ((memberAccessSymbol.anyDeclHasFlag(1 /* Exported */) && !this.symbolIsUsedInItsEnclosingContainer(memberAccessSymbol)))) {
                        if (memberExpressionNodeType === 212 /* MemberAccessExpression */) {
                            return this.canEmitDottedNameMemberAccessExpression(expression.expression);
                        }

                        return true;
                    }
                }
            }

            return false;
        };

        Emitter.prototype.emitDottedNameMemberAccessExpression = function (expression) {
            this.recordSourceMappingStart(expression);
            if (expression.expression.kind() === 212 /* MemberAccessExpression */) {
                this.emitDottedNameMemberAccessExpressionRecurse(expression.expression);
            } else {
                this.emitName(expression.expression, true);
            }

            this.writeToOutput(".");
            this.emitName(expression.name, false);

            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitDottedNameMemberAccessExpressionRecurse = function (expression) {
            this.emitComments(expression, true);
            this.emitDottedNameMemberAccessExpression(expression);
            this.emitComments(expression, false);
        };

        Emitter.prototype.emitMemberAccessExpression = function (expression) {
            if (!this.tryEmitConstant(expression)) {
                if (this.canEmitDottedNameMemberAccessExpression(expression)) {
                    this.emitDottedNameMemberAccessExpression(expression);
                } else {
                    this.recordSourceMappingStart(expression);
                    this.emit(expression.expression);
                    this.writeToOutput(".");
                    this.emitName(expression.name, false);
                    this.recordSourceMappingEnd(expression);
                }
            }
        };

        Emitter.prototype.emitQualifiedName = function (name) {
            this.recordSourceMappingStart(name);

            this.emit(name.left);
            this.writeToOutput(".");
            this.emitName(name.right, false);

            this.recordSourceMappingEnd(name);
        };

        Emitter.prototype.emitBinaryExpression = function (expression) {
            this.recordSourceMappingStart(expression);
            switch (expression.kind()) {
                case 173 /* CommaExpression */:
                    this.emit(expression.left);
                    this.writeToOutput(", ");
                    this.emit(expression.right);
                    break;
                default: {
                    this.emit(expression.left);
                    var binOp = TypeScript.SyntaxFacts.getText(TypeScript.SyntaxFacts.getOperatorTokenFromBinaryExpression(expression.kind()));
                    if (binOp === "instanceof") {
                        this.writeToOutput(" instanceof ");
                    } else if (binOp === "in") {
                        this.writeToOutput(" in ");
                    } else {
                        this.writeToOutput(" " + binOp + " ");
                    }
                    this.emit(expression.right);
                }
            }
            this.recordSourceMappingEnd(expression);
        };

        Emitter.prototype.emitSimplePropertyAssignment = function (property) {
            this.recordSourceMappingStart(property);
            this.emit(property.propertyName);
            this.writeToOutput(": ");
            this.emit(property.expression);
            this.recordSourceMappingEnd(property);
        };

        Emitter.prototype.emitFunctionPropertyAssignment = function (funcProp) {
            this.recordSourceMappingStart(funcProp);

            this.emit(funcProp.propertyName);
            this.writeToOutput(": ");

            var pullFunctionDecl = this.semanticInfoChain.getDeclForAST(funcProp);

            var savedInArrowFunction = this.inArrowFunction;
            this.inArrowFunction = false;

            var temp = this.setContainer(5 /* Function */);
            var funcName = funcProp.propertyName;

            var pullDecl = this.semanticInfoChain.getDeclForAST(funcProp);
            this.pushDecl(pullDecl);

            this.recordSourceMappingStart(funcProp);
            this.writeToOutput("function ");

            this.writeToOutput("(");

            var parameters = TypeScript.ASTHelpers.parametersFromParameterList(funcProp.callSignature.parameterList);
            this.emitFunctionParameters(parameters);
            this.writeToOutput(")");

            this.emitFunctionBodyStatements(funcProp.propertyName.text(), funcProp, parameters, funcProp.block, null);

            this.recordSourceMappingEnd(funcProp);

            this.recordSourceMappingEnd(funcProp);

            this.emitComments(funcProp, false);

            this.popDecl(pullDecl);

            this.setContainer(temp);
            this.inArrowFunction = savedInArrowFunction;
        };

        Emitter.prototype.emitConditionalExpression = function (expression) {
            this.emit(expression.condition);
            this.writeToOutput(" ? ");
            this.emit(expression.whenTrue);
            this.writeToOutput(" : ");
            this.emit(expression.whenFalse);
        };

        Emitter.prototype.emitThrowStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("throw ");
            this.emit(statement.expression);
            this.recordSourceMappingEnd(statement);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitExpressionStatement = function (statement) {
            var isArrowExpression = statement.expression.kind() === 219 /* SimpleArrowFunctionExpression */ || statement.expression.kind() === 218 /* ParenthesizedArrowFunctionExpression */;

            this.recordSourceMappingStart(statement);
            if (isArrowExpression) {
                this.writeToOutput("(");
            }

            this.emit(statement.expression);

            if (isArrowExpression) {
                this.writeToOutput(")");
            }

            this.recordSourceMappingEnd(statement);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitLabeledStatement = function (statement) {
            this.writeToOutputWithSourceMapRecord(statement.identifier.text(), statement.identifier);
            this.writeLineToOutput(":");
            this.emitJavascript(statement.statement, true);
        };

        Emitter.prototype.emitBlock = function (block) {
            this.recordSourceMappingStart(block);
            this.writeLineToOutput(" {");
            this.indenter.increaseIndent();
            if (block.statements) {
                this.emitList(block.statements);
            }
            this.emitCommentsArray(block.closeBraceLeadingComments, false);
            this.indenter.decreaseIndent();
            this.emitIndent();
            this.writeToOutput("}");
            this.recordSourceMappingEnd(block);
        };

        Emitter.prototype.emitBreakStatement = function (jump) {
            this.recordSourceMappingStart(jump);
            this.writeToOutput("break");

            if (jump.identifier) {
                this.writeToOutput(" " + jump.identifier.text());
            }

            this.recordSourceMappingEnd(jump);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitContinueStatement = function (jump) {
            this.recordSourceMappingStart(jump);
            this.writeToOutput("continue");

            if (jump.identifier) {
                this.writeToOutput(" " + jump.identifier.text());
            }

            this.recordSourceMappingEnd(jump);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitWhileStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("while (");
            this.emit(statement.condition);
            this.writeToOutput(")");
            this.emitBlockOrStatement(statement.statement);
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitDoStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("do");
            this.emitBlockOrStatement(statement.statement);
            this.writeToOutputWithSourceMapRecord(" while", statement.whileKeyword);
            this.writeToOutput('(');
            this.emit(statement.condition);
            this.writeToOutput(")");
            this.recordSourceMappingEnd(statement);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitIfStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("if (");
            this.emit(statement.condition);
            this.writeToOutput(")");

            this.emitBlockOrStatement(statement.statement);

            if (statement.elseClause) {
                if (statement.statement.kind() !== 146 /* Block */) {
                    this.writeLineToOutput("");
                    this.emitIndent();
                } else {
                    this.writeToOutput(" ");
                }

                this.emit(statement.elseClause);
            }
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitElseClause = function (elseClause) {
            if (elseClause.statement.kind() === 147 /* IfStatement */) {
                this.writeToOutput("else ");
                this.emit(elseClause.statement);
            } else {
                this.writeToOutput("else");
                this.emitBlockOrStatement(elseClause.statement);
            }
        };

        Emitter.prototype.emitReturnStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            if (statement.expression) {
                this.writeToOutput("return ");
                this.emit(statement.expression);
            } else {
                this.writeToOutput("return");
            }
            this.recordSourceMappingEnd(statement);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitForInStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("for (");
            if (statement.left) {
                this.emit(statement.left);
            } else {
                this.emit(statement.variableDeclaration);
            }
            this.writeToOutput(" in ");
            this.emit(statement.expression);
            this.writeToOutput(")");
            this.emitBlockOrStatement(statement.statement);
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitForStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("for (");
            if (statement.variableDeclaration) {
                this.emit(statement.variableDeclaration);
            } else if (statement.initializer) {
                this.emit(statement.initializer);
            }

            this.writeToOutput("; ");
            this.emitJavascript(statement.condition, false);
            this.writeToOutput(";");
            if (statement.incrementor) {
                this.writeToOutput(" ");
                this.emitJavascript(statement.incrementor, false);
            }
            this.writeToOutput(")");
            this.emitBlockOrStatement(statement.statement);
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitWithStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("with (");
            if (statement.condition) {
                this.emit(statement.condition);
            }

            this.writeToOutput(")");
            var prevInWithBlock = this.inWithBlock;
            this.inWithBlock = true;
            this.emitBlockOrStatement(statement.statement);
            this.inWithBlock = prevInWithBlock;
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitSwitchStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("switch (");
            this.emit(statement.expression);
            this.recordSourceMappingStart(statement.closeParenToken);
            this.writeToOutput(")");
            this.recordSourceMappingEnd(statement.closeParenToken);
            this.writeLineToOutput(" {");
            this.indenter.increaseIndent();
            this.emitList(statement.switchClauses, false);
            this.indenter.decreaseIndent();
            this.emitIndent();
            this.writeToOutput("}");
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitCaseSwitchClause = function (clause) {
            this.recordSourceMappingStart(clause);
            this.writeToOutput("case ");
            this.emit(clause.expression);
            this.writeToOutput(":");

            this.emitSwitchClauseBody(clause.statements);
            this.recordSourceMappingEnd(clause);
        };

        Emitter.prototype.emitSwitchClauseBody = function (body) {
            if (body.childCount() === 1 && body.childAt(0).kind() === 146 /* Block */) {
                this.emit(body.childAt(0));
                this.writeLineToOutput("");
            } else {
                this.writeLineToOutput("");
                this.indenter.increaseIndent();
                this.emit(body);
                this.indenter.decreaseIndent();
            }
        };

        Emitter.prototype.emitDefaultSwitchClause = function (clause) {
            this.recordSourceMappingStart(clause);
            this.writeToOutput("default:");

            this.emitSwitchClauseBody(clause.statements);
            this.recordSourceMappingEnd(clause);
        };

        Emitter.prototype.emitTryStatement = function (statement) {
            this.recordSourceMappingStart(statement);
            this.writeToOutput("try ");
            this.emit(statement.block);
            this.emitJavascript(statement.catchClause, false);

            if (statement.finallyClause) {
                this.emit(statement.finallyClause);
            }
            this.recordSourceMappingEnd(statement);
        };

        Emitter.prototype.emitCatchClause = function (clause) {
            this.writeToOutput(" ");
            this.recordSourceMappingStart(clause);
            this.writeToOutput("catch (");
            this.emit(clause.identifier);
            this.writeToOutput(")");
            this.emit(clause.block);
            this.recordSourceMappingEnd(clause);
        };

        Emitter.prototype.emitFinallyClause = function (clause) {
            this.writeToOutput(" finally");
            this.emit(clause.block);
        };

        Emitter.prototype.emitDebuggerStatement = function (statement) {
            this.writeToOutputWithSourceMapRecord("debugger", statement);
            this.writeToOutput(";");
        };

        Emitter.prototype.emitNumericLiteral = function (literal) {
            this.writeToOutputWithSourceMapRecord(literal.text(), literal);
        };

        Emitter.prototype.emitRegularExpressionLiteral = function (literal) {
            this.writeToOutputWithSourceMapRecord(literal.text(), literal);
        };

        Emitter.prototype.emitStringLiteral = function (literal) {
            this.writeToOutputWithSourceMapRecord(literal.text(), literal);
        };

        Emitter.prototype.emitEqualsValueClause = function (clause) {
            this.writeToOutput(" = ");
            this.emit(clause.value);
        };

        Emitter.prototype.emitParameter = function (parameter) {
            this.writeToOutputWithSourceMapRecord(parameter.identifier.text(), parameter);
        };

        Emitter.prototype.emitConstructorDeclaration = function (declaration) {
            if (declaration.block) {
                this.emitConstructor(declaration);
            } else {
                this.emitComments(declaration, true, true);
            }
        };

        Emitter.prototype.shouldEmitFunctionDeclaration = function (declaration) {
            return declaration.preComments() !== null || (!TypeScript.hasModifier(declaration.modifiers, 8 /* Ambient */) && declaration.block !== null);
        };

        Emitter.prototype.emitFunctionDeclaration = function (declaration) {
            if (!TypeScript.hasModifier(declaration.modifiers, 8 /* Ambient */) && declaration.block !== null) {
                this.emitFunction(declaration);
            } else {
                this.emitComments(declaration, true, true);
            }
        };

        Emitter.prototype.emitSourceUnit = function (sourceUnit) {
            if (!this.document.isDeclareFile()) {
                var pullDecl = this.semanticInfoChain.getDeclForAST(sourceUnit);
                this.pushDecl(pullDecl);
                this.emitScriptElements(sourceUnit);
                this.popDecl(pullDecl);

                this.emitCommentsArray(sourceUnit.endOfFileTokenLeadingComments, false);
            }
        };

        Emitter.prototype.shouldEmitEnumDeclaration = function (declaration) {
            return declaration.preComments() !== null || !TypeScript.ASTHelpers.enumIsElided(declaration);
        };

        Emitter.prototype.emitEnumDeclaration = function (declaration) {
            if (!TypeScript.ASTHelpers.enumIsElided(declaration)) {
                this.emitComments(declaration, true);
                this.emitEnum(declaration);
                this.emitComments(declaration, false);
            } else {
                this.emitComments(declaration, true, true);
            }
        };

        Emitter.prototype.shouldEmitModuleDeclaration = function (declaration) {
            return declaration.preComments() !== null || !TypeScript.ASTHelpers.moduleIsElided(declaration);
        };

        Emitter.prototype.emitModuleDeclaration = function (declaration) {
            if (!TypeScript.ASTHelpers.moduleIsElided(declaration)) {
                this.emitModuleDeclarationWorker(declaration);
            } else {
                this.emitComments(declaration, true, true);
            }
        };

        Emitter.prototype.shouldEmitClassDeclaration = function (declaration) {
            return declaration.preComments() !== null || !TypeScript.hasModifier(declaration.modifiers, 8 /* Ambient */);
        };

        Emitter.prototype.emitClassDeclaration = function (declaration) {
            if (!TypeScript.hasModifier(declaration.modifiers, 8 /* Ambient */)) {
                this.emitClass(declaration);
            } else {
                this.emitComments(declaration, true, true);
            }
        };

        Emitter.prototype.shouldEmitInterfaceDeclaration = function (declaration) {
            return declaration.preComments() !== null;
        };

        Emitter.prototype.emitInterfaceDeclaration = function (declaration) {
            this.emitComments(declaration, true, true);
        };

        Emitter.prototype.firstVariableDeclarator = function (statement) {
            return statement.declaration.declarators.nonSeparatorAt(0);
        };

        Emitter.prototype.isNotAmbientOrHasInitializer = function (variableStatement) {
            return !TypeScript.hasModifier(variableStatement.modifiers, 8 /* Ambient */) || this.firstVariableDeclarator(variableStatement).equalsValueClause !== null;
        };

        Emitter.prototype.shouldEmitVariableStatement = function (statement) {
            return statement.preComments() !== null || this.isNotAmbientOrHasInitializer(statement);
        };

        Emitter.prototype.emitVariableStatement = function (statement) {
            if (this.isNotAmbientOrHasInitializer(statement)) {
                this.emitComments(statement, true);
                this.emit(statement.declaration);
                this.writeToOutput(";");
                this.emitComments(statement, false);
            } else {
                this.emitComments(statement, true, true);
            }
        };

        Emitter.prototype.emitGenericType = function (type) {
            this.emit(type.name);
        };

        Emitter.prototype.shouldEmit = function (ast) {
            if (!ast) {
                return false;
            }

            switch (ast.kind()) {
                case 133 /* ImportDeclaration */:
                    return this.shouldEmitImportDeclaration(ast);
                case 131 /* ClassDeclaration */:
                    return this.shouldEmitClassDeclaration(ast);
                case 128 /* InterfaceDeclaration */:
                    return this.shouldEmitInterfaceDeclaration(ast);
                case 129 /* FunctionDeclaration */:
                    return this.shouldEmitFunctionDeclaration(ast);
                case 130 /* ModuleDeclaration */:
                    return this.shouldEmitModuleDeclaration(ast);
                case 148 /* VariableStatement */:
                    return this.shouldEmitVariableStatement(ast);
                case 223 /* OmittedExpression */:
                    return false;
                case 132 /* EnumDeclaration */:
                    return this.shouldEmitEnumDeclaration(ast);
            }

            return true;
        };

        Emitter.prototype.emit = function (ast) {
            if (!ast) {
                return;
            }

            switch (ast.kind()) {
                case 2 /* SeparatedList */:
                    return this.emitSeparatedList(ast);
                case 1 /* List */:
                    return this.emitList(ast);
                case 120 /* SourceUnit */:
                    return this.emitSourceUnit(ast);
                case 133 /* ImportDeclaration */:
                    return this.emitImportDeclaration(ast);
                case 134 /* ExportAssignment */:
                    return this.setExportAssignment(ast);
                case 131 /* ClassDeclaration */:
                    return this.emitClassDeclaration(ast);
                case 128 /* InterfaceDeclaration */:
                    return this.emitInterfaceDeclaration(ast);
                case 11 /* IdentifierName */:
                    return this.emitName(ast, true);
                case 225 /* VariableDeclarator */:
                    return this.emitVariableDeclarator(ast);
                case 219 /* SimpleArrowFunctionExpression */:
                    return this.emitSimpleArrowFunctionExpression(ast);
                case 218 /* ParenthesizedArrowFunctionExpression */:
                    return this.emitParenthesizedArrowFunctionExpression(ast);
                case 129 /* FunctionDeclaration */:
                    return this.emitFunctionDeclaration(ast);
                case 130 /* ModuleDeclaration */:
                    return this.emitModuleDeclaration(ast);
                case 224 /* VariableDeclaration */:
                    return this.emitVariableDeclaration(ast);
                case 126 /* GenericType */:
                    return this.emitGenericType(ast);
                case 137 /* ConstructorDeclaration */:
                    return this.emitConstructorDeclaration(ast);
                case 132 /* EnumDeclaration */:
                    return this.emitEnumDeclaration(ast);
                case 243 /* EnumElement */:
                    return this.emitEnumElement(ast);
                case 222 /* FunctionExpression */:
                    return this.emitFunctionExpression(ast);
                case 148 /* VariableStatement */:
                    return this.emitVariableStatement(ast);
            }

            this.emitComments(ast, true);
            this.emitWorker(ast);
            this.emitComments(ast, false);
        };

        Emitter.prototype.emitWorker = function (ast) {
            if (!ast) {
                return;
            }

            switch (ast.kind()) {
                case 13 /* NumericLiteral */:
                    return this.emitNumericLiteral(ast);
                case 12 /* RegularExpressionLiteral */:
                    return this.emitRegularExpressionLiteral(ast);
                case 14 /* StringLiteral */:
                    return this.emitStringLiteral(ast);
                case 24 /* FalseKeyword */:
                case 32 /* NullKeyword */:
                case 37 /* TrueKeyword */:
                    return this.emitLiteralExpression(ast);
                case 35 /* ThisKeyword */:
                    return this.emitThisExpression(ast);
                case 50 /* SuperKeyword */:
                    return this.emitSuperExpression(ast);
                case 217 /* ParenthesizedExpression */:
                    return this.emitParenthesizedExpression(ast);
                case 214 /* ArrayLiteralExpression */:
                    return this.emitArrayLiteralExpression(ast);
                case 211 /* PostDecrementExpression */:
                case 210 /* PostIncrementExpression */:
                    return this.emitPostfixUnaryExpression(ast);
                case 167 /* LogicalNotExpression */:
                case 166 /* BitwiseNotExpression */:
                case 165 /* NegateExpression */:
                case 164 /* PlusExpression */:
                case 168 /* PreIncrementExpression */:
                case 169 /* PreDecrementExpression */:
                    return this.emitPrefixUnaryExpression(ast);
                case 213 /* InvocationExpression */:
                    return this.emitInvocationExpression(ast);
                case 221 /* ElementAccessExpression */:
                    return this.emitElementAccessExpression(ast);
                case 212 /* MemberAccessExpression */:
                    return this.emitMemberAccessExpression(ast);
                case 121 /* QualifiedName */:
                    return this.emitQualifiedName(ast);
                case 173 /* CommaExpression */:
                case 174 /* AssignmentExpression */:
                case 175 /* AddAssignmentExpression */:
                case 176 /* SubtractAssignmentExpression */:
                case 177 /* MultiplyAssignmentExpression */:
                case 178 /* DivideAssignmentExpression */:
                case 179 /* ModuloAssignmentExpression */:
                case 180 /* AndAssignmentExpression */:
                case 181 /* ExclusiveOrAssignmentExpression */:
                case 182 /* OrAssignmentExpression */:
                case 183 /* LeftShiftAssignmentExpression */:
                case 184 /* SignedRightShiftAssignmentExpression */:
                case 185 /* UnsignedRightShiftAssignmentExpression */:
                case 187 /* LogicalOrExpression */:
                case 188 /* LogicalAndExpression */:
                case 189 /* BitwiseOrExpression */:
                case 190 /* BitwiseExclusiveOrExpression */:
                case 191 /* BitwiseAndExpression */:
                case 192 /* EqualsWithTypeConversionExpression */:
                case 193 /* NotEqualsWithTypeConversionExpression */:
                case 194 /* EqualsExpression */:
                case 195 /* NotEqualsExpression */:
                case 196 /* LessThanExpression */:
                case 197 /* GreaterThanExpression */:
                case 198 /* LessThanOrEqualExpression */:
                case 199 /* GreaterThanOrEqualExpression */:
                case 200 /* InstanceOfExpression */:
                case 201 /* InExpression */:
                case 202 /* LeftShiftExpression */:
                case 203 /* SignedRightShiftExpression */:
                case 204 /* UnsignedRightShiftExpression */:
                case 205 /* MultiplyExpression */:
                case 206 /* DivideExpression */:
                case 207 /* ModuloExpression */:
                case 208 /* AddExpression */:
                case 209 /* SubtractExpression */:
                    return this.emitBinaryExpression(ast);
                case 186 /* ConditionalExpression */:
                    return this.emitConditionalExpression(ast);
                case 232 /* EqualsValueClause */:
                    return this.emitEqualsValueClause(ast);
                case 242 /* Parameter */:
                    return this.emitParameter(ast);
                case 146 /* Block */:
                    return this.emitBlock(ast);
                case 235 /* ElseClause */:
                    return this.emitElseClause(ast);
                case 147 /* IfStatement */:
                    return this.emitIfStatement(ast);
                case 149 /* ExpressionStatement */:
                    return this.emitExpressionStatement(ast);
                case 139 /* GetAccessor */:
                    return this.emitGetAccessor(ast);
                case 140 /* SetAccessor */:
                    return this.emitSetAccessor(ast);
                case 157 /* ThrowStatement */:
                    return this.emitThrowStatement(ast);
                case 150 /* ReturnStatement */:
                    return this.emitReturnStatement(ast);
                case 216 /* ObjectCreationExpression */:
                    return this.emitObjectCreationExpression(ast);
                case 151 /* SwitchStatement */:
                    return this.emitSwitchStatement(ast);
                case 233 /* CaseSwitchClause */:
                    return this.emitCaseSwitchClause(ast);
                case 234 /* DefaultSwitchClause */:
                    return this.emitDefaultSwitchClause(ast);
                case 152 /* BreakStatement */:
                    return this.emitBreakStatement(ast);
                case 153 /* ContinueStatement */:
                    return this.emitContinueStatement(ast);
                case 154 /* ForStatement */:
                    return this.emitForStatement(ast);
                case 155 /* ForInStatement */:
                    return this.emitForInStatement(ast);
                case 158 /* WhileStatement */:
                    return this.emitWhileStatement(ast);
                case 163 /* WithStatement */:
                    return this.emitWithStatement(ast);
                case 220 /* CastExpression */:
                    return this.emitCastExpression(ast);
                case 215 /* ObjectLiteralExpression */:
                    return this.emitObjectLiteralExpression(ast);
                case 240 /* SimplePropertyAssignment */:
                    return this.emitSimplePropertyAssignment(ast);
                case 241 /* FunctionPropertyAssignment */:
                    return this.emitFunctionPropertyAssignment(ast);
                case 156 /* EmptyStatement */:
                    return this.writeToOutputWithSourceMapRecord(";", ast);
                case 159 /* TryStatement */:
                    return this.emitTryStatement(ast);
                case 236 /* CatchClause */:
                    return this.emitCatchClause(ast);
                case 237 /* FinallyClause */:
                    return this.emitFinallyClause(ast);
                case 160 /* LabeledStatement */:
                    return this.emitLabeledStatement(ast);
                case 161 /* DoStatement */:
                    return this.emitDoStatement(ast);
                case 171 /* TypeOfExpression */:
                    return this.emitTypeOfExpression(ast);
                case 170 /* DeleteExpression */:
                    return this.emitDeleteExpression(ast);
                case 172 /* VoidExpression */:
                    return this.emitVoidExpression(ast);
                case 162 /* DebuggerStatement */:
                    return this.emitDebuggerStatement(ast);
            }
        };
        return Emitter;
    })();
    TypeScript.Emitter = Emitter;

    function getLastConstructor(classDecl) {
        return classDecl.classElements.lastOrDefault(function (e) {
            return e.kind() === 137 /* ConstructorDeclaration */;
        });
    }
    TypeScript.getLastConstructor = getLastConstructor;

    function getTrimmedTextLines(comment) {
        if (comment.kind() === 6 /* MultiLineCommentTrivia */) {
            return comment.fullText().split("\n").map(function (s) {
                return s.trim();
            });
        } else {
            return [comment.fullText().trim()];
        }
    }
    TypeScript.getTrimmedTextLines = getTrimmedTextLines;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var MemberName = (function () {
        function MemberName() {
            this.prefix = "";
            this.suffix = "";
        }
        MemberName.prototype.isString = function () {
            return false;
        };
        MemberName.prototype.isArray = function () {
            return false;
        };
        MemberName.prototype.isMarker = function () {
            return !this.isString() && !this.isArray();
        };

        MemberName.prototype.toString = function () {
            return MemberName.memberNameToString(this);
        };

        MemberName.memberNameToString = function (memberName, markerInfo, markerBaseLength) {
            if (typeof markerBaseLength === "undefined") { markerBaseLength = 0; }
            var result = memberName.prefix;

            if (memberName.isString()) {
                result += memberName.text;
            } else if (memberName.isArray()) {
                var ar = memberName;
                for (var index = 0; index < ar.entries.length; index++) {
                    if (ar.entries[index].isMarker()) {
                        if (markerInfo) {
                            markerInfo.push(markerBaseLength + result.length);
                        }
                        continue;
                    }

                    result += MemberName.memberNameToString(ar.entries[index], markerInfo, markerBaseLength + result.length);
                    result += ar.delim;
                }
            }

            result += memberName.suffix;
            return result;
        };

        MemberName.create = function (arg1, arg2, arg3) {
            if (typeof arg1 === "string") {
                return new MemberNameString(arg1);
            } else {
                var result = new MemberNameArray();
                if (arg2)
                    result.prefix = arg2;
                if (arg3)
                    result.suffix = arg3;
                result.entries.push(arg1);
                return result;
            }
        };
        return MemberName;
    })();
    TypeScript.MemberName = MemberName;

    var MemberNameString = (function (_super) {
        __extends(MemberNameString, _super);
        function MemberNameString(text) {
            _super.call(this);
            this.text = text;
        }
        MemberNameString.prototype.isString = function () {
            return true;
        };
        return MemberNameString;
    })(MemberName);
    TypeScript.MemberNameString = MemberNameString;

    var MemberNameArray = (function (_super) {
        __extends(MemberNameArray, _super);
        function MemberNameArray() {
            _super.call(this);
            this.delim = "";
            this.entries = [];
        }
        MemberNameArray.prototype.isArray = function () {
            return true;
        };

        MemberNameArray.prototype.add = function (entry) {
            this.entries.push(entry);
        };

        MemberNameArray.prototype.addAll = function (entries) {
            for (var i = 0; i < entries.length; i++) {
                this.entries.push(entries[i]);
            }
        };
        return MemberNameArray;
    })(MemberName);
    TypeScript.MemberNameArray = MemberNameArray;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    function stripStartAndEndQuotes(str) {
        var firstCharCode = str && str.charCodeAt(0);
        if (str && str.length >= 2 && firstCharCode === str.charCodeAt(str.length - 1) && (firstCharCode === 39 /* singleQuote */ || firstCharCode === 34 /* doubleQuote */)) {
            return str.substring(1, str.length - 1);
        }

        return str;
    }
    TypeScript.stripStartAndEndQuotes = stripStartAndEndQuotes;

    function isSingleQuoted(str) {
        return str && str.length >= 2 && str.charCodeAt(0) === str.charCodeAt(str.length - 1) && str.charCodeAt(0) === 39 /* singleQuote */;
    }
    TypeScript.isSingleQuoted = isSingleQuoted;

    function isDoubleQuoted(str) {
        return str && str.length >= 2 && str.charCodeAt(0) === str.charCodeAt(str.length - 1) && str.charCodeAt(0) === 34 /* doubleQuote */;
    }
    TypeScript.isDoubleQuoted = isDoubleQuoted;

    function isQuoted(str) {
        return isDoubleQuoted(str) || isSingleQuoted(str);
    }
    TypeScript.isQuoted = isQuoted;

    function quoteStr(str) {
        return "\"" + str + "\"";
    }
    TypeScript.quoteStr = quoteStr;

    var switchToForwardSlashesRegEx = /\\/g;
    function switchToForwardSlashes(path) {
        return path.replace(switchToForwardSlashesRegEx, "/");
    }
    TypeScript.switchToForwardSlashes = switchToForwardSlashes;

    function trimModName(modName) {
        if (modName.length > 5 && modName.substring(modName.length - 5, modName.length) === ".d.ts") {
            return modName.substring(0, modName.length - 5);
        }
        if (modName.length > 3 && modName.substring(modName.length - 3, modName.length) === ".ts") {
            return modName.substring(0, modName.length - 3);
        }

        if (modName.length > 3 && modName.substring(modName.length - 3, modName.length) === ".js") {
            return modName.substring(0, modName.length - 3);
        }

        return modName;
    }
    TypeScript.trimModName = trimModName;

    function getDeclareFilePath(fname) {
        return isTSFile(fname) ? changePathToDTS(fname) : changePathToDTS(fname);
    }
    TypeScript.getDeclareFilePath = getDeclareFilePath;

    function isFileOfExtension(fname, ext) {
        var invariantFname = fname.toLocaleUpperCase();
        var invariantExt = ext.toLocaleUpperCase();
        var extLength = invariantExt.length;
        return invariantFname.length > extLength && invariantFname.substring(invariantFname.length - extLength, invariantFname.length) === invariantExt;
    }

    function isTSFile(fname) {
        return isFileOfExtension(fname, ".ts");
    }
    TypeScript.isTSFile = isTSFile;

    function isDTSFile(fname) {
        return isFileOfExtension(fname, ".d.ts");
    }
    TypeScript.isDTSFile = isDTSFile;

    function getPrettyName(modPath, quote, treatAsFileName) {
        if (typeof quote === "undefined") { quote = true; }
        if (typeof treatAsFileName === "undefined") { treatAsFileName = false; }
        var modName = treatAsFileName ? switchToForwardSlashes(modPath) : trimModName(stripStartAndEndQuotes(modPath));
        var components = this.getPathComponents(modName);
        return components.length ? (quote ? quoteStr(components[components.length - 1]) : components[components.length - 1]) : modPath;
    }
    TypeScript.getPrettyName = getPrettyName;

    function getPathComponents(path) {
        return path.split("/");
    }
    TypeScript.getPathComponents = getPathComponents;

    function getRelativePathToFixedPath(fixedModFilePath, absoluteModPath, isAbsoultePathURL) {
        if (typeof isAbsoultePathURL === "undefined") { isAbsoultePathURL = true; }
        absoluteModPath = switchToForwardSlashes(absoluteModPath);

        var modComponents = this.getPathComponents(absoluteModPath);
        var fixedModComponents = this.getPathComponents(fixedModFilePath);

        var joinStartIndex = 0;
        for (; joinStartIndex < modComponents.length && joinStartIndex < fixedModComponents.length; joinStartIndex++) {
            if (fixedModComponents[joinStartIndex] !== modComponents[joinStartIndex]) {
                break;
            }
        }

        if (joinStartIndex !== 0) {
            var relativePath = "";
            var relativePathComponents = modComponents.slice(joinStartIndex, modComponents.length);
            for (; joinStartIndex < fixedModComponents.length; joinStartIndex++) {
                if (fixedModComponents[joinStartIndex] !== "") {
                    relativePath = relativePath + "../";
                }
            }

            return relativePath + relativePathComponents.join("/");
        }

        if (isAbsoultePathURL && absoluteModPath.indexOf("://") === -1) {
            absoluteModPath = "file:///" + absoluteModPath;
        }

        return absoluteModPath;
    }
    TypeScript.getRelativePathToFixedPath = getRelativePathToFixedPath;

    function changePathToDTS(modPath) {
        return trimModName(stripStartAndEndQuotes(modPath)) + ".d.ts";
    }
    TypeScript.changePathToDTS = changePathToDTS;

    function isRelative(path) {
        return path.length > 0 && path.charAt(0) === ".";
    }
    TypeScript.isRelative = isRelative;
    function isRooted(path) {
        return path.length > 0 && (path.charAt(0) === "\\" || path.charAt(0) === "/" || (path.indexOf(":\\") !== -1) || (path.indexOf(":/") !== -1));
    }
    TypeScript.isRooted = isRooted;

    function getRootFilePath(outFname) {
        if (outFname === "") {
            return outFname;
        } else {
            var isPath = outFname.indexOf("/") !== -1;
            return isPath ? filePath(outFname) : "";
        }
    }
    TypeScript.getRootFilePath = getRootFilePath;

    function filePathComponents(fullPath) {
        fullPath = switchToForwardSlashes(fullPath);
        var components = getPathComponents(fullPath);
        return components.slice(0, components.length - 1);
    }
    TypeScript.filePathComponents = filePathComponents;

    function filePath(fullPath) {
        var path = filePathComponents(fullPath);
        return path.join("/") + "/";
    }
    TypeScript.filePath = filePath;

    function convertToDirectoryPath(dirPath) {
        if (dirPath && dirPath.charAt(dirPath.length - 1) !== "/") {
            dirPath += "/";
        }

        return dirPath;
    }
    TypeScript.convertToDirectoryPath = convertToDirectoryPath;

    var normalizePathRegEx = /^\\\\[^\\]/;
    function normalizePath(path) {
        if (normalizePathRegEx.test(path)) {
            path = "file:" + path;
        }
        var parts = this.getPathComponents(switchToForwardSlashes(path));
        var normalizedParts = [];

        for (var i = 0; i < parts.length; i++) {
            var part = parts[i];
            if (part === ".") {
                continue;
            }

            if (normalizedParts.length > 0 && TypeScript.ArrayUtilities.last(normalizedParts) !== ".." && part === "..") {
                normalizedParts.pop();
                continue;
            }

            normalizedParts.push(part);
        }

        return normalizedParts.join("/");
    }
    TypeScript.normalizePath = normalizePath;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    

    function isNoDefaultLibMatch(comment) {
        var isNoDefaultLibRegex = /^(\/\/\/\s*<reference\s+no-default-lib=)('|")(.+?)\2\s*\/>/gim;
        return isNoDefaultLibRegex.exec(comment);
    }

    TypeScript.tripleSlashReferenceRegExp = /^(\/\/\/\s*<reference\s+path=)('|")(.+?)\2\s*(static=('|")(.+?)\2\s*)*\/>/;

    function getFileReferenceFromReferencePath(fileName, lineMap, position, comment, diagnostics) {
        var simpleReferenceRegEx = /^\/\/\/\s*<reference\s+/gim;
        if (simpleReferenceRegEx.exec(comment)) {
            var isNoDefaultLib = isNoDefaultLibMatch(comment);

            if (!isNoDefaultLib) {
                var fullReferenceRegEx = TypeScript.tripleSlashReferenceRegExp;
                var fullReference = fullReferenceRegEx.exec(comment);

                if (!fullReference) {
                    diagnostics.push(new TypeScript.Diagnostic(fileName, lineMap, position, comment.length, TypeScript.DiagnosticCode.Invalid_reference_directive_syntax));
                } else {
                    var path = TypeScript.normalizePath(fullReference[3]);
                    var adjustedPath = TypeScript.normalizePath(path);

                    var isResident = fullReference.length >= 7 && fullReference[6] === "true";
                    if (isResident) {
                        TypeScript.CompilerDiagnostics.debugPrint(path + " is resident");
                    }
                    return {
                        line: 0,
                        character: 0,
                        position: 0,
                        length: 0,
                        path: TypeScript.switchToForwardSlashes(adjustedPath),
                        isResident: isResident
                    };
                }
            }
        }

        return null;
    }

    var scannerWindow = TypeScript.ArrayUtilities.createArray(2048, 0);
    var scannerDiagnostics = [];

    function processImports(lineMap, scanner, token, importedFiles) {
        var position = 0;
        var lineChar = { line: -1, character: -1 };

        var start = new Date().getTime();

        while (token.tokenKind !== 10 /* EndOfFileToken */) {
            if (token.tokenKind === 49 /* ImportKeyword */) {
                var importStart = position + token.leadingTriviaWidth();
                token = scanner.scan(scannerDiagnostics, false);

                if (TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(token)) {
                    token = scanner.scan(scannerDiagnostics, false);

                    if (token.tokenKind === 107 /* EqualsToken */) {
                        token = scanner.scan(scannerDiagnostics, false);

                        if (token.tokenKind === 65 /* ModuleKeyword */ || token.tokenKind === 66 /* RequireKeyword */) {
                            token = scanner.scan(scannerDiagnostics, false);

                            if (token.tokenKind === 72 /* OpenParenToken */) {
                                var afterOpenParenPosition = scanner.absoluteIndex();
                                token = scanner.scan(scannerDiagnostics, false);

                                lineMap.fillLineAndCharacterFromPosition(importStart, lineChar);

                                if (token.tokenKind === 14 /* StringLiteral */) {
                                    var ref = {
                                        line: lineChar.line,
                                        character: lineChar.character,
                                        position: afterOpenParenPosition + token.leadingTriviaWidth(),
                                        length: token.width(),
                                        path: TypeScript.stripStartAndEndQuotes(TypeScript.switchToForwardSlashes(token.text())),
                                        isResident: false
                                    };
                                    importedFiles.push(ref);
                                }
                            }
                        }
                    }
                }
            }

            position = scanner.absoluteIndex();
            token = scanner.scan(scannerDiagnostics, false);
        }

        var totalTime = new Date().getTime() - start;
        TypeScript.fileResolutionScanImportsTime += totalTime;
    }

    function processTripleSlashDirectives(fileName, lineMap, firstToken) {
        var leadingTrivia = firstToken.leadingTrivia();

        var position = 0;
        var lineChar = { line: -1, character: -1 };
        var noDefaultLib = false;
        var diagnostics = [];
        var referencedFiles = [];

        for (var i = 0, n = leadingTrivia.count(); i < n; i++) {
            var trivia = leadingTrivia.syntaxTriviaAt(i);

            if (trivia.kind() === 7 /* SingleLineCommentTrivia */) {
                var triviaText = trivia.fullText();
                var referencedCode = getFileReferenceFromReferencePath(fileName, lineMap, position, triviaText, diagnostics);

                if (referencedCode) {
                    lineMap.fillLineAndCharacterFromPosition(position, lineChar);
                    referencedCode.position = position;
                    referencedCode.length = trivia.fullWidth();
                    referencedCode.line = lineChar.line;
                    referencedCode.character = lineChar.character;

                    referencedFiles.push(referencedCode);
                }

                var isNoDefaultLib = isNoDefaultLibMatch(triviaText);
                if (isNoDefaultLib) {
                    noDefaultLib = isNoDefaultLib[3] === "true";
                }
            }

            position += trivia.fullWidth();
        }

        return { noDefaultLib: noDefaultLib, diagnostics: diagnostics, referencedFiles: referencedFiles };
    }

    function preProcessFile(fileName, sourceText, readImportFiles) {
        if (typeof readImportFiles === "undefined") { readImportFiles = true; }
        var text = TypeScript.SimpleText.fromScriptSnapshot(sourceText);
        var scanner = new TypeScript.Scanner(fileName, text, 1 /* EcmaScript5 */, scannerWindow);

        var firstToken = scanner.scan(scannerDiagnostics, false);

        var importedFiles = [];
        if (readImportFiles) {
            processImports(text.lineMap(), scanner, firstToken, importedFiles);
        }

        var properties = processTripleSlashDirectives(fileName, text.lineMap(), firstToken);

        scannerDiagnostics.length = 0;
        return { referencedFiles: properties.referencedFiles, importedFiles: importedFiles, isLibFile: properties.noDefaultLib, diagnostics: properties.diagnostics };
    }
    TypeScript.preProcessFile = preProcessFile;

    function getParseOptions(settings) {
        return new TypeScript.ParseOptions(settings.codeGenTarget(), settings.allowAutomaticSemicolonInsertion());
    }
    TypeScript.getParseOptions = getParseOptions;

    function getReferencedFiles(fileName, sourceText) {
        return preProcessFile(fileName, sourceText, false).referencedFiles;
    }
    TypeScript.getReferencedFiles = getReferencedFiles;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var ReferenceResolutionResult = (function () {
        function ReferenceResolutionResult() {
            this.resolvedFiles = [];
            this.diagnostics = [];
            this.seenNoDefaultLibTag = false;
        }
        return ReferenceResolutionResult;
    })();
    TypeScript.ReferenceResolutionResult = ReferenceResolutionResult;

    var ReferenceLocation = (function () {
        function ReferenceLocation(filePath, lineMap, position, length, isImported) {
            this.filePath = filePath;
            this.lineMap = lineMap;
            this.position = position;
            this.length = length;
            this.isImported = isImported;
        }
        return ReferenceLocation;
    })();

    var ReferenceResolver = (function () {
        function ReferenceResolver(inputFileNames, host, useCaseSensitiveFileResolution) {
            this.useCaseSensitiveFileResolution = useCaseSensitiveFileResolution;
            this.inputFileNames = inputFileNames;
            this.host = host;
            this.visited = {};
        }
        ReferenceResolver.resolve = function (inputFileNames, host, useCaseSensitiveFileResolution) {
            var resolver = new ReferenceResolver(inputFileNames, host, useCaseSensitiveFileResolution);
            return resolver.resolveInputFiles();
        };

        ReferenceResolver.prototype.resolveInputFiles = function () {
            var _this = this;
            var result = new ReferenceResolutionResult();

            if (!this.inputFileNames || this.inputFileNames.length <= 0) {
                return result;
            }

            var referenceLocation = new ReferenceLocation(null, null, 0, 0, false);
            this.inputFileNames.forEach(function (fileName) {
                return _this.resolveIncludedFile(fileName, referenceLocation, result);
            });

            return result;
        };

        ReferenceResolver.prototype.resolveIncludedFile = function (path, referenceLocation, resolutionResult) {
            var normalizedPath = this.getNormalizedFilePath(path, referenceLocation.filePath);

            if (this.isSameFile(normalizedPath, referenceLocation.filePath)) {
                if (!referenceLocation.isImported) {
                    resolutionResult.diagnostics.push(new TypeScript.Diagnostic(referenceLocation.filePath, referenceLocation.lineMap, referenceLocation.position, referenceLocation.length, TypeScript.DiagnosticCode.A_file_cannot_have_a_reference_to_itself, null));
                }

                return normalizedPath;
            }

            if (!TypeScript.isTSFile(normalizedPath) && !TypeScript.isDTSFile(normalizedPath)) {
                var dtsFile = normalizedPath + ".d.ts";
                var tsFile = normalizedPath + ".ts";

                if (this.host.fileExists(tsFile)) {
                    normalizedPath = tsFile;
                } else {
                    normalizedPath = dtsFile;
                }
            }

            if (!this.host.fileExists(normalizedPath)) {
                if (!referenceLocation.isImported) {
                    resolutionResult.diagnostics.push(new TypeScript.Diagnostic(referenceLocation.filePath, referenceLocation.lineMap, referenceLocation.position, referenceLocation.length, TypeScript.DiagnosticCode.Cannot_resolve_referenced_file_0, [path]));
                }

                return normalizedPath;
            }

            return this.resolveFile(normalizedPath, resolutionResult);
        };

        ReferenceResolver.prototype.resolveImportedFile = function (path, referenceLocation, resolutionResult) {
            var isRelativePath = TypeScript.isRelative(path);
            var isRootedPath = isRelativePath ? false : TypeScript.isRooted(path);

            if (isRelativePath || isRootedPath) {
                return this.resolveIncludedFile(path, referenceLocation, resolutionResult);
            } else {
                var parentDirectory = this.host.getParentDirectory(referenceLocation.filePath);
                var searchFilePath = null;
                var dtsFileName = path + ".d.ts";
                var tsFilePath = path + ".ts";

                var start = new Date().getTime();

                do {
                    currentFilePath = this.host.resolveRelativePath(tsFilePath, parentDirectory);
                    if (this.host.fileExists(currentFilePath)) {
                        searchFilePath = currentFilePath;
                        break;
                    }

                    var currentFilePath = this.host.resolveRelativePath(dtsFileName, parentDirectory);
                    if (this.host.fileExists(currentFilePath)) {
                        searchFilePath = currentFilePath;
                        break;
                    }

                    parentDirectory = this.host.getParentDirectory(parentDirectory);
                } while(parentDirectory);

                TypeScript.fileResolutionImportFileSearchTime += new Date().getTime() - start;

                if (!searchFilePath) {
                    return path;
                }

                return this.resolveFile(searchFilePath, resolutionResult);
            }
        };

        ReferenceResolver.prototype.resolveFile = function (normalizedPath, resolutionResult) {
            var _this = this;
            var visitedPath = this.isVisited(normalizedPath);
            if (!visitedPath) {
                this.recordVisitedFile(normalizedPath);

                var start = new Date().getTime();
                var scriptSnapshot = this.host.getScriptSnapshot(normalizedPath);
                var totalTime = new Date().getTime() - start;
                TypeScript.fileResolutionIOTime += totalTime;

                var lineMap = TypeScript.LineMap1.fromScriptSnapshot(scriptSnapshot);
                var preprocessedFileInformation = TypeScript.preProcessFile(normalizedPath, scriptSnapshot);
                resolutionResult.diagnostics.push.apply(resolutionResult.diagnostics, preprocessedFileInformation.diagnostics);

                if (preprocessedFileInformation.isLibFile) {
                    resolutionResult.seenNoDefaultLibTag = true;
                }

                var normalizedReferencePaths = [];
                preprocessedFileInformation.referencedFiles.forEach(function (fileReference) {
                    var currentReferenceLocation = new ReferenceLocation(normalizedPath, lineMap, fileReference.position, fileReference.length, false);
                    var normalizedReferencePath = _this.resolveIncludedFile(fileReference.path, currentReferenceLocation, resolutionResult);
                    normalizedReferencePaths.push(normalizedReferencePath);
                });

                var normalizedImportPaths = [];
                for (var i = 0; i < preprocessedFileInformation.importedFiles.length; i++) {
                    var fileImport = preprocessedFileInformation.importedFiles[i];
                    var currentReferenceLocation = new ReferenceLocation(normalizedPath, lineMap, fileImport.position, fileImport.length, true);
                    var normalizedImportPath = this.resolveImportedFile(fileImport.path, currentReferenceLocation, resolutionResult);
                    normalizedImportPaths.push(normalizedImportPath);
                }

                resolutionResult.resolvedFiles.push({
                    path: normalizedPath,
                    referencedFiles: normalizedReferencePaths,
                    importedFiles: normalizedImportPaths
                });
            } else {
                normalizedPath = visitedPath;
            }

            return normalizedPath;
        };

        ReferenceResolver.prototype.getNormalizedFilePath = function (path, parentFilePath) {
            var parentFileDirectory = parentFilePath ? this.host.getParentDirectory(parentFilePath) : "";
            var normalizedPath = this.host.resolveRelativePath(path, parentFileDirectory);
            return normalizedPath;
        };

        ReferenceResolver.prototype.getUniqueFileId = function (filePath) {
            return this.useCaseSensitiveFileResolution ? filePath : filePath.toLocaleUpperCase();
        };

        ReferenceResolver.prototype.recordVisitedFile = function (filePath) {
            this.visited[this.getUniqueFileId(filePath)] = filePath;
        };

        ReferenceResolver.prototype.isVisited = function (filePath) {
            return this.visited[this.getUniqueFileId(filePath)];
        };

        ReferenceResolver.prototype.isSameFile = function (filePath1, filePath2) {
            if (!filePath1 || !filePath2) {
                return false;
            }

            if (this.useCaseSensitiveFileResolution) {
                return filePath1 === filePath2;
            } else {
                return filePath1.toLocaleUpperCase() === filePath2.toLocaleUpperCase();
            }
        };
        return ReferenceResolver;
    })();
    TypeScript.ReferenceResolver = ReferenceResolver;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var TextWriter = (function () {
        function TextWriter(name, writeByteOrderMark, outputFileType) {
            this.name = name;
            this.writeByteOrderMark = writeByteOrderMark;
            this.outputFileType = outputFileType;
            this.contents = "";
            this.onNewLine = true;
        }
        TextWriter.prototype.Write = function (s) {
            this.contents += s;
            this.onNewLine = false;
        };

        TextWriter.prototype.WriteLine = function (s) {
            this.contents += s;
            this.contents += TypeScript.newLine();
            this.onNewLine = true;
        };

        TextWriter.prototype.Close = function () {
        };

        TextWriter.prototype.getOutputFile = function () {
            return new TypeScript.OutputFile(this.name, this.writeByteOrderMark, this.contents, this.outputFileType);
        };
        return TextWriter;
    })();
    TypeScript.TextWriter = TextWriter;

    var DeclarationEmitter = (function () {
        function DeclarationEmitter(emittingFileName, document, compiler, emitOptions, semanticInfoChain) {
            this.emittingFileName = emittingFileName;
            this.document = document;
            this.compiler = compiler;
            this.emitOptions = emitOptions;
            this.semanticInfoChain = semanticInfoChain;
            this.declFile = null;
            this.indenter = new TypeScript.Indenter();
            this.emittedReferencePaths = false;
            this.declFile = new TextWriter(emittingFileName, this.document.byteOrderMark !== 0 /* None */, 2 /* Declaration */);
        }
        DeclarationEmitter.prototype.getOutputFile = function () {
            return this.declFile.getOutputFile();
        };

        DeclarationEmitter.prototype.emitDeclarations = function (sourceUnit) {
            this.emitDeclarationsForSourceUnit(sourceUnit);
        };

        DeclarationEmitter.prototype.emitDeclarationsForList = function (list) {
            for (var i = 0, n = list.childCount(); i < n; i++) {
                this.emitDeclarationsForAST(list.childAt(i));
            }
        };

        DeclarationEmitter.prototype.emitSeparatedList = function (list) {
            for (var i = 0, n = list.nonSeparatorCount(); i < n; i++) {
                this.emitDeclarationsForAST(list.nonSeparatorAt(i));
            }
        };

        DeclarationEmitter.prototype.emitDeclarationsForAST = function (ast) {
            switch (ast.kind()) {
                case 148 /* VariableStatement */:
                    return this.emitDeclarationsForVariableStatement(ast);
                case 141 /* PropertySignature */:
                    return this.emitPropertySignature(ast);
                case 225 /* VariableDeclarator */:
                    return this.emitVariableDeclarator(ast, true, true);
                case 136 /* MemberVariableDeclaration */:
                    return this.emitDeclarationsForMemberVariableDeclaration(ast);
                case 137 /* ConstructorDeclaration */:
                    return this.emitDeclarationsForConstructorDeclaration(ast);
                case 139 /* GetAccessor */:
                    return this.emitDeclarationsForGetAccessor(ast);
                case 140 /* SetAccessor */:
                    return this.emitDeclarationsForSetAccessor(ast);
                case 138 /* IndexMemberDeclaration */:
                    return this.emitIndexMemberDeclaration(ast);
                case 144 /* IndexSignature */:
                    return this.emitIndexSignature(ast);
                case 142 /* CallSignature */:
                    return this.emitCallSignature(ast);
                case 143 /* ConstructSignature */:
                    return this.emitConstructSignature(ast);
                case 145 /* MethodSignature */:
                    return this.emitMethodSignature(ast);
                case 129 /* FunctionDeclaration */:
                    return this.emitDeclarationsForFunctionDeclaration(ast);
                case 135 /* MemberFunctionDeclaration */:
                    return this.emitMemberFunctionDeclaration(ast);
                case 131 /* ClassDeclaration */:
                    return this.emitDeclarationsForClassDeclaration(ast);
                case 128 /* InterfaceDeclaration */:
                    return this.emitDeclarationsForInterfaceDeclaration(ast);
                case 133 /* ImportDeclaration */:
                    return this.emitDeclarationsForImportDeclaration(ast);
                case 130 /* ModuleDeclaration */:
                    return this.emitDeclarationsForModuleDeclaration(ast);
                case 132 /* EnumDeclaration */:
                    return this.emitDeclarationsForEnumDeclaration(ast);
                case 134 /* ExportAssignment */:
                    return this.emitDeclarationsForExportAssignment(ast);
            }
        };

        DeclarationEmitter.prototype.getIndentString = function (declIndent) {
            if (typeof declIndent === "undefined") { declIndent = false; }
            return this.indenter.getIndent();
        };

        DeclarationEmitter.prototype.emitIndent = function () {
            this.declFile.Write(this.getIndentString());
        };

        DeclarationEmitter.prototype.canEmitDeclarations = function (declAST) {
            var container = DeclarationEmitter.getEnclosingContainer(declAST);
            if (container.kind() === 130 /* ModuleDeclaration */ || container.kind() === 120 /* SourceUnit */) {
                var pullDecl = this.semanticInfoChain.getDeclForAST(declAST);
                if (!TypeScript.hasFlag(pullDecl.flags, 1 /* Exported */)) {
                    var start = new Date().getTime();
                    var declSymbol = this.semanticInfoChain.getSymbolForAST(declAST);
                    var result = declSymbol && declSymbol.isExternallyVisible();
                    TypeScript.declarationEmitIsExternallyVisibleTime += new Date().getTime() - start;

                    return result;
                }
            }

            return true;
        };

        DeclarationEmitter.prototype.getDeclFlagsString = function (pullDecl, typeString) {
            var result = this.getIndentString();
            var pullFlags = pullDecl.flags;

            if (TypeScript.hasFlag(pullFlags, 16 /* Static */)) {
                if (TypeScript.hasFlag(pullFlags, 2 /* Private */)) {
                    result += "private ";
                }
                result += "static ";
            } else {
                if (TypeScript.hasFlag(pullFlags, 2 /* Private */)) {
                    result += "private ";
                } else if (TypeScript.hasFlag(pullFlags, 4 /* Public */)) {
                    result += "public ";
                } else {
                    var emitDeclare = !TypeScript.hasFlag(pullFlags, 1 /* Exported */);

                    var declAST = this.semanticInfoChain.getASTForDecl(pullDecl);
                    var container = DeclarationEmitter.getEnclosingContainer(declAST);

                    var isExternalModule = container.kind() === 120 /* SourceUnit */ && this.document.isExternalModule();

                    if (isExternalModule && TypeScript.hasFlag(pullFlags, 1 /* Exported */)) {
                        result += "export ";
                        emitDeclare = true;
                    }

                    if (isExternalModule || container.kind() === 120 /* SourceUnit */) {
                        if (emitDeclare && typeString !== "interface" && typeString !== "import") {
                            result += "declare ";
                        }
                    }

                    result += typeString + " ";
                }
            }

            return result;
        };

        DeclarationEmitter.prototype.emitDeclFlags = function (declarationAST, typeString) {
            this.declFile.Write(this.getDeclFlagsString(this.semanticInfoChain.getDeclForAST(declarationAST), typeString));
        };

        DeclarationEmitter.prototype.emitTypeNamesMember = function (memberName, emitIndent) {
            if (typeof emitIndent === "undefined") { emitIndent = false; }
            if (memberName.prefix === "{ ") {
                if (emitIndent) {
                    this.emitIndent();
                }

                this.declFile.WriteLine("{");
                this.indenter.increaseIndent();
                emitIndent = true;
            } else if (memberName.prefix !== "") {
                if (emitIndent) {
                    this.emitIndent();
                }

                this.declFile.Write(memberName.prefix);
                emitIndent = false;
            }

            if (memberName.isString()) {
                if (emitIndent) {
                    this.emitIndent();
                }

                this.declFile.Write(memberName.text);
            } else if (memberName.isArray()) {
                var ar = memberName;
                for (var index = 0; index < ar.entries.length; index++) {
                    this.emitTypeNamesMember(ar.entries[index], emitIndent);
                    if (ar.delim === "; ") {
                        this.declFile.WriteLine(";");
                    }
                }
            }

            if (memberName.suffix === "}") {
                this.indenter.decreaseIndent();
                this.emitIndent();
                this.declFile.Write(memberName.suffix);
            } else {
                this.declFile.Write(memberName.suffix);
            }
        };

        DeclarationEmitter.prototype.emitTypeSignature = function (ast, type) {
            var declarationContainerAst = DeclarationEmitter.getEnclosingContainer(ast);

            var start = new Date().getTime();
            var declarationContainerDecl = this.semanticInfoChain.getDeclForAST(declarationContainerAst);

            var declarationPullSymbol = declarationContainerDecl.getSymbol();
            TypeScript.declarationEmitTypeSignatureTime += new Date().getTime() - start;

            var isNotAGenericType = ast.kind() !== 126 /* GenericType */;

            var typeNameMembers = type.getScopedNameEx(declarationPullSymbol, false, false, false, false, false, isNotAGenericType);
            this.emitTypeNamesMember(typeNameMembers);
        };

        DeclarationEmitter.prototype.emitComment = function (comment) {
            var text = TypeScript.getTrimmedTextLines(comment);
            if (this.declFile.onNewLine) {
                this.emitIndent();
            } else if (comment.kind() !== 6 /* MultiLineCommentTrivia */) {
                this.declFile.WriteLine("");
                this.emitIndent();
            }

            this.declFile.Write(text[0]);

            for (var i = 1; i < text.length; i++) {
                this.declFile.WriteLine("");
                this.emitIndent();
                this.declFile.Write(text[i]);
            }

            if (comment.endsLine || comment.kind() !== 6 /* MultiLineCommentTrivia */) {
                this.declFile.WriteLine("");
            } else {
                this.declFile.Write(" ");
            }
        };

        DeclarationEmitter.prototype.emitDeclarationComments = function (astOrSymbol, endLine) {
            if (typeof endLine === "undefined") { endLine = true; }
            if (this.emitOptions.compilationSettings().removeComments()) {
                return;
            }

            var declComments = astOrSymbol.docComments ? astOrSymbol.docComments() : TypeScript.ASTHelpers.docComments(astOrSymbol);
            this.writeDeclarationComments(declComments, endLine);
        };

        DeclarationEmitter.prototype.writeDeclarationComments = function (declComments, endLine) {
            if (typeof endLine === "undefined") { endLine = true; }
            if (declComments.length > 0) {
                for (var i = 0; i < declComments.length; i++) {
                    this.emitComment(declComments[i]);
                }

                if (endLine) {
                    if (!this.declFile.onNewLine) {
                        this.declFile.WriteLine("");
                    }
                } else {
                    if (this.declFile.onNewLine) {
                        this.emitIndent();
                    }
                }
            }
        };

        DeclarationEmitter.prototype.emitTypeOfVariableDeclaratorOrParameter = function (boundDecl) {
            var start = new Date().getTime();
            var decl = this.semanticInfoChain.getDeclForAST(boundDecl);
            var pullSymbol = decl.getSymbol();
            TypeScript.declarationEmitGetBoundDeclTypeTime += new Date().getTime() - start;

            var type = pullSymbol.type;
            TypeScript.Debug.assert(type);

            this.declFile.Write(": ");
            this.emitTypeSignature(boundDecl, type);
        };

        DeclarationEmitter.prototype.emitPropertySignature = function (varDecl) {
            this.emitDeclarationComments(varDecl);
            this.emitIndent();
            this.declFile.Write(varDecl.propertyName.text());
            if (varDecl.questionToken) {
                this.declFile.Write("?");
            }

            this.emitTypeOfVariableDeclaratorOrParameter(varDecl);

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitVariableDeclarator = function (varDecl, isFirstVarInList, isLastVarInList) {
            if (this.canEmitDeclarations(varDecl)) {
                this.emitDeclarationComments(varDecl);

                if (isFirstVarInList) {
                    this.emitDeclFlags(varDecl, "var");
                }

                this.declFile.Write(varDecl.propertyName.text());

                if (!TypeScript.hasModifier(TypeScript.ASTHelpers.getVariableDeclaratorModifiers(varDecl), 2 /* Private */)) {
                    this.emitTypeOfVariableDeclaratorOrParameter(varDecl);
                }

                if (isLastVarInList) {
                    this.declFile.WriteLine(";");
                } else {
                    this.declFile.Write(", ");
                }
            }
        };

        DeclarationEmitter.prototype.emitClassElementModifiers = function (modifiers) {
            if (TypeScript.hasModifier(modifiers, 16 /* Static */)) {
                if (TypeScript.hasModifier(modifiers, 2 /* Private */)) {
                    this.declFile.Write("private ");
                }
                this.declFile.Write("static ");
            } else {
                if (TypeScript.hasModifier(modifiers, 2 /* Private */)) {
                    this.declFile.Write("private ");
                } else {
                    this.declFile.Write("public ");
                }
            }
        };

        DeclarationEmitter.prototype.emitDeclarationsForMemberVariableDeclaration = function (varDecl) {
            if (this.canEmitDeclarations(varDecl)) {
                this.emitDeclarationComments(varDecl);

                this.declFile.Write(this.getIndentString());
                this.emitClassElementModifiers(varDecl.modifiers);
                ;

                this.declFile.Write(varDecl.variableDeclarator.propertyName.text());

                if (!TypeScript.hasModifier(varDecl.modifiers, 2 /* Private */)) {
                    this.emitTypeOfVariableDeclaratorOrParameter(varDecl);
                }

                this.declFile.WriteLine(";");
            }
        };

        DeclarationEmitter.prototype.emitDeclarationsForVariableStatement = function (variableStatement) {
            this.emitDeclarationsForVariableDeclaration(variableStatement.declaration);
        };

        DeclarationEmitter.prototype.emitDeclarationsForVariableDeclaration = function (variableDeclaration) {
            var varListCount = variableDeclaration.declarators.nonSeparatorCount();
            for (var i = 0; i < varListCount; i++) {
                this.emitVariableDeclarator(variableDeclaration.declarators.nonSeparatorAt(i), i === 0, i === varListCount - 1);
            }
        };

        DeclarationEmitter.prototype.emitArgDecl = function (argDecl, id, isOptional, isPrivate) {
            this.indenter.increaseIndent();

            this.emitDeclarationComments(argDecl, false);
            this.declFile.Write(id.text());
            if (isOptional) {
                this.declFile.Write("?");
            }

            this.indenter.decreaseIndent();

            if (!isPrivate) {
                this.emitTypeOfVariableDeclaratorOrParameter(argDecl);
            }
        };

        DeclarationEmitter.prototype.isOverloadedCallSignature = function (funcDecl) {
            var start = new Date().getTime();
            var functionDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            var funcSymbol = functionDecl.getSymbol();
            TypeScript.declarationEmitIsOverloadedCallSignatureTime += new Date().getTime() - start;

            var funcTypeSymbol = funcSymbol.type;
            var signatures = funcTypeSymbol.getCallSignatures();
            var result = signatures && signatures.length > 1;

            return result;
        };

        DeclarationEmitter.prototype.emitDeclarationsForConstructorDeclaration = function (funcDecl) {
            var start = new Date().getTime();
            var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);

            TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;

            var funcTypeSymbol = funcSymbol.type;
            if (funcDecl.block) {
                var constructSignatures = funcTypeSymbol.getConstructSignatures();
                if (constructSignatures && constructSignatures.length > 1) {
                    return;
                }
            }

            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            var funcSignature = funcPullDecl.getSignatureSymbol();
            this.emitDeclarationComments(funcDecl);

            this.emitIndent();
            this.declFile.Write("constructor");

            this.declFile.Write("(");
            this.emitParameters(false, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList));
            this.declFile.Write(")");
            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitParameterList = function (isPrivate, parameterList) {
            this.declFile.Write("(");
            this.emitParameters(isPrivate, TypeScript.ASTHelpers.parametersFromParameterList(parameterList));
            this.declFile.Write(")");
        };

        DeclarationEmitter.prototype.emitParameters = function (isPrivate, parameterList) {
            var hasLastParameterRestParameter = parameterList.lastParameterIsRest();
            var argsLen = parameterList.length;
            if (hasLastParameterRestParameter) {
                argsLen--;
            }

            for (var i = 0; i < argsLen; i++) {
                this.emitArgDecl(parameterList.astAt(i), parameterList.identifierAt(i), parameterList.isOptionalAt(i), isPrivate);
                if (i < (argsLen - 1)) {
                    this.declFile.Write(", ");
                }
            }

            if (hasLastParameterRestParameter) {
                if (parameterList.length > 1) {
                    this.declFile.Write(", ...");
                } else {
                    this.declFile.Write("...");
                }

                var index = parameterList.length - 1;
                this.emitArgDecl(parameterList.astAt(index), parameterList.identifierAt(index), parameterList.isOptionalAt(index), isPrivate);
            }
        };

        DeclarationEmitter.prototype.emitMemberFunctionDeclaration = function (funcDecl) {
            var start = new Date().getTime();
            var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);

            TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;

            var funcTypeSymbol = funcSymbol.type;
            if (funcDecl.block) {
                var constructSignatures = funcTypeSymbol.getConstructSignatures();
                if (constructSignatures && constructSignatures.length > 1) {
                    return;
                } else if (this.isOverloadedCallSignature(funcDecl)) {
                    return;
                }
            } else if (TypeScript.hasModifier(funcDecl.modifiers, 2 /* Private */) && this.isOverloadedCallSignature(funcDecl)) {
                var callSignatures = funcTypeSymbol.getCallSignatures();
                TypeScript.Debug.assert(callSignatures && callSignatures.length > 1);
                var firstSignature = callSignatures[0].isDefinition() ? callSignatures[1] : callSignatures[0];
                var firstSignatureDecl = firstSignature.getDeclarations()[0];
                var firstFuncDecl = this.semanticInfoChain.getASTForDecl(firstSignatureDecl);
                if (firstFuncDecl !== funcDecl) {
                    return;
                }
            }

            if (!this.canEmitDeclarations(funcDecl)) {
                return;
            }

            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            var funcSignature = funcPullDecl.getSignatureSymbol();
            this.emitDeclarationComments(funcDecl);

            this.emitDeclFlags(funcDecl, "function");
            var id = funcDecl.propertyName.text();
            this.declFile.Write(id);
            this.emitTypeParameters(funcDecl.callSignature.typeParameterList, funcSignature);

            var isPrivate = TypeScript.hasModifier(funcDecl.modifiers, 2 /* Private */);

            this.emitParameterList(isPrivate, funcDecl.callSignature.parameterList);

            if (!isPrivate) {
                var returnType = funcSignature.returnType;
                this.declFile.Write(": ");
                this.emitTypeSignature(funcDecl, returnType);
            }

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitCallSignature = function (funcDecl) {
            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);

            this.emitDeclarationComments(funcDecl);

            var funcSignature = funcPullDecl.getSignatureSymbol();
            this.emitTypeParameters(funcDecl.typeParameterList, funcSignature);

            this.emitIndent();
            this.declFile.Write("(");
            this.emitParameters(false, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.parameterList));
            this.declFile.Write(")");

            var returnType = funcSignature.returnType;
            this.declFile.Write(": ");
            if (returnType) {
                this.emitTypeSignature(funcDecl, returnType);
            } else {
                this.declFile.Write("any");
            }

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitConstructSignature = function (funcDecl) {
            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);

            var start = new Date().getTime();
            var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);

            TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;

            this.emitDeclarationComments(funcDecl);

            this.emitIndent();
            this.declFile.Write("new");

            var funcSignature = funcPullDecl.getSignatureSymbol();
            this.emitTypeParameters(funcDecl.callSignature.typeParameterList, funcSignature);

            this.declFile.Write("(");
            this.emitParameters(false, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList));
            this.declFile.Write(")");

            var returnType = funcSignature.returnType;
            this.declFile.Write(": ");
            if (returnType) {
                this.emitTypeSignature(funcDecl, returnType);
            } else {
                this.declFile.Write("any");
            }

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitMethodSignature = function (funcDecl) {
            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);

            var start = new Date().getTime();
            var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);

            TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;

            this.emitDeclarationComments(funcDecl);

            this.emitIndent();
            this.declFile.Write(funcDecl.propertyName.text());
            if (funcDecl.questionToken) {
                this.declFile.Write("? ");
            }

            var funcSignature = funcPullDecl.getSignatureSymbol();
            this.emitTypeParameters(funcDecl.callSignature.typeParameterList, funcSignature);

            this.declFile.Write("(");
            this.emitParameters(false, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList));
            this.declFile.Write(")");

            var returnType = funcSignature.returnType;
            this.declFile.Write(": ");
            if (returnType) {
                this.emitTypeSignature(funcDecl, returnType);
            } else {
                this.declFile.Write("any");
            }

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitDeclarationsForFunctionDeclaration = function (funcDecl) {
            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);

            var start = new Date().getTime();
            var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);

            TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;

            if (funcDecl.block) {
                var funcTypeSymbol = funcSymbol.type;
                var constructSignatures = funcTypeSymbol.getConstructSignatures();
                if (constructSignatures && constructSignatures.length > 1) {
                    return;
                } else if (this.isOverloadedCallSignature(funcDecl)) {
                    return;
                }
            }

            if (!this.canEmitDeclarations(funcDecl)) {
                return;
            }

            this.emitDeclarationComments(funcDecl);

            var id = funcDecl.identifier.text();
            this.emitDeclFlags(funcDecl, "function");
            if (id !== "" || !funcDecl.identifier || funcDecl.identifier.text().length > 0) {
                this.declFile.Write(id);
            } else if (funcPullDecl.kind === 2097152 /* ConstructSignature */) {
                this.declFile.Write("new");
            }

            var funcSignature = funcPullDecl.getSignatureSymbol();
            this.emitTypeParameters(funcDecl.callSignature.typeParameterList, funcSignature);

            this.declFile.Write("(");
            this.emitParameters(false, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList));
            this.declFile.Write(")");

            var returnType = funcSignature.returnType;
            this.declFile.Write(": ");
            if (returnType) {
                this.emitTypeSignature(funcDecl, returnType);
            } else {
                this.declFile.Write("any");
            }

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitIndexMemberDeclaration = function (funcDecl) {
            this.emitDeclarationsForAST(funcDecl.indexSignature);
        };

        DeclarationEmitter.prototype.emitIndexSignature = function (funcDecl) {
            if (!this.canEmitDeclarations(funcDecl)) {
                return;
            }

            this.emitDeclarationComments(funcDecl);

            this.emitIndent();
            this.declFile.Write("[");
            this.emitParameters(false, TypeScript.ASTHelpers.parametersFromParameter(funcDecl.parameter));
            this.declFile.Write("]");

            var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
            var funcSignature = funcPullDecl.getSignatureSymbol();
            var returnType = funcSignature.returnType;
            this.declFile.Write(": ");
            this.emitTypeSignature(funcDecl, returnType);

            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitBaseList = function (bases, useExtendsList) {
            if (bases && (bases.nonSeparatorCount() > 0)) {
                var qual = useExtendsList ? "extends" : "implements";
                this.declFile.Write(" " + qual + " ");
                var basesLen = bases.nonSeparatorCount();
                for (var i = 0; i < basesLen; i++) {
                    if (i > 0) {
                        this.declFile.Write(", ");
                    }
                    var base = bases.nonSeparatorAt(i);
                    var baseType = this.semanticInfoChain.getSymbolForAST(base);
                    this.emitTypeSignature(base, baseType);
                }
            }
        };

        DeclarationEmitter.prototype.emitAccessorDeclarationComments = function (funcDecl) {
            if (this.emitOptions.compilationSettings().removeComments()) {
                return;
            }

            var start = new Date().getTime();
            var accessors = TypeScript.PullHelpers.getGetterAndSetterFunction(funcDecl, this.semanticInfoChain);
            TypeScript.declarationEmitGetAccessorFunctionTime += new Date().getTime();

            var comments = [];
            if (accessors.getter) {
                comments = comments.concat(TypeScript.ASTHelpers.docComments(accessors.getter));
            }
            if (accessors.setter) {
                comments = comments.concat(TypeScript.ASTHelpers.docComments(accessors.setter));
            }

            this.writeDeclarationComments(comments);
        };

        DeclarationEmitter.prototype.emitDeclarationsForGetAccessor = function (funcDecl) {
            this.emitMemberAccessorDeclaration(funcDecl, funcDecl.modifiers, funcDecl.propertyName);
        };

        DeclarationEmitter.prototype.emitDeclarationsForSetAccessor = function (funcDecl) {
            this.emitMemberAccessorDeclaration(funcDecl, funcDecl.modifiers, funcDecl.propertyName);
        };

        DeclarationEmitter.prototype.emitMemberAccessorDeclaration = function (funcDecl, modifiers, name) {
            var start = new Date().getTime();
            var accessorSymbol = TypeScript.PullHelpers.getAccessorSymbol(funcDecl, this.semanticInfoChain);
            TypeScript.declarationEmitGetAccessorFunctionTime += new Date().getTime();

            if (funcDecl.kind() === 140 /* SetAccessor */ && accessorSymbol.getGetter()) {
                return;
            }

            var isPrivate = TypeScript.hasModifier(modifiers, 2 /* Private */);
            this.emitAccessorDeclarationComments(funcDecl);
            this.declFile.Write(this.getIndentString());
            this.emitClassElementModifiers(modifiers);
            this.declFile.Write(name.text());
            if (!isPrivate) {
                this.declFile.Write(" : ");
                var type = accessorSymbol.type;
                this.emitTypeSignature(funcDecl, type);
            }
            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.emitClassMembersFromConstructorDefinition = function (funcDecl) {
            var argsLen = funcDecl.callSignature.parameterList.parameters.nonSeparatorCount();
            if (TypeScript.lastParameterIsRest(funcDecl.callSignature.parameterList)) {
                argsLen--;
            }

            for (var i = 0; i < argsLen; i++) {
                var parameter = funcDecl.callSignature.parameterList.parameters.nonSeparatorAt(i);
                var parameterDecl = this.semanticInfoChain.getDeclForAST(parameter);
                if (TypeScript.hasFlag(parameterDecl.flags, 8388608 /* PropertyParameter */)) {
                    var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
                    this.emitDeclarationComments(parameter);
                    this.declFile.Write(this.getIndentString());
                    this.emitClassElementModifiers(parameter.modifiers);
                    this.declFile.Write(parameter.identifier.text());

                    if (!TypeScript.hasModifier(parameter.modifiers, 2 /* Private */)) {
                        this.emitTypeOfVariableDeclaratorOrParameter(parameter);
                    }
                    this.declFile.WriteLine(";");
                }
            }
        };

        DeclarationEmitter.prototype.emitDeclarationsForClassDeclaration = function (classDecl) {
            if (!this.canEmitDeclarations(classDecl)) {
                return;
            }

            var className = classDecl.identifier.text();
            this.emitDeclarationComments(classDecl);
            var classPullDecl = this.semanticInfoChain.getDeclForAST(classDecl);
            this.emitDeclFlags(classDecl, "class");
            this.declFile.Write(className);

            this.emitTypeParameters(classDecl.typeParameterList);
            this.emitHeritageClauses(classDecl.heritageClauses);
            this.declFile.WriteLine(" {");

            this.indenter.increaseIndent();
            var constructorDecl = TypeScript.getLastConstructor(classDecl);
            if (constructorDecl) {
                this.emitClassMembersFromConstructorDefinition(constructorDecl);
            }

            this.emitDeclarationsForList(classDecl.classElements);

            this.indenter.decreaseIndent();

            this.emitIndent();
            this.declFile.WriteLine("}");
        };

        DeclarationEmitter.prototype.emitHeritageClauses = function (clauses) {
            if (clauses) {
                for (var i = 0, n = clauses.childCount(); i < n; i++) {
                    this.emitHeritageClause(clauses.childAt(i));
                }
            }
        };

        DeclarationEmitter.prototype.emitHeritageClause = function (clause) {
            this.emitBaseList(clause.typeNames, clause.kind() === 230 /* ExtendsHeritageClause */);
        };

        DeclarationEmitter.getEnclosingContainer = function (ast) {
            var enclosingModule = TypeScript.ASTHelpers.getModuleDeclarationFromNameAST(ast);
            ast = enclosingModule || ast;

            ast = ast.parent;
            while (ast) {
                if (ast.kind() === 131 /* ClassDeclaration */ || ast.kind() === 128 /* InterfaceDeclaration */ || ast.kind() === 130 /* ModuleDeclaration */ || ast.kind() === 120 /* SourceUnit */) {
                    return ast;
                }

                ast = ast.parent;
            }

            return null;
        };

        DeclarationEmitter.prototype.emitTypeParameters = function (typeParams, funcSignature) {
            if (!typeParams || !typeParams.typeParameters.nonSeparatorCount()) {
                return;
            }

            this.declFile.Write("<");
            var containerAst = DeclarationEmitter.getEnclosingContainer(typeParams);

            var start = new Date().getTime();
            var containerDecl = this.semanticInfoChain.getDeclForAST(containerAst);
            var containerSymbol = containerDecl.getSymbol();
            TypeScript.declarationEmitGetTypeParameterSymbolTime += new Date().getTime() - start;

            var typars;
            if (funcSignature) {
                typars = funcSignature.getTypeParameters();
            } else {
                typars = containerSymbol.getTypeArgumentsOrTypeParameters();
            }

            for (var i = 0; i < typars.length; i++) {
                if (i) {
                    this.declFile.Write(", ");
                }

                var memberName = typars[i].getScopedNameEx(containerSymbol, false, true);
                this.emitTypeNamesMember(memberName);
            }

            this.declFile.Write(">");
        };

        DeclarationEmitter.prototype.emitDeclarationsForInterfaceDeclaration = function (interfaceDecl) {
            if (!this.canEmitDeclarations(interfaceDecl)) {
                return;
            }

            var interfaceName = interfaceDecl.identifier.text();
            this.emitDeclarationComments(interfaceDecl);
            var interfacePullDecl = this.semanticInfoChain.getDeclForAST(interfaceDecl);
            this.emitDeclFlags(interfaceDecl, "interface");
            this.declFile.Write(interfaceName);

            this.emitTypeParameters(interfaceDecl.typeParameterList);
            this.emitHeritageClauses(interfaceDecl.heritageClauses);
            this.declFile.WriteLine(" {");

            this.indenter.increaseIndent();

            this.emitSeparatedList(interfaceDecl.body.typeMembers);

            this.indenter.decreaseIndent();

            this.emitIndent();
            this.declFile.WriteLine("}");
        };

        DeclarationEmitter.prototype.emitDeclarationsForImportDeclaration = function (importDeclAST) {
            var importDecl = this.semanticInfoChain.getDeclForAST(importDeclAST);
            var importSymbol = importDecl.getSymbol();
            var isExportedImportDecl = TypeScript.hasModifier(importDeclAST.modifiers, 1 /* Exported */);

            if (isExportedImportDecl || importSymbol.typeUsedExternally() || TypeScript.PullContainerSymbol.usedAsSymbol(importSymbol.getContainer(), importSymbol)) {
                this.emitDeclarationComments(importDeclAST);
                this.emitIndent();
                if (isExportedImportDecl) {
                    this.declFile.Write("export ");
                }
                this.declFile.Write("import ");
                this.declFile.Write(importDeclAST.identifier.text() + " = ");
                if (importDeclAST.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                    this.declFile.WriteLine("require(" + importDeclAST.moduleReference.stringLiteral.text() + ");");
                } else {
                    this.declFile.WriteLine(TypeScript.ASTHelpers.getNameOfIdenfierOrQualifiedName(importDeclAST.moduleReference.moduleName) + ";");
                }
            }
        };

        DeclarationEmitter.prototype.emitDeclarationsForEnumDeclaration = function (moduleDecl) {
            if (!this.canEmitDeclarations(moduleDecl)) {
                return;
            }

            this.emitDeclarationComments(moduleDecl);
            var modulePullDecl = this.semanticInfoChain.getDeclForAST(moduleDecl);
            this.emitDeclFlags(moduleDecl, "enum");
            this.declFile.WriteLine(moduleDecl.identifier.text() + " {");

            this.indenter.increaseIndent();
            var membersLen = moduleDecl.enumElements.nonSeparatorCount();
            for (var j = 0; j < membersLen; j++) {
                var memberDecl = moduleDecl.enumElements.nonSeparatorAt(j);
                var enumElement = memberDecl;
                var enumElementDecl = this.semanticInfoChain.getDeclForAST(enumElement);
                this.emitDeclarationComments(enumElement);
                this.emitIndent();
                this.declFile.Write(enumElement.propertyName.text());
                if (enumElementDecl.constantValue !== null) {
                    this.declFile.Write(" = " + enumElementDecl.constantValue);
                }
                this.declFile.WriteLine(",");
            }
            this.indenter.decreaseIndent();

            this.emitIndent();
            this.declFile.WriteLine("}");
        };

        DeclarationEmitter.prototype.emitDeclarationsForModuleDeclaration = function (moduleDecl) {
            var name = moduleDecl.stringLiteral || TypeScript.ArrayUtilities.first(TypeScript.ASTHelpers.getModuleNames(moduleDecl.name));
            if (!this.canEmitDeclarations(name)) {
                return;
            }

            this.emitDeclarationComments(moduleDecl);
            this.emitDeclFlags(name, "module");

            if (moduleDecl.stringLiteral) {
                this.declFile.Write(moduleDecl.stringLiteral.text());
            } else {
                this.declFile.Write(TypeScript.ASTHelpers.getNameOfIdenfierOrQualifiedName(moduleDecl.name));
            }

            this.declFile.WriteLine(" {");
            this.indenter.increaseIndent();

            this.emitDeclarationsForList(moduleDecl.moduleElements);

            this.indenter.decreaseIndent();
            this.emitIndent();
            this.declFile.WriteLine("}");
        };

        DeclarationEmitter.prototype.emitDeclarationsForExportAssignment = function (ast) {
            this.emitIndent();
            this.declFile.Write("export = ");
            this.declFile.Write(ast.identifier.text());
            this.declFile.WriteLine(";");
        };

        DeclarationEmitter.prototype.resolveScriptReference = function (document, reference) {
            if (!this.emitOptions.compilationSettings().noResolve() || TypeScript.isRooted(reference)) {
                return reference;
            }

            var documentDir = TypeScript.convertToDirectoryPath(TypeScript.switchToForwardSlashes(TypeScript.getRootFilePath(document.fileName)));
            var resolvedReferencePath = this.emitOptions.resolvePath(documentDir + reference);
            return resolvedReferencePath;
        };

        DeclarationEmitter.prototype.emitReferencePaths = function (sourceUnit) {
            if (this.emittedReferencePaths) {
                return;
            }

            var documents = [];
            if (this.document.emitToOwnOutputFile()) {
                var scriptReferences = this.document.referencedFiles;
                var addedGlobalDocument = false;
                for (var j = 0; j < scriptReferences.length; j++) {
                    var currentReference = this.resolveScriptReference(this.document, scriptReferences[j]);
                    var document = this.compiler.getDocument(currentReference);

                    if (document && (document.emitToOwnOutputFile() || document.isDeclareFile() || !addedGlobalDocument)) {
                        documents = documents.concat(document);

                        if (!document.isDeclareFile() && document.isExternalModule()) {
                            addedGlobalDocument = true;
                        }
                    }
                }
            } else {
                var fileNames = this.compiler.fileNames();
                for (var i = 0; i < fileNames.length; i++) {
                    var doc = this.compiler.getDocument(fileNames[i]);
                    if (!doc.isDeclareFile() && !doc.isExternalModule()) {
                        var scriptReferences = doc.referencedFiles;
                        for (var j = 0; j < scriptReferences.length; j++) {
                            var currentReference = this.resolveScriptReference(doc, scriptReferences[j]);
                            var document = this.compiler.getDocument(currentReference);

                            if (document && (document.isDeclareFile() || document.isExternalModule())) {
                                for (var k = 0; k < documents.length; k++) {
                                    if (documents[k] === document) {
                                        break;
                                    }
                                }

                                if (k === documents.length) {
                                    documents = documents.concat(document);
                                }
                            }
                        }
                    }
                }
            }

            var emittingFilePath = documents.length ? TypeScript.getRootFilePath(this.emittingFileName) : null;
            for (var i = 0; i < documents.length; i++) {
                var document = documents[i];
                var declFileName;
                if (document.isDeclareFile()) {
                    declFileName = document.fileName;
                } else {
                    declFileName = this.compiler.mapOutputFileName(document, this.emitOptions, TypeScript.TypeScriptCompiler.mapToDTSFileName);
                }

                declFileName = TypeScript.getRelativePathToFixedPath(emittingFilePath, declFileName, false);
                this.declFile.WriteLine('/// <reference path="' + declFileName + '" />');
            }

            this.emittedReferencePaths = true;
        };

        DeclarationEmitter.prototype.emitDeclarationsForSourceUnit = function (sourceUnit) {
            this.emitReferencePaths(sourceUnit);
            this.emitDeclarationsForList(sourceUnit.moduleElements);
        };
        return DeclarationEmitter;
    })();
    TypeScript.DeclarationEmitter = DeclarationEmitter;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var BloomFilter = (function () {
        function BloomFilter(expectedCount) {
            var m = Math.max(1, BloomFilter.computeM(expectedCount));
            var k = Math.max(1, BloomFilter.computeK(expectedCount));
            ;

            var sizeInEvenBytes = (m + 7) & ~7;

            this.bitArray = [];
            for (var i = 0, len = sizeInEvenBytes; i < len; i++) {
                this.bitArray[i] = false;
            }
            this.hashFunctionCount = k;
        }
        BloomFilter.computeM = function (expectedCount) {
            var p = BloomFilter.falsePositiveProbability;
            var n = expectedCount;

            var numerator = n * Math.log(p);
            var denominator = Math.log(1.0 / Math.pow(2.0, Math.log(2.0)));
            return Math.ceil(numerator / denominator);
        };

        BloomFilter.computeK = function (expectedCount) {
            var n = expectedCount;
            var m = BloomFilter.computeM(expectedCount);

            var temp = Math.log(2.0) * m / n;
            return Math.round(temp);
        };

        BloomFilter.prototype.computeHash = function (key, seed) {
            return TypeScript.Hash.computeMurmur2StringHashCode(key, seed);
        };

        BloomFilter.prototype.addKeys = function (keys) {
            for (var name in keys) {
                if (keys[name]) {
                    this.add(name);
                }
            }
        };

        BloomFilter.prototype.add = function (value) {
            for (var i = 0; i < this.hashFunctionCount; i++) {
                var hash = this.computeHash(value, i);
                hash = hash % this.bitArray.length;
                this.bitArray[Math.abs(hash)] = true;
            }
        };

        BloomFilter.prototype.probablyContains = function (value) {
            for (var i = 0; i < this.hashFunctionCount; i++) {
                var hash = this.computeHash(value, i);
                hash = hash % this.bitArray.length;
                if (!this.bitArray[Math.abs(hash)]) {
                    return false;
                }
            }

            return true;
        };

        BloomFilter.prototype.isEquivalent = function (filter) {
            return BloomFilter.isEquivalent(this.bitArray, filter.bitArray) && this.hashFunctionCount === filter.hashFunctionCount;
        };

        BloomFilter.isEquivalent = function (array1, array2) {
            if (array1.length !== array2.length) {
                return false;
            }

            for (var i = 0; i < array1.length; i++) {
                if (array1[i] !== array2[i]) {
                    return false;
                }
            }

            return true;
        };
        BloomFilter.falsePositiveProbability = 0.0001;
        return BloomFilter;
    })();
    TypeScript.BloomFilter = BloomFilter;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var IdentifierWalker = (function (_super) {
        __extends(IdentifierWalker, _super);
        function IdentifierWalker(list) {
            _super.call(this);
            this.list = list;
        }
        IdentifierWalker.prototype.visitToken = function (token) {
            this.list[token.text()] = true;
        };
        return IdentifierWalker;
    })(TypeScript.SyntaxWalker);
    TypeScript.IdentifierWalker = IdentifierWalker;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var CompilationSettings = (function () {
        function CompilationSettings() {
            this.propagateEnumConstants = false;
            this.removeComments = false;
            this.watch = false;
            this.noResolve = false;
            this.allowAutomaticSemicolonInsertion = true;
            this.noImplicitAny = false;
            this.noLib = false;
            this.codeGenTarget = 0 /* EcmaScript3 */;
            this.moduleGenTarget = 0 /* Unspecified */;
            this.outFileOption = "";
            this.outDirOption = "";
            this.mapSourceFiles = false;
            this.mapRoot = "";
            this.sourceRoot = "";
            this.generateDeclarationFiles = false;
            this.useCaseSensitiveFileResolution = false;
            this.gatherDiagnostics = false;
            this.codepage = null;
            this.createFileLog = false;
        }
        return CompilationSettings;
    })();
    TypeScript.CompilationSettings = CompilationSettings;

    var ImmutableCompilationSettings = (function () {
        function ImmutableCompilationSettings(propagateEnumConstants, removeComments, watch, noResolve, allowAutomaticSemicolonInsertion, noImplicitAny, noLib, codeGenTarget, moduleGenTarget, outFileOption, outDirOption, mapSourceFiles, mapRoot, sourceRoot, generateDeclarationFiles, useCaseSensitiveFileResolution, gatherDiagnostics, codepage, createFileLog) {
            this._propagateEnumConstants = propagateEnumConstants;
            this._removeComments = removeComments;
            this._watch = watch;
            this._noResolve = noResolve;
            this._allowAutomaticSemicolonInsertion = allowAutomaticSemicolonInsertion;
            this._noImplicitAny = noImplicitAny;
            this._noLib = noLib;
            this._codeGenTarget = codeGenTarget;
            this._moduleGenTarget = moduleGenTarget;
            this._outFileOption = outFileOption;
            this._outDirOption = outDirOption;
            this._mapSourceFiles = mapSourceFiles;
            this._mapRoot = mapRoot;
            this._sourceRoot = sourceRoot;
            this._generateDeclarationFiles = generateDeclarationFiles;
            this._useCaseSensitiveFileResolution = useCaseSensitiveFileResolution;
            this._gatherDiagnostics = gatherDiagnostics;
            this._codepage = codepage;
            this._createFileLog = createFileLog;
        }
        ImmutableCompilationSettings.prototype.propagateEnumConstants = function () {
            return this._propagateEnumConstants;
        };
        ImmutableCompilationSettings.prototype.removeComments = function () {
            return this._removeComments;
        };
        ImmutableCompilationSettings.prototype.watch = function () {
            return this._watch;
        };
        ImmutableCompilationSettings.prototype.noResolve = function () {
            return this._noResolve;
        };
        ImmutableCompilationSettings.prototype.allowAutomaticSemicolonInsertion = function () {
            return this._allowAutomaticSemicolonInsertion;
        };
        ImmutableCompilationSettings.prototype.noImplicitAny = function () {
            return this._noImplicitAny;
        };
        ImmutableCompilationSettings.prototype.noLib = function () {
            return this._noLib;
        };
        ImmutableCompilationSettings.prototype.codeGenTarget = function () {
            return this._codeGenTarget;
        };
        ImmutableCompilationSettings.prototype.moduleGenTarget = function () {
            return this._moduleGenTarget;
        };
        ImmutableCompilationSettings.prototype.outFileOption = function () {
            return this._outFileOption;
        };
        ImmutableCompilationSettings.prototype.outDirOption = function () {
            return this._outDirOption;
        };
        ImmutableCompilationSettings.prototype.mapSourceFiles = function () {
            return this._mapSourceFiles;
        };
        ImmutableCompilationSettings.prototype.mapRoot = function () {
            return this._mapRoot;
        };
        ImmutableCompilationSettings.prototype.sourceRoot = function () {
            return this._sourceRoot;
        };
        ImmutableCompilationSettings.prototype.generateDeclarationFiles = function () {
            return this._generateDeclarationFiles;
        };
        ImmutableCompilationSettings.prototype.useCaseSensitiveFileResolution = function () {
            return this._useCaseSensitiveFileResolution;
        };
        ImmutableCompilationSettings.prototype.gatherDiagnostics = function () {
            return this._gatherDiagnostics;
        };
        ImmutableCompilationSettings.prototype.codepage = function () {
            return this._codepage;
        };
        ImmutableCompilationSettings.prototype.createFileLog = function () {
            return this._createFileLog;
        };

        ImmutableCompilationSettings.defaultSettings = function () {
            if (!ImmutableCompilationSettings._defaultSettings) {
                ImmutableCompilationSettings._defaultSettings = ImmutableCompilationSettings.fromCompilationSettings(new CompilationSettings());
            }

            return ImmutableCompilationSettings._defaultSettings;
        };

        ImmutableCompilationSettings.fromCompilationSettings = function (settings) {
            return new ImmutableCompilationSettings(settings.propagateEnumConstants, settings.removeComments, settings.watch, settings.noResolve, settings.allowAutomaticSemicolonInsertion, settings.noImplicitAny, settings.noLib, settings.codeGenTarget, settings.moduleGenTarget, settings.outFileOption, settings.outDirOption, settings.mapSourceFiles, settings.mapRoot, settings.sourceRoot, settings.generateDeclarationFiles, settings.useCaseSensitiveFileResolution, settings.gatherDiagnostics, settings.codepage, settings.createFileLog);
        };

        ImmutableCompilationSettings.prototype.toCompilationSettings = function () {
            var result = new CompilationSettings();

            var thisAsIndexable = this;
            var resultAsIndexable = result;
            for (var name in this) {
                if (this.hasOwnProperty(name) && TypeScript.StringUtilities.startsWith(name, "_")) {
                    resultAsIndexable[name.substr(1)] = thisAsIndexable[name];
                }
            }

            return result;
        };
        return ImmutableCompilationSettings;
    })();
    TypeScript.ImmutableCompilationSettings = ImmutableCompilationSettings;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (PullElementFlags) {
        PullElementFlags[PullElementFlags["None"] = 0] = "None";
        PullElementFlags[PullElementFlags["Exported"] = 1] = "Exported";
        PullElementFlags[PullElementFlags["Private"] = 1 << 1] = "Private";
        PullElementFlags[PullElementFlags["Public"] = 1 << 2] = "Public";
        PullElementFlags[PullElementFlags["Ambient"] = 1 << 3] = "Ambient";
        PullElementFlags[PullElementFlags["Static"] = 1 << 4] = "Static";
        PullElementFlags[PullElementFlags["Optional"] = 1 << 7] = "Optional";
        PullElementFlags[PullElementFlags["Signature"] = 1 << 11] = "Signature";
        PullElementFlags[PullElementFlags["Enum"] = 1 << 12] = "Enum";
        PullElementFlags[PullElementFlags["ArrowFunction"] = 1 << 13] = "ArrowFunction";

        PullElementFlags[PullElementFlags["ClassConstructorVariable"] = 1 << 14] = "ClassConstructorVariable";
        PullElementFlags[PullElementFlags["InitializedModule"] = 1 << 15] = "InitializedModule";
        PullElementFlags[PullElementFlags["InitializedDynamicModule"] = 1 << 16] = "InitializedDynamicModule";

        PullElementFlags[PullElementFlags["MustCaptureThis"] = 1 << 18] = "MustCaptureThis";

        PullElementFlags[PullElementFlags["DeclaredInAWithBlock"] = 1 << 21] = "DeclaredInAWithBlock";

        PullElementFlags[PullElementFlags["HasReturnStatement"] = 1 << 22] = "HasReturnStatement";

        PullElementFlags[PullElementFlags["PropertyParameter"] = 1 << 23] = "PropertyParameter";

        PullElementFlags[PullElementFlags["IsAnnotatedWithAny"] = 1 << 24] = "IsAnnotatedWithAny";

        PullElementFlags[PullElementFlags["HasDefaultArgs"] = 1 << 25] = "HasDefaultArgs";

        PullElementFlags[PullElementFlags["ConstructorParameter"] = 1 << 26] = "ConstructorParameter";

        PullElementFlags[PullElementFlags["ImplicitVariable"] = PullElementFlags.ClassConstructorVariable | PullElementFlags.InitializedModule | PullElementFlags.InitializedDynamicModule | PullElementFlags.Enum] = "ImplicitVariable";
        PullElementFlags[PullElementFlags["SomeInitializedModule"] = PullElementFlags.InitializedModule | PullElementFlags.InitializedDynamicModule | PullElementFlags.Enum] = "SomeInitializedModule";
    })(TypeScript.PullElementFlags || (TypeScript.PullElementFlags = {}));
    var PullElementFlags = TypeScript.PullElementFlags;

    function hasModifier(modifiers, flag) {
        for (var i = 0, n = modifiers.length; i < n; i++) {
            if (TypeScript.hasFlag(modifiers[i], flag)) {
                return true;
            }
        }

        return false;
    }
    TypeScript.hasModifier = hasModifier;

    (function (PullElementKind) {
        PullElementKind[PullElementKind["None"] = 0] = "None";
        PullElementKind[PullElementKind["Global"] = 0] = "Global";

        PullElementKind[PullElementKind["Script"] = 1 << 0] = "Script";
        PullElementKind[PullElementKind["Primitive"] = 1 << 1] = "Primitive";

        PullElementKind[PullElementKind["Container"] = 1 << 2] = "Container";
        PullElementKind[PullElementKind["Class"] = 1 << 3] = "Class";
        PullElementKind[PullElementKind["Interface"] = 1 << 4] = "Interface";
        PullElementKind[PullElementKind["DynamicModule"] = 1 << 5] = "DynamicModule";
        PullElementKind[PullElementKind["Enum"] = 1 << 6] = "Enum";
        PullElementKind[PullElementKind["TypeAlias"] = 1 << 7] = "TypeAlias";
        PullElementKind[PullElementKind["ObjectLiteral"] = 1 << 8] = "ObjectLiteral";

        PullElementKind[PullElementKind["Variable"] = 1 << 9] = "Variable";
        PullElementKind[PullElementKind["CatchVariable"] = 1 << 10] = "CatchVariable";
        PullElementKind[PullElementKind["Parameter"] = 1 << 11] = "Parameter";
        PullElementKind[PullElementKind["Property"] = 1 << 12] = "Property";
        PullElementKind[PullElementKind["TypeParameter"] = 1 << 13] = "TypeParameter";

        PullElementKind[PullElementKind["Function"] = 1 << 14] = "Function";
        PullElementKind[PullElementKind["ConstructorMethod"] = 1 << 15] = "ConstructorMethod";
        PullElementKind[PullElementKind["Method"] = 1 << 16] = "Method";
        PullElementKind[PullElementKind["FunctionExpression"] = 1 << 17] = "FunctionExpression";

        PullElementKind[PullElementKind["GetAccessor"] = 1 << 18] = "GetAccessor";
        PullElementKind[PullElementKind["SetAccessor"] = 1 << 19] = "SetAccessor";

        PullElementKind[PullElementKind["CallSignature"] = 1 << 20] = "CallSignature";
        PullElementKind[PullElementKind["ConstructSignature"] = 1 << 21] = "ConstructSignature";
        PullElementKind[PullElementKind["IndexSignature"] = 1 << 22] = "IndexSignature";

        PullElementKind[PullElementKind["ObjectType"] = 1 << 23] = "ObjectType";
        PullElementKind[PullElementKind["FunctionType"] = 1 << 24] = "FunctionType";
        PullElementKind[PullElementKind["ConstructorType"] = 1 << 25] = "ConstructorType";

        PullElementKind[PullElementKind["EnumMember"] = 1 << 26] = "EnumMember";

        PullElementKind[PullElementKind["WithBlock"] = 1 << 27] = "WithBlock";
        PullElementKind[PullElementKind["CatchBlock"] = 1 << 28] = "CatchBlock";

        PullElementKind[PullElementKind["All"] = PullElementKind.Script | PullElementKind.Global | PullElementKind.Primitive | PullElementKind.Container | PullElementKind.Class | PullElementKind.Interface | PullElementKind.DynamicModule | PullElementKind.Enum | PullElementKind.TypeAlias | PullElementKind.ObjectLiteral | PullElementKind.Variable | PullElementKind.Parameter | PullElementKind.Property | PullElementKind.TypeParameter | PullElementKind.Function | PullElementKind.ConstructorMethod | PullElementKind.Method | PullElementKind.FunctionExpression | PullElementKind.GetAccessor | PullElementKind.SetAccessor | PullElementKind.CallSignature | PullElementKind.ConstructSignature | PullElementKind.IndexSignature | PullElementKind.ObjectType | PullElementKind.FunctionType | PullElementKind.ConstructorType | PullElementKind.EnumMember | PullElementKind.WithBlock | PullElementKind.CatchBlock] = "All";

        PullElementKind[PullElementKind["SomeFunction"] = PullElementKind.Function | PullElementKind.ConstructorMethod | PullElementKind.Method | PullElementKind.FunctionExpression | PullElementKind.GetAccessor | PullElementKind.SetAccessor] = "SomeFunction";

        PullElementKind[PullElementKind["SomeValue"] = PullElementKind.Variable | PullElementKind.Parameter | PullElementKind.Property | PullElementKind.EnumMember | PullElementKind.SomeFunction] = "SomeValue";

        PullElementKind[PullElementKind["SomeType"] = PullElementKind.Script | PullElementKind.Global | PullElementKind.Primitive | PullElementKind.Class | PullElementKind.Interface | PullElementKind.Enum | PullElementKind.ObjectLiteral | PullElementKind.ObjectType | PullElementKind.FunctionType | PullElementKind.ConstructorType | PullElementKind.TypeParameter] = "SomeType";

        PullElementKind[PullElementKind["AcceptableAlias"] = PullElementKind.Variable | PullElementKind.SomeFunction | PullElementKind.Class | PullElementKind.Interface | PullElementKind.Enum | PullElementKind.Container | PullElementKind.ObjectType | PullElementKind.FunctionType | PullElementKind.ConstructorType] = "AcceptableAlias";

        PullElementKind[PullElementKind["SomeContainer"] = PullElementKind.Container | PullElementKind.DynamicModule | PullElementKind.TypeAlias] = "SomeContainer";

        PullElementKind[PullElementKind["SomeSignature"] = PullElementKind.CallSignature | PullElementKind.ConstructSignature | PullElementKind.IndexSignature] = "SomeSignature";

        PullElementKind[PullElementKind["SomeTypeReference"] = PullElementKind.Interface | PullElementKind.ObjectType | PullElementKind.FunctionType | PullElementKind.ConstructorType] = "SomeTypeReference";

        PullElementKind[PullElementKind["SomeInstantiatableType"] = PullElementKind.Class | PullElementKind.Interface | PullElementKind.TypeParameter] = "SomeInstantiatableType";
    })(TypeScript.PullElementKind || (TypeScript.PullElementKind = {}));
    var PullElementKind = TypeScript.PullElementKind;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var pullDeclID = 0;
    var sentinelEmptyPullDeclArray = [];

    var PullDecl = (function () {
        function PullDecl(declName, displayName, kind, declFlags, semanticInfoChain) {
            this.declID = pullDeclID++;
            this.flags = 0 /* None */;
            this.declGroups = null;
            this.childDecls = null;
            this.typeParameters = null;
            this.synthesizedValDecl = null;
            this.containerDecl = null;
            this.childDeclTypeCache = null;
            this.childDeclValueCache = null;
            this.childDeclNamespaceCache = null;
            this.childDeclTypeParameterCache = null;
            this.name = declName;
            this.kind = kind;
            this.flags = declFlags;
            this.semanticInfoChain = semanticInfoChain;

            if (displayName !== this.name) {
                this.declDisplayName = displayName;
            }
        }
        PullDecl.prototype.fileName = function () {
            throw TypeScript.Errors.abstract();
        };

        PullDecl.prototype.getParentPath = function () {
            throw TypeScript.Errors.abstract();
        };

        PullDecl.prototype.getParentDecl = function () {
            throw TypeScript.Errors.abstract();
        };

        PullDecl.prototype.isExternalModule = function () {
            throw TypeScript.Errors.abstract();
        };

        PullDecl.prototype.getEnclosingDecl = function () {
            throw TypeScript.Errors.abstract();
        };

        PullDecl.prototype._getEnclosingDeclFromParentDecl = function () {
            var decl = this;
            while (decl) {
                switch (decl.kind) {
                    default:
                        return decl;
                    case 512 /* Variable */:
                    case 8192 /* TypeParameter */:
                    case 2048 /* Parameter */:
                    case 128 /* TypeAlias */:
                    case 67108864 /* EnumMember */:
                }

                decl = decl.getParentDecl();
            }

            TypeScript.Debug.fail();
        };

        PullDecl.prototype.getDisplayName = function () {
            return this.declDisplayName === undefined ? this.name : this.declDisplayName;
        };

        PullDecl.prototype.setSymbol = function (symbol) {
            this.semanticInfoChain.setSymbolForDecl(this, symbol);
        };

        PullDecl.prototype.ensureSymbolIsBound = function () {
            if (!this.hasBeenBound() && this.kind !== 1 /* Script */) {
                var binder = this.semanticInfoChain.getBinder();
                binder.bindDeclToPullSymbol(this);
            }
        };

        PullDecl.prototype.getSymbol = function () {
            if (this.kind === 1 /* Script */) {
                return null;
            }

            this.ensureSymbolIsBound();

            return this.semanticInfoChain.getSymbolForDecl(this);
        };

        PullDecl.prototype.hasSymbol = function () {
            var symbol = this.semanticInfoChain.getSymbolForDecl(this);
            return !!symbol;
        };

        PullDecl.prototype.setSignatureSymbol = function (signatureSymbol) {
            this.semanticInfoChain.setSignatureSymbolForDecl(this, signatureSymbol);
        };

        PullDecl.prototype.getSignatureSymbol = function () {
            this.ensureSymbolIsBound();
            return this.semanticInfoChain.getSignatureSymbolForDecl(this);
        };

        PullDecl.prototype.hasSignatureSymbol = function () {
            var signatureSymbol = this.semanticInfoChain.getSignatureSymbolForDecl(this);
            return !!signatureSymbol;
        };

        PullDecl.prototype.setFlags = function (flags) {
            this.flags = flags;
        };

        PullDecl.prototype.setFlag = function (flags) {
            this.flags |= flags;
        };

        PullDecl.prototype.setValueDecl = function (valDecl) {
            this.synthesizedValDecl = valDecl;
            valDecl.containerDecl = this;
        };

        PullDecl.prototype.getValueDecl = function () {
            return this.synthesizedValDecl;
        };

        PullDecl.prototype.getContainerDecl = function () {
            return this.containerDecl;
        };

        PullDecl.prototype.getChildDeclCache = function (declKind) {
            if (declKind === 8192 /* TypeParameter */) {
                if (!this.childDeclTypeParameterCache) {
                    this.childDeclTypeParameterCache = TypeScript.createIntrinsicsObject();
                }

                return this.childDeclTypeParameterCache;
            } else if (TypeScript.hasFlag(declKind, 164 /* SomeContainer */)) {
                if (!this.childDeclNamespaceCache) {
                    this.childDeclNamespaceCache = TypeScript.createIntrinsicsObject();
                }

                return this.childDeclNamespaceCache;
            } else if (TypeScript.hasFlag(declKind, 58728795 /* SomeType */)) {
                if (!this.childDeclTypeCache) {
                    this.childDeclTypeCache = TypeScript.createIntrinsicsObject();
                }

                return this.childDeclTypeCache;
            } else {
                if (!this.childDeclValueCache) {
                    this.childDeclValueCache = TypeScript.createIntrinsicsObject();
                }

                return this.childDeclValueCache;
            }
        };

        PullDecl.prototype.addChildDecl = function (childDecl) {
            if (childDecl.kind === 8192 /* TypeParameter */) {
                if (!this.typeParameters) {
                    this.typeParameters = [];
                }
                this.typeParameters[this.typeParameters.length] = childDecl;
            } else {
                if (!this.childDecls) {
                    this.childDecls = [];
                }
                this.childDecls[this.childDecls.length] = childDecl;
            }

            var declName = childDecl.name;

            if (!(childDecl.kind & 7340032 /* SomeSignature */)) {
                var cache = this.getChildDeclCache(childDecl.kind);
                var childrenOfName = cache[declName];
                if (!childrenOfName) {
                    childrenOfName = [];
                }

                childrenOfName.push(childDecl);
                cache[declName] = childrenOfName;
            }
        };

        PullDecl.prototype.searchChildDecls = function (declName, searchKind) {
            var cacheVal = null;

            if (searchKind & 58728795 /* SomeType */) {
                cacheVal = this.childDeclTypeCache ? this.childDeclTypeCache[declName] : null;
            } else if (searchKind & 164 /* SomeContainer */) {
                cacheVal = this.childDeclNamespaceCache ? this.childDeclNamespaceCache[declName] : null;
            } else {
                cacheVal = this.childDeclValueCache ? this.childDeclValueCache[declName] : null;
            }

            if (cacheVal) {
                return cacheVal;
            } else {
                if (searchKind & 58728795 /* SomeType */) {
                    cacheVal = this.childDeclTypeParameterCache ? this.childDeclTypeParameterCache[declName] : null;

                    if (cacheVal) {
                        return cacheVal;
                    }
                }

                return sentinelEmptyPullDeclArray;
            }
        };

        PullDecl.prototype.getChildDecls = function () {
            return this.childDecls || sentinelEmptyPullDeclArray;
        };

        PullDecl.prototype.getTypeParameters = function () {
            return this.typeParameters || sentinelEmptyPullDeclArray;
        };

        PullDecl.prototype.addVariableDeclToGroup = function (decl) {
            if (!this.declGroups) {
                this.declGroups = TypeScript.createIntrinsicsObject();
            }

            var declGroup = this.declGroups[decl.name];
            if (declGroup) {
                declGroup.addDecl(decl);
            } else {
                declGroup = new PullDeclGroup(decl.name);
                declGroup.addDecl(decl);
                this.declGroups[decl.name] = declGroup;
            }
        };

        PullDecl.prototype.getVariableDeclGroups = function () {
            var declGroups = null;

            if (this.declGroups) {
                for (var declName in this.declGroups) {
                    if (this.declGroups[declName]) {
                        if (declGroups === null) {
                            declGroups = [];
                        }

                        declGroups.push(this.declGroups[declName].getDecls());
                    }
                }
            }

            return declGroups || sentinelEmptyPullDeclArray;
        };

        PullDecl.prototype.hasBeenBound = function () {
            return this.hasSymbol() || this.hasSignatureSymbol();
        };

        PullDecl.prototype.isSynthesized = function () {
            return false;
        };

        PullDecl.prototype.ast = function () {
            return this.semanticInfoChain.getASTForDecl(this);
        };

        PullDecl.prototype.isRootDecl = function () {
            throw TypeScript.Errors.abstract();
        };
        return PullDecl;
    })();
    TypeScript.PullDecl = PullDecl;

    var RootPullDecl = (function (_super) {
        __extends(RootPullDecl, _super);
        function RootPullDecl(name, fileName, kind, declFlags, semanticInfoChain, isExternalModule) {
            _super.call(this, name, name, kind, declFlags, semanticInfoChain);
            this.semanticInfoChain = semanticInfoChain;
            this._isExternalModule = isExternalModule;
            this._fileName = fileName;
        }
        RootPullDecl.prototype.fileName = function () {
            return this._fileName;
        };

        RootPullDecl.prototype.getParentPath = function () {
            return [this];
        };

        RootPullDecl.prototype.getParentDecl = function () {
            return null;
        };

        RootPullDecl.prototype.isExternalModule = function () {
            return this._isExternalModule;
        };

        RootPullDecl.prototype.getEnclosingDecl = function () {
            return this;
        };

        RootPullDecl.prototype.isRootDecl = function () {
            return true;
        };
        return RootPullDecl;
    })(PullDecl);
    TypeScript.RootPullDecl = RootPullDecl;

    var NormalPullDecl = (function (_super) {
        __extends(NormalPullDecl, _super);
        function NormalPullDecl(declName, displayName, kind, declFlags, parentDecl, addToParent) {
            if (typeof addToParent === "undefined") { addToParent = true; }
            _super.call(this, declName, displayName, kind, declFlags, parentDecl ? parentDecl.semanticInfoChain : null);
            this.parentDecl = null;
            this.parentPath = null;

            this.parentDecl = parentDecl;
            if (addToParent) {
                parentDecl.addChildDecl(this);
            }

            if (this.parentDecl) {
                if (this.parentDecl.isRootDecl()) {
                    this._rootDecl = this.parentDecl;
                } else {
                    this._rootDecl = this.parentDecl._rootDecl;
                }
            } else {
                TypeScript.Debug.assert(this.isSynthesized());
                this._rootDecl = null;
            }
        }
        NormalPullDecl.prototype.fileName = function () {
            return this._rootDecl.fileName();
        };

        NormalPullDecl.prototype.getParentDecl = function () {
            return this.parentDecl;
        };

        NormalPullDecl.prototype.getParentPath = function () {
            if (!this.parentPath) {
                var path = [this];
                var parentDecl = this.parentDecl;

                while (parentDecl) {
                    if (parentDecl && path[path.length - 1] !== parentDecl && !(parentDecl.kind & (256 /* ObjectLiteral */ | 8388608 /* ObjectType */))) {
                        path.unshift(parentDecl);
                    }

                    parentDecl = parentDecl.getParentDecl();
                }

                this.parentPath = path;
            }

            return this.parentPath;
        };

        NormalPullDecl.prototype.isExternalModule = function () {
            return false;
        };

        NormalPullDecl.prototype.getEnclosingDecl = function () {
            return this.parentDecl && this.parentDecl._getEnclosingDeclFromParentDecl();
        };

        NormalPullDecl.prototype.isRootDecl = function () {
            return false;
        };
        return NormalPullDecl;
    })(PullDecl);
    TypeScript.NormalPullDecl = NormalPullDecl;

    var PullEnumElementDecl = (function (_super) {
        __extends(PullEnumElementDecl, _super);
        function PullEnumElementDecl(declName, displayName, parentDecl) {
            _super.call(this, declName, displayName, 67108864 /* EnumMember */, 4 /* Public */, parentDecl);
            this.constantValue = null;
        }
        return PullEnumElementDecl;
    })(NormalPullDecl);
    TypeScript.PullEnumElementDecl = PullEnumElementDecl;

    var PullFunctionExpressionDecl = (function (_super) {
        __extends(PullFunctionExpressionDecl, _super);
        function PullFunctionExpressionDecl(expressionName, declFlags, parentDecl, displayName) {
            if (typeof displayName === "undefined") { displayName = ""; }
            _super.call(this, "", displayName, 131072 /* FunctionExpression */, declFlags, parentDecl);
            this.functionExpressionName = expressionName;
        }
        PullFunctionExpressionDecl.prototype.getFunctionExpressionName = function () {
            return this.functionExpressionName;
        };
        return PullFunctionExpressionDecl;
    })(NormalPullDecl);
    TypeScript.PullFunctionExpressionDecl = PullFunctionExpressionDecl;

    var PullSynthesizedDecl = (function (_super) {
        __extends(PullSynthesizedDecl, _super);
        function PullSynthesizedDecl(declName, displayName, kind, declFlags, parentDecl, semanticInfoChain) {
            _super.call(this, declName, displayName, kind, declFlags, parentDecl, false);
            this.semanticInfoChain = semanticInfoChain;
        }
        PullSynthesizedDecl.prototype.isSynthesized = function () {
            return true;
        };

        PullSynthesizedDecl.prototype.fileName = function () {
            return this._rootDecl ? this._rootDecl.fileName() : "";
        };
        return PullSynthesizedDecl;
    })(NormalPullDecl);
    TypeScript.PullSynthesizedDecl = PullSynthesizedDecl;

    var PullDeclGroup = (function () {
        function PullDeclGroup(name) {
            this.name = name;
            this._decls = [];
        }
        PullDeclGroup.prototype.addDecl = function (decl) {
            if (decl.name === this.name) {
                this._decls[this._decls.length] = decl;
            }
        };

        PullDeclGroup.prototype.getDecls = function () {
            return this._decls;
        };
        return PullDeclGroup;
    })();
    TypeScript.PullDeclGroup = PullDeclGroup;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    TypeScript.pullSymbolID = 0;
    TypeScript.sentinelEmptyArray = [];

    var PullSymbol = (function () {
        function PullSymbol(name, declKind) {
            this.pullSymbolID = ++TypeScript.pullSymbolID;
            this._container = null;
            this.type = null;
            this._declarations = null;
            this.isResolved = false;
            this.isOptional = false;
            this.inResolution = false;
            this.isSynthesized = false;
            this.isVarArg = false;
            this.rootSymbol = null;
            this._enclosingSignature = null;
            this._docComments = null;
            this.isPrinting = false;
            this.name = name;
            this.kind = declKind;
        }
        PullSymbol.prototype.isAny = function () {
            return false;
        };

        PullSymbol.prototype.isType = function () {
            return (this.kind & 58728795 /* SomeType */) !== 0;
        };

        PullSymbol.prototype.isTypeReference = function () {
            return false;
        };

        PullSymbol.prototype.isSignature = function () {
            return (this.kind & 7340032 /* SomeSignature */) !== 0;
        };

        PullSymbol.prototype.isArrayNamedTypeReference = function () {
            return false;
        };

        PullSymbol.prototype.isPrimitive = function () {
            return this.kind === 2 /* Primitive */;
        };

        PullSymbol.prototype.isAccessor = function () {
            return false;
        };

        PullSymbol.prototype.isError = function () {
            return false;
        };

        PullSymbol.prototype.isInterface = function () {
            return this.kind === 16 /* Interface */;
        };

        PullSymbol.prototype.isMethod = function () {
            return this.kind === 65536 /* Method */;
        };

        PullSymbol.prototype.isProperty = function () {
            return this.kind === 4096 /* Property */;
        };

        PullSymbol.prototype.isAlias = function () {
            return false;
        };

        PullSymbol.prototype.isContainer = function () {
            return false;
        };

        PullSymbol.prototype.findAliasedTypeSymbols = function (scopeSymbol, skipScopeSymbolAliasesLookIn, lookIntoOnlyExportedAlias, aliasSymbols, visitedScopeDeclarations) {
            if (typeof aliasSymbols === "undefined") { aliasSymbols = []; }
            if (typeof visitedScopeDeclarations === "undefined") { visitedScopeDeclarations = []; }
            var scopeDeclarations = scopeSymbol.getDeclarations();
            var scopeSymbolAliasesToLookIn = [];

            for (var i = 0; i < scopeDeclarations.length; i++) {
                var scopeDecl = scopeDeclarations[i];
                if (!TypeScript.ArrayUtilities.contains(visitedScopeDeclarations, scopeDecl)) {
                    visitedScopeDeclarations.push(scopeDecl);

                    var childDecls = scopeDecl.getChildDecls();
                    for (var j = 0; j < childDecls.length; j++) {
                        var childDecl = childDecls[j];
                        if (childDecl.kind === 128 /* TypeAlias */ && (!lookIntoOnlyExportedAlias || (childDecl.flags & 1 /* Exported */))) {
                            var symbol = childDecl.getSymbol();

                            if (PullContainerSymbol.usedAsSymbol(symbol, this) || (this.rootSymbol && PullContainerSymbol.usedAsSymbol(symbol, this.rootSymbol))) {
                                aliasSymbols.push(symbol);
                                return aliasSymbols;
                            }

                            if (!skipScopeSymbolAliasesLookIn && PullSymbol._isExternalModuleReferenceAlias(symbol) && (!symbol.assignedContainer().hasExportAssignment() || (symbol.assignedContainer().getExportAssignedContainerSymbol() && symbol.assignedContainer().getExportAssignedContainerSymbol().kind === 32 /* DynamicModule */))) {
                                scopeSymbolAliasesToLookIn.push(symbol);
                            }
                        }
                    }
                }
            }

            for (var i = 0; i < scopeSymbolAliasesToLookIn.length; i++) {
                var scopeSymbolAlias = scopeSymbolAliasesToLookIn[i];

                aliasSymbols.push(scopeSymbolAlias);
                var result = this.findAliasedTypeSymbols(scopeSymbolAlias.assignedContainer().hasExportAssignment() ? scopeSymbolAlias.assignedContainer().getExportAssignedContainerSymbol() : scopeSymbolAlias.assignedContainer(), false, true, aliasSymbols, visitedScopeDeclarations);
                if (result) {
                    return result;
                }

                aliasSymbols.pop();
            }

            return null;
        };

        PullSymbol.prototype.getExternalAliasedSymbols = function (scopeSymbol) {
            if (!scopeSymbol) {
                return null;
            }

            var scopePath = scopeSymbol.pathToRoot();
            if (scopePath.length && scopePath[scopePath.length - 1].kind === 32 /* DynamicModule */) {
                var symbols = this.findAliasedTypeSymbols(scopePath[scopePath.length - 1]);
                return symbols;
            }

            return null;
        };

        PullSymbol._isExternalModuleReferenceAlias = function (aliasSymbol) {
            if (aliasSymbol) {
                if (aliasSymbol.assignedValue()) {
                    return false;
                }

                if (aliasSymbol.assignedType() && aliasSymbol.assignedType() !== aliasSymbol.assignedContainer()) {
                    return false;
                }

                if (aliasSymbol.assignedContainer() && aliasSymbol.assignedContainer().kind !== 32 /* DynamicModule */) {
                    return false;
                }

                return true;
            }

            return false;
        };

        PullSymbol.prototype.getExportedInternalAliasSymbol = function (scopeSymbol) {
            if (scopeSymbol) {
                if (this.kind !== 128 /* TypeAlias */) {
                    var scopePath = scopeSymbol.pathToRoot();
                    for (var i = 0; i < scopePath.length; i++) {
                        var internalAliases = this.findAliasedTypeSymbols(scopeSymbol, true, true);
                        if (internalAliases) {
                            TypeScript.Debug.assert(internalAliases.length === 1);
                            return internalAliases[0];
                        }
                    }
                }
            }

            return null;
        };

        PullSymbol.prototype.getAliasSymbolName = function (scopeSymbol, aliasNameGetter, aliasPartsNameGetter, skipInternalAlias) {
            if (!skipInternalAlias) {
                var internalAlias = this.getExportedInternalAliasSymbol(scopeSymbol);
                if (internalAlias) {
                    return aliasNameGetter(internalAlias);
                }
            }

            var externalAliases = this.getExternalAliasedSymbols(scopeSymbol);

            if (externalAliases && externalAliases[0] != this && PullSymbol._isExternalModuleReferenceAlias(externalAliases[externalAliases.length - 1])) {
                var aliasFullName = aliasNameGetter(externalAliases[0]);
                if (!aliasFullName) {
                    return null;
                }
                for (var i = 1, symbolsLen = externalAliases.length; i < symbolsLen; i++) {
                    aliasFullName = aliasFullName + "." + aliasPartsNameGetter(externalAliases[i]);
                }
                return aliasFullName;
            }

            return null;
        };

        PullSymbol.prototype._getResolver = function () {
            TypeScript.Debug.assert(this._declarations && this._declarations.length > 0);
            return this._declarations[0].semanticInfoChain.getResolver();
        };

        PullSymbol.prototype._resolveDeclaredSymbol = function () {
            return this._getResolver().resolveDeclaredSymbol(this);
        };

        PullSymbol.prototype.getName = function (scopeSymbol, useConstraintInName) {
            var aliasName = this.getAliasSymbolName(scopeSymbol, function (symbol) {
                return symbol.getName(scopeSymbol, useConstraintInName);
            }, function (symbol) {
                return symbol.getName();
            });
            return aliasName || this.name;
        };

        PullSymbol.prototype.getDisplayName = function (scopeSymbol, useConstraintInName, skipInternalAliasName) {
            var aliasDisplayName = this.getAliasSymbolName(scopeSymbol, function (symbol) {
                return symbol.getDisplayName(scopeSymbol, useConstraintInName);
            }, function (symbol) {
                return symbol.getDisplayName();
            }, skipInternalAliasName);
            if (aliasDisplayName) {
                return aliasDisplayName;
            }

            var decls = this.getDeclarations();
            var name = decls.length && decls[0].getDisplayName();

            return (name && name.length) ? name : this.name;
        };

        PullSymbol.prototype.getIsSpecialized = function () {
            return false;
        };

        PullSymbol.prototype.getRootSymbol = function () {
            if (!this.rootSymbol) {
                return this;
            }
            return this.rootSymbol;
        };
        PullSymbol.prototype.setRootSymbol = function (symbol) {
            this.rootSymbol = symbol;
        };

        PullSymbol.prototype.setIsSynthesized = function (value) {
            if (typeof value === "undefined") { value = true; }
            TypeScript.Debug.assert(this.rootSymbol == null);
            this.isSynthesized = value;
        };

        PullSymbol.prototype.getIsSynthesized = function () {
            if (this.rootSymbol) {
                return this.rootSymbol.getIsSynthesized();
            }
            return this.isSynthesized;
        };

        PullSymbol.prototype.setEnclosingSignature = function (signature) {
            this._enclosingSignature = signature;
        };

        PullSymbol.prototype.getEnclosingSignature = function () {
            return this._enclosingSignature;
        };

        PullSymbol.prototype.addDeclaration = function (decl) {
            TypeScript.Debug.assert(!!decl);

            if (this.rootSymbol) {
                return;
            }

            if (!this._declarations) {
                this._declarations = [decl];
            } else {
                this._declarations[this._declarations.length] = decl;
            }
        };

        PullSymbol.prototype.getDeclarations = function () {
            if (this.rootSymbol) {
                return this.rootSymbol.getDeclarations();
            }

            if (!this._declarations) {
                this._declarations = [];
            }

            return this._declarations;
        };

        PullSymbol.prototype.hasDeclaration = function (decl) {
            if (!this._declarations) {
                return false;
            }

            return TypeScript.ArrayUtilities.any(this._declarations, function (eachDecl) {
                return eachDecl === decl;
            });
        };

        PullSymbol.prototype.setContainer = function (containerSymbol) {
            if (this.rootSymbol) {
                return;
            }

            this._container = containerSymbol;
        };

        PullSymbol.prototype.getContainer = function () {
            if (this.rootSymbol) {
                return this.rootSymbol.getContainer();
            }

            return this._container;
        };

        PullSymbol.prototype.setResolved = function () {
            this.isResolved = true;
            this.inResolution = false;
        };

        PullSymbol.prototype.startResolving = function () {
            this.inResolution = true;
        };

        PullSymbol.prototype.setUnresolved = function () {
            this.isResolved = false;
            this.inResolution = false;
        };

        PullSymbol.prototype.anyDeclHasFlag = function (flag) {
            var declarations = this.getDeclarations();
            for (var i = 0, n = declarations.length; i < n; i++) {
                if (TypeScript.hasFlag(declarations[i].flags, flag)) {
                    return true;
                }
            }
            return false;
        };

        PullSymbol.prototype.allDeclsHaveFlag = function (flag) {
            var declarations = this.getDeclarations();
            for (var i = 0, n = declarations.length; i < n; i++) {
                if (!TypeScript.hasFlag(declarations[i].flags, flag)) {
                    return false;
                }
            }
            return true;
        };

        PullSymbol.prototype.pathToRoot = function () {
            var path = [];
            var node = this;
            while (node) {
                if (node.isType()) {
                    var associatedContainerSymbol = node.getAssociatedContainerType();
                    if (associatedContainerSymbol) {
                        node = associatedContainerSymbol;
                    }
                }
                path[path.length] = node;
                var nodeKind = node.kind;
                if (nodeKind === 2048 /* Parameter */) {
                    break;
                } else {
                    node = node.getContainer();
                }
            }
            return path;
        };

        PullSymbol.unqualifiedNameReferencesDifferentSymbolInScope = function (symbol, scopePath, endScopePathIndex) {
            var declPath = scopePath[0].getDeclarations()[0].getParentPath();
            for (var i = 0, declIndex = declPath.length - 1; i <= endScopePathIndex; i++, declIndex--) {
                if (scopePath[i].isContainer()) {
                    var scopeContainer = scopePath[i];
                    if (symbol.isContainer()) {
                        var memberSymbol = scopeContainer.findContainedNonMemberContainer(symbol.name, 164 /* SomeContainer */);
                        if (memberSymbol && memberSymbol != symbol && memberSymbol.getDeclarations()[0].getParentDecl() == declPath[declIndex]) {
                            return true;
                        }

                        var memberSymbol = scopeContainer.findNestedContainer(symbol.name, 164 /* SomeContainer */);
                        if (memberSymbol && memberSymbol != symbol) {
                            return true;
                        }
                    } else if (symbol.isType()) {
                        var memberSymbol = scopeContainer.findContainedNonMemberType(symbol.name, 58728795 /* SomeType */);
                        var symbolRootType = TypeScript.PullHelpers.getRootType(symbol);
                        if (memberSymbol && TypeScript.PullHelpers.getRootType(memberSymbol) != symbolRootType && memberSymbol.getDeclarations()[0].getParentDecl() == declPath[declIndex]) {
                            return true;
                        }

                        var memberSymbol = scopeContainer.findNestedType(symbol.name, 58728795 /* SomeType */);
                        if (memberSymbol && TypeScript.PullHelpers.getRootType(memberSymbol) != symbolRootType) {
                            return true;
                        }
                    }
                }
            }

            return false;
        };

        PullSymbol.prototype.findQualifyingSymbolPathInScopeSymbol = function (scopeSymbol) {
            var thisPath = this.pathToRoot();
            if (thisPath.length === 1) {
                return thisPath;
            }

            var scopeSymbolPath;
            if (scopeSymbol) {
                scopeSymbolPath = scopeSymbol.pathToRoot();
            } else {
                return thisPath;
            }

            var thisCommonAncestorIndex = TypeScript.ArrayUtilities.indexOf(thisPath, function (thisNode) {
                return TypeScript.ArrayUtilities.contains(scopeSymbolPath, thisNode);
            });
            if (thisCommonAncestorIndex > 0) {
                var thisCommonAncestor = thisPath[thisCommonAncestorIndex];
                var scopeCommonAncestorIndex = TypeScript.ArrayUtilities.indexOf(scopeSymbolPath, function (scopeNode) {
                    return scopeNode === thisCommonAncestor;
                });
                TypeScript.Debug.assert(thisPath.length - thisCommonAncestorIndex === scopeSymbolPath.length - scopeCommonAncestorIndex);

                for (; thisCommonAncestorIndex < thisPath.length; thisCommonAncestorIndex++, scopeCommonAncestorIndex++) {
                    if (!PullSymbol.unqualifiedNameReferencesDifferentSymbolInScope(thisPath[thisCommonAncestorIndex - 1], scopeSymbolPath, scopeCommonAncestorIndex)) {
                        break;
                    }
                }
            }

            if (thisCommonAncestorIndex >= 0 && thisCommonAncestorIndex < thisPath.length) {
                return thisPath.slice(0, thisCommonAncestorIndex);
            } else {
                return thisPath;
            }
        };

        PullSymbol.prototype.toString = function (scopeSymbol, useConstraintInName) {
            var str = this.getNameAndTypeName(scopeSymbol);
            return str;
        };

        PullSymbol.prototype.getNamePartForFullName = function () {
            return this.getDisplayName(null, true);
        };

        PullSymbol.prototype.fullName = function (scopeSymbol) {
            var _this = this;
            var path = this.pathToRoot();
            var fullName = "";

            var aliasFullName = this.getAliasSymbolName(scopeSymbol, function (symbol) {
                return symbol.fullName(scopeSymbol);
            }, function (symbol) {
                return symbol.getNamePartForFullName();
            });
            if (aliasFullName) {
                return aliasFullName;
            }

            for (var i = 1; i < path.length; i++) {
                var aliasFullName = path[i].getAliasSymbolName(scopeSymbol, function (symbol) {
                    return symbol === _this ? null : symbol.fullName(scopeSymbol);
                }, function (symbol) {
                    return symbol.getNamePartForFullName();
                });
                if (aliasFullName) {
                    fullName = aliasFullName + "." + fullName;
                    break;
                }

                var scopedName = path[i].getNamePartForFullName();
                if (path[i].kind === 32 /* DynamicModule */ && !TypeScript.isQuoted(scopedName)) {
                    break;
                }

                if (scopedName === "") {
                    break;
                }

                fullName = scopedName + "." + fullName;
            }

            fullName = fullName + this.getNamePartForFullName();
            return fullName;
        };

        PullSymbol.prototype.getScopedName = function (scopeSymbol, skipTypeParametersInName, useConstraintInName, skipInternalAliasName) {
            var path = this.findQualifyingSymbolPathInScopeSymbol(scopeSymbol);
            var fullName = "";

            var aliasFullName = this.getAliasSymbolName(scopeSymbol, function (symbol) {
                return symbol.getScopedName(scopeSymbol, skipTypeParametersInName, useConstraintInName, skipInternalAliasName);
            }, function (symbol) {
                return symbol.getNamePartForFullName();
            }, skipInternalAliasName);
            if (aliasFullName) {
                return aliasFullName;
            }

            for (var i = 1; i < path.length; i++) {
                var kind = path[i].kind;
                if (kind === 4 /* Container */ || kind === 32 /* DynamicModule */) {
                    var aliasFullName = path[i].getAliasSymbolName(scopeSymbol, function (symbol) {
                        return symbol.getScopedName(scopeSymbol, skipTypeParametersInName, false, skipInternalAliasName);
                    }, function (symbol) {
                        return symbol.getNamePartForFullName();
                    }, skipInternalAliasName);
                    if (aliasFullName) {
                        fullName = aliasFullName + "." + fullName;
                        break;
                    }

                    if (kind === 4 /* Container */) {
                        fullName = path[i].getDisplayName() + "." + fullName;
                    } else {
                        var displayName = path[i].getDisplayName();
                        if (TypeScript.isQuoted(displayName)) {
                            fullName = displayName + "." + fullName;
                        }
                        break;
                    }
                } else {
                    break;
                }
            }
            fullName = fullName + this.getDisplayName(scopeSymbol, useConstraintInName, skipInternalAliasName);
            return fullName;
        };

        PullSymbol.prototype.getScopedNameEx = function (scopeSymbol, skipTypeParametersInName, useConstraintInName, getPrettyTypeName, getTypeParamMarkerInfo, skipInternalAliasName) {
            var name = this.getScopedName(scopeSymbol, skipTypeParametersInName, useConstraintInName, skipInternalAliasName);
            return TypeScript.MemberName.create(name);
        };

        PullSymbol.prototype.getTypeName = function (scopeSymbol, getPrettyTypeName) {
            var memberName = this.getTypeNameEx(scopeSymbol, getPrettyTypeName);
            return memberName.toString();
        };

        PullSymbol.prototype.getTypeNameEx = function (scopeSymbol, getPrettyTypeName) {
            var type = this.type;
            if (type) {
                var memberName = getPrettyTypeName ? this.getTypeNameForFunctionSignature("", scopeSymbol, getPrettyTypeName) : null;
                if (!memberName) {
                    memberName = type.getScopedNameEx(scopeSymbol, false, true, getPrettyTypeName);
                }

                return memberName;
            }
            return TypeScript.MemberName.create("");
        };

        PullSymbol.prototype.getTypeNameForFunctionSignature = function (prefix, scopeSymbol, getPrettyTypeName) {
            var type = this.type;
            if (type && !type.isNamedTypeSymbol() && this.kind !== 4096 /* Property */ && this.kind !== 512 /* Variable */ && this.kind !== 2048 /* Parameter */) {
                var signatures = type.getCallSignatures();
                if (signatures.length === 1 || (getPrettyTypeName && signatures.length)) {
                    var typeName = new TypeScript.MemberNameArray();
                    var signatureName = PullSignatureSymbol.getSignaturesTypeNameEx(signatures, prefix, false, false, scopeSymbol, getPrettyTypeName);
                    typeName.addAll(signatureName);
                    return typeName;
                }
            }

            return null;
        };

        PullSymbol.prototype.getNameAndTypeName = function (scopeSymbol) {
            var nameAndTypeName = this.getNameAndTypeNameEx(scopeSymbol);
            return nameAndTypeName.toString();
        };

        PullSymbol.prototype.getNameAndTypeNameEx = function (scopeSymbol) {
            var type = this.type;
            var nameStr = this.getDisplayName(scopeSymbol);
            if (type) {
                nameStr = nameStr + (this.isOptional ? "?" : "");
                var memberName = this.getTypeNameForFunctionSignature(nameStr, scopeSymbol);
                if (!memberName) {
                    var typeNameEx = type.getScopedNameEx(scopeSymbol);
                    memberName = TypeScript.MemberName.create(typeNameEx, nameStr + ": ", "");
                }
                return memberName;
            }
            return TypeScript.MemberName.create(nameStr);
        };

        PullSymbol.getTypeParameterString = function (typars, scopeSymbol, useContraintInName) {
            return PullSymbol.getTypeParameterStringEx(typars, scopeSymbol, undefined, useContraintInName).toString();
        };

        PullSymbol.getTypeParameterStringEx = function (typeParameters, scopeSymbol, getTypeParamMarkerInfo, useContraintInName) {
            var builder = new TypeScript.MemberNameArray();
            builder.prefix = "";

            if (typeParameters && typeParameters.length) {
                builder.add(TypeScript.MemberName.create("<"));

                for (var i = 0; i < typeParameters.length; i++) {
                    if (i) {
                        builder.add(TypeScript.MemberName.create(", "));
                    }

                    if (getTypeParamMarkerInfo) {
                        builder.add(new TypeScript.MemberName());
                    }

                    builder.add(typeParameters[i].getScopedNameEx(scopeSymbol, false, useContraintInName));

                    if (getTypeParamMarkerInfo) {
                        builder.add(new TypeScript.MemberName());
                    }
                }

                builder.add(TypeScript.MemberName.create(">"));
            }

            return builder;
        };

        PullSymbol.getIsExternallyVisible = function (symbol, fromIsExternallyVisibleSymbol, inIsExternallyVisibleSymbols) {
            if (inIsExternallyVisibleSymbols) {
                for (var i = 0; i < inIsExternallyVisibleSymbols.length; i++) {
                    if (inIsExternallyVisibleSymbols[i] === symbol) {
                        return true;
                    }
                }
            } else {
                inIsExternallyVisibleSymbols = [];
            }

            if (fromIsExternallyVisibleSymbol === symbol) {
                return true;
            }

            inIsExternallyVisibleSymbols.push(fromIsExternallyVisibleSymbol);

            var result = symbol.isExternallyVisible(inIsExternallyVisibleSymbols);

            TypeScript.Debug.assert(TypeScript.ArrayUtilities.last(inIsExternallyVisibleSymbols) === fromIsExternallyVisibleSymbol);
            inIsExternallyVisibleSymbols.pop();

            return result;
        };

        PullSymbol.prototype.isExternallyVisible = function (inIsExternallyVisibleSymbols) {
            var kind = this.kind;
            if (kind === 2 /* Primitive */) {
                return true;
            }

            if (this.rootSymbol) {
                return PullSymbol.getIsExternallyVisible(this.rootSymbol, this, inIsExternallyVisibleSymbols);
            }

            if (this.isType()) {
                var associatedContainerSymbol = this.getAssociatedContainerType();
                if (associatedContainerSymbol) {
                    return PullSymbol.getIsExternallyVisible(associatedContainerSymbol, this, inIsExternallyVisibleSymbols);
                }
            }

            if (this.anyDeclHasFlag(2 /* Private */)) {
                return false;
            }

            var container = this.getContainer();
            if (container === null) {
                var decls = this.getDeclarations();
                if (decls.length) {
                    var parentDecl = decls[0].getParentDecl();
                    if (parentDecl) {
                        var parentSymbol = parentDecl.getSymbol();
                        if (!parentSymbol || parentDecl.kind === 1 /* Script */) {
                            return true;
                        }

                        return PullSymbol.getIsExternallyVisible(parentSymbol, this, inIsExternallyVisibleSymbols);
                    }
                }

                return true;
            }

            if (container.kind === 32 /* DynamicModule */ || (container.getAssociatedContainerType() && container.getAssociatedContainerType().kind === 32 /* DynamicModule */)) {
                var containerSymbol = container.kind === 32 /* DynamicModule */ ? container : container.getAssociatedContainerType();
                if (PullContainerSymbol.usedAsSymbol(containerSymbol, this)) {
                    return true;
                }
            }

            if (!this.anyDeclHasFlag(1 /* Exported */) && kind !== 4096 /* Property */ && kind !== 65536 /* Method */) {
                return false;
            }

            return PullSymbol.getIsExternallyVisible(container, this, inIsExternallyVisibleSymbols);
        };

        PullSymbol.prototype.getDocCommentsOfDecl = function (decl) {
            var ast = decl.ast();

            if (ast) {
                var enclosingModuleDeclaration = TypeScript.ASTHelpers.getModuleDeclarationFromNameAST(ast);
                if (TypeScript.ASTHelpers.isLastNameOfModule(enclosingModuleDeclaration, ast)) {
                    return TypeScript.ASTHelpers.docComments(enclosingModuleDeclaration);
                }

                if (ast.kind() !== 130 /* ModuleDeclaration */ || decl.kind !== 512 /* Variable */) {
                    return TypeScript.ASTHelpers.docComments(ast);
                }
            }

            return [];
        };

        PullSymbol.prototype.getDocCommentArray = function (symbol) {
            var docComments = [];
            if (!symbol) {
                return docComments;
            }

            var isParameter = symbol.kind === 2048 /* Parameter */;
            var decls = symbol.getDeclarations();
            for (var i = 0; i < decls.length; i++) {
                if (isParameter && decls[i].kind === 4096 /* Property */) {
                    continue;
                }
                docComments = docComments.concat(this.getDocCommentsOfDecl(decls[i]));
            }
            return docComments;
        };

        PullSymbol.getDefaultConstructorSymbolForDocComments = function (classSymbol) {
            if (classSymbol.getHasDefaultConstructor()) {
                var extendedTypes = classSymbol.getExtendedTypes();
                if (extendedTypes.length) {
                    return PullSymbol.getDefaultConstructorSymbolForDocComments(extendedTypes[0]);
                }
            }

            return classSymbol.type.getConstructSignatures()[0];
        };

        PullSymbol.prototype.getDocCommentText = function (comments) {
            var docCommentText = new Array();
            for (var c = 0; c < comments.length; c++) {
                var commentText = this.getDocCommentTextValue(comments[c]);
                if (commentText !== "") {
                    docCommentText.push(commentText);
                }
            }
            return docCommentText.join("\n");
        };

        PullSymbol.prototype.getDocCommentTextValue = function (comment) {
            return this.cleanJSDocComment(comment.fullText());
        };

        PullSymbol.prototype.docComments = function (useConstructorAsClass) {
            var decls = this.getDeclarations();
            if (useConstructorAsClass && decls.length && decls[0].kind === 32768 /* ConstructorMethod */) {
                var classDecl = decls[0].getParentDecl();
                return this.getDocCommentText(this.getDocCommentsOfDecl(classDecl));
            }

            if (this._docComments === null) {
                var docComments = "";
                if (!useConstructorAsClass && this.kind === 2097152 /* ConstructSignature */ && decls.length && decls[0].kind === 8 /* Class */) {
                    var classSymbol = this.returnType;
                    var extendedTypes = classSymbol.getExtendedTypes();
                    if (extendedTypes.length) {
                        docComments = extendedTypes[0].getConstructorMethod().docComments();
                    } else {
                        docComments = "";
                    }
                } else if (this.kind === 2048 /* Parameter */) {
                    var parameterComments = [];

                    var funcContainer = this.getEnclosingSignature();
                    var funcDocComments = this.getDocCommentArray(funcContainer);
                    var paramComment = this.getParameterDocCommentText(this.getDisplayName(), funcDocComments);
                    if (paramComment != "") {
                        parameterComments.push(paramComment);
                    }

                    var paramSelfComment = this.getDocCommentText(this.getDocCommentArray(this));
                    if (paramSelfComment != "") {
                        parameterComments.push(paramSelfComment);
                    }
                    docComments = parameterComments.join("\n");
                } else {
                    var getSymbolComments = true;
                    if (this.kind === 16777216 /* FunctionType */) {
                        var functionSymbol = this.getFunctionSymbol();

                        if (functionSymbol) {
                            docComments = functionSymbol._docComments || "";
                            getSymbolComments = false;
                        } else {
                            var declarationList = this.getDeclarations();
                            if (declarationList.length > 0) {
                                docComments = declarationList[0].getSymbol()._docComments || "";
                                getSymbolComments = false;
                            }
                        }
                    }
                    if (getSymbolComments) {
                        docComments = this.getDocCommentText(this.getDocCommentArray(this));
                        if (docComments === "") {
                            if (this.kind === 1048576 /* CallSignature */) {
                                var callTypeSymbol = this.functionType;
                                if (callTypeSymbol && callTypeSymbol.getCallSignatures().length === 1) {
                                    docComments = callTypeSymbol.docComments();
                                }
                            }
                        }
                    }
                }

                this._docComments = docComments;
            }

            return this._docComments;
        };

        PullSymbol.prototype.getParameterDocCommentText = function (param, fncDocComments) {
            if (fncDocComments.length === 0 || fncDocComments[0].kind() !== 6 /* MultiLineCommentTrivia */) {
                return "";
            }

            for (var i = 0; i < fncDocComments.length; i++) {
                var commentContents = fncDocComments[i].fullText();
                for (var j = commentContents.indexOf("@param", 0); 0 <= j; j = commentContents.indexOf("@param", j)) {
                    j += 6;
                    if (!this.isSpaceChar(commentContents, j)) {
                        continue;
                    }

                    j = this.consumeLeadingSpace(commentContents, j);
                    if (j === -1) {
                        break;
                    }

                    if (commentContents.charCodeAt(j) === 123 /* openBrace */) {
                        j++;

                        var charCode = 0;
                        for (var curlies = 1; j < commentContents.length; j++) {
                            charCode = commentContents.charCodeAt(j);

                            if (charCode === 123 /* openBrace */) {
                                curlies++;
                                continue;
                            }

                            if (charCode === 125 /* closeBrace */) {
                                curlies--;
                                if (curlies === 0) {
                                    break;
                                } else {
                                    continue;
                                }
                            }

                            if (charCode === 64 /* at */) {
                                break;
                            }
                        }

                        if (j === commentContents.length) {
                            break;
                        }

                        if (charCode === 64 /* at */) {
                            continue;
                        }

                        j = this.consumeLeadingSpace(commentContents, j + 1);
                        if (j === -1) {
                            break;
                        }
                    }

                    if (param !== commentContents.substr(j, param.length) || !this.isSpaceChar(commentContents, j + param.length)) {
                        continue;
                    }

                    j = this.consumeLeadingSpace(commentContents, j + param.length);
                    if (j === -1) {
                        return "";
                    }

                    var endOfParam = commentContents.indexOf("@", j);
                    var paramHelpString = commentContents.substring(j, endOfParam < 0 ? commentContents.length : endOfParam);

                    var paramSpacesToRemove = undefined;
                    var paramLineIndex = commentContents.substring(0, j).lastIndexOf("\n") + 1;
                    if (paramLineIndex !== 0) {
                        if (paramLineIndex < j && commentContents.charAt(paramLineIndex + 1) === "\r") {
                            paramLineIndex++;
                        }
                    }
                    var startSpaceRemovalIndex = this.consumeLeadingSpace(commentContents, paramLineIndex);
                    if (startSpaceRemovalIndex !== j && commentContents.charAt(startSpaceRemovalIndex) === "*") {
                        paramSpacesToRemove = j - startSpaceRemovalIndex - 1;
                    }

                    return this.cleanJSDocComment(paramHelpString, paramSpacesToRemove);
                }
            }

            return "";
        };

        PullSymbol.prototype.cleanJSDocComment = function (content, spacesToRemove) {
            var docCommentLines = new Array();
            content = content.replace("/**", "");
            if (content.length >= 2 && content.charAt(content.length - 1) === "/" && content.charAt(content.length - 2) === "*") {
                content = content.substring(0, content.length - 2);
            }
            var lines = content.split("\n");
            var inParamTag = false;
            for (var l = 0; l < lines.length; l++) {
                var line = lines[l];
                var cleanLinePos = this.cleanDocCommentLine(line, true, spacesToRemove);
                if (!cleanLinePos) {
                    continue;
                }

                var docCommentText = "";
                var prevPos = cleanLinePos.start;
                for (var i = line.indexOf("@", cleanLinePos.start); 0 <= i && i < cleanLinePos.end; i = line.indexOf("@", i + 1)) {
                    var wasInParamtag = inParamTag;

                    if (line.indexOf("param", i + 1) === i + 1 && this.isSpaceChar(line, i + 6)) {
                        if (!wasInParamtag) {
                            docCommentText += line.substring(prevPos, i);
                        }

                        prevPos = i;
                        inParamTag = true;
                    } else if (wasInParamtag) {
                        prevPos = i;
                        inParamTag = false;
                    }
                }

                if (!inParamTag) {
                    docCommentText += line.substring(prevPos, cleanLinePos.end);
                }

                var newCleanPos = this.cleanDocCommentLine(docCommentText, false);
                if (newCleanPos) {
                    if (spacesToRemove === undefined) {
                        spacesToRemove = cleanLinePos.jsDocSpacesRemoved;
                    }
                    docCommentLines.push(docCommentText);
                }
            }

            return docCommentLines.join("\n");
        };

        PullSymbol.prototype.consumeLeadingSpace = function (line, startIndex, maxSpacesToRemove) {
            var endIndex = line.length;
            if (maxSpacesToRemove !== undefined) {
                endIndex = TypeScript.MathPrototype.min(startIndex + maxSpacesToRemove, endIndex);
            }

            for (; startIndex < endIndex; startIndex++) {
                var charCode = line.charCodeAt(startIndex);
                if (charCode !== 32 /* space */ && charCode !== 9 /* tab */) {
                    return startIndex;
                }
            }

            if (endIndex !== line.length) {
                return endIndex;
            }

            return -1;
        };

        PullSymbol.prototype.isSpaceChar = function (line, index) {
            var length = line.length;
            if (index < length) {
                var charCode = line.charCodeAt(index);

                return charCode === 32 /* space */ || charCode === 9 /* tab */;
            }

            return index === length;
        };

        PullSymbol.prototype.cleanDocCommentLine = function (line, jsDocStyleComment, jsDocLineSpaceToRemove) {
            var nonSpaceIndex = this.consumeLeadingSpace(line, 0);
            if (nonSpaceIndex !== -1) {
                var jsDocSpacesRemoved = nonSpaceIndex;
                if (jsDocStyleComment && line.charAt(nonSpaceIndex) === '*') {
                    var startIndex = nonSpaceIndex + 1;
                    nonSpaceIndex = this.consumeLeadingSpace(line, startIndex, jsDocLineSpaceToRemove);

                    if (nonSpaceIndex !== -1) {
                        jsDocSpacesRemoved = nonSpaceIndex - startIndex;
                    } else {
                        return null;
                    }
                }

                return {
                    start: nonSpaceIndex,
                    end: line.charAt(line.length - 1) === "\r" ? line.length - 1 : line.length,
                    jsDocSpacesRemoved: jsDocSpacesRemoved
                };
            }

            return null;
        };
        return PullSymbol;
    })();
    TypeScript.PullSymbol = PullSymbol;

    

    var PullSignatureSymbol = (function (_super) {
        __extends(PullSignatureSymbol, _super);
        function PullSignatureSymbol(kind, _isDefinition) {
            if (typeof _isDefinition === "undefined") { _isDefinition = false; }
            _super.call(this, "", kind);
            this._isDefinition = _isDefinition;
            this._memberTypeParameterNameCache = null;
            this._stringConstantOverload = undefined;
            this.parameters = TypeScript.sentinelEmptyArray;
            this._typeParameters = null;
            this.returnType = null;
            this.functionType = null;
            this.hasOptionalParam = false;
            this.nonOptionalParamCount = 0;
            this.hasVarArgs = false;
            this._allowedToReferenceTypeParameters = null;
            this._instantiationCache = null;
            this.hasBeenChecked = false;
            this.inWrapCheck = false;
            this.inWrapInfiniteExpandingReferenceCheck = false;
        }
        PullSignatureSymbol.prototype.isDefinition = function () {
            return this._isDefinition;
        };

        PullSignatureSymbol.prototype.isGeneric = function () {
            var typeParameters = this.getTypeParameters();
            return !!typeParameters && typeParameters.length !== 0;
        };

        PullSignatureSymbol.prototype.addParameter = function (parameter, isOptional) {
            if (typeof isOptional === "undefined") { isOptional = false; }
            if (this.parameters === TypeScript.sentinelEmptyArray) {
                this.parameters = [];
            }

            this.parameters[this.parameters.length] = parameter;
            this.hasOptionalParam = isOptional;

            if (!parameter.getEnclosingSignature()) {
                parameter.setEnclosingSignature(this);
            }

            if (!isOptional) {
                this.nonOptionalParamCount++;
            }
        };

        PullSignatureSymbol.prototype.addTypeParameter = function (typeParameter) {
            if (!this._typeParameters) {
                this._typeParameters = [];
            }

            if (!this._memberTypeParameterNameCache) {
                this._memberTypeParameterNameCache = TypeScript.createIntrinsicsObject();
            }

            this._typeParameters[this._typeParameters.length] = typeParameter;

            this._memberTypeParameterNameCache[typeParameter.getName()] = typeParameter;
        };

        PullSignatureSymbol.prototype.addTypeParametersFromReturnType = function () {
            var typeParameters = this.returnType.getTypeParameters();
            for (var i = 0; i < typeParameters.length; i++) {
                this.addTypeParameter(typeParameters[i]);
            }
        };

        PullSignatureSymbol.prototype.getTypeParameters = function () {
            if (!this._typeParameters) {
                this._typeParameters = [];
            }

            return this._typeParameters;
        };

        PullSignatureSymbol.prototype.findTypeParameter = function (name) {
            var memberSymbol;

            if (!this._memberTypeParameterNameCache) {
                this._memberTypeParameterNameCache = TypeScript.createIntrinsicsObject();

                for (var i = 0; i < this.getTypeParameters().length; i++) {
                    this._memberTypeParameterNameCache[this._typeParameters[i].getName()] = this._typeParameters[i];
                }
            }

            memberSymbol = this._memberTypeParameterNameCache[name];

            return memberSymbol;
        };

        PullSignatureSymbol.prototype.getTypeParameterArgumentMap = function () {
            return null;
        };

        PullSignatureSymbol.prototype.getAllowedToReferenceTypeParameters = function () {
            TypeScript.Debug.assert(this.getRootSymbol() == this);
            if (!this._allowedToReferenceTypeParameters) {
                this._allowedToReferenceTypeParameters = TypeScript.PullInstantiationHelpers.getAllowedToReferenceTypeParametersFromDecl(this.getDeclarations()[0]);
            }

            return this._allowedToReferenceTypeParameters;
        };

        PullSignatureSymbol.prototype.addSpecialization = function (specializedVersionOfThisSignature, typeArgumentMap) {
            TypeScript.Debug.assert(this.getRootSymbol() == this);
            if (!this._instantiationCache) {
                this._instantiationCache = TypeScript.createIntrinsicsObject();
            }

            this._instantiationCache[getIDForTypeSubstitutions(this, typeArgumentMap)] = specializedVersionOfThisSignature;
        };

        PullSignatureSymbol.prototype.getSpecialization = function (typeArgumentMap) {
            TypeScript.Debug.assert(this.getRootSymbol() == this);
            if (!this._instantiationCache) {
                return null;
            }

            var result = this._instantiationCache[getIDForTypeSubstitutions(this, typeArgumentMap)];
            return result || null;
        };

        PullSignatureSymbol.prototype.isStringConstantOverloadSignature = function () {
            if (this._stringConstantOverload === undefined) {
                var params = this.parameters;
                this._stringConstantOverload = false;
                for (var i = 0; i < params.length; i++) {
                    var paramType = params[i].type;
                    if (paramType && paramType.isPrimitive() && paramType.isStringConstant()) {
                        this._stringConstantOverload = true;
                    }
                }
            }

            return this._stringConstantOverload;
        };

        PullSignatureSymbol.prototype.getParameterTypeAtIndex = function (iParam) {
            if (iParam < this.parameters.length - 1 || (iParam < this.parameters.length && !this.hasVarArgs)) {
                return this.parameters[iParam].type;
            } else if (this.hasVarArgs) {
                var paramType = this.parameters[this.parameters.length - 1].type;
                if (paramType.isArrayNamedTypeReference()) {
                    paramType = paramType.getElementType();
                }
                return paramType;
            }

            return null;
        };

        PullSignatureSymbol.getSignatureTypeMemberName = function (candidateSignature, signatures, scopeSymbol) {
            var allMemberNames = new TypeScript.MemberNameArray();
            var signatureMemberName = PullSignatureSymbol.getSignaturesTypeNameEx(signatures, "", false, false, scopeSymbol, true, candidateSignature);
            allMemberNames.addAll(signatureMemberName);
            return allMemberNames;
        };

        PullSignatureSymbol.getSignaturesTypeNameEx = function (signatures, prefix, shortform, brackets, scopeSymbol, getPrettyTypeName, candidateSignature) {
            var result = [];
            if (!signatures) {
                return result;
            }

            var len = signatures.length;
            if (!getPrettyTypeName && len > 1) {
                shortform = false;
            }

            var foundDefinition = false;
            if (candidateSignature && candidateSignature.isDefinition() && len > 1) {
                candidateSignature = null;
            }

            for (var i = 0; i < len; i++) {
                if (len > 1 && signatures[i].isDefinition()) {
                    foundDefinition = true;
                    continue;
                }

                var signature = signatures[i];
                if (getPrettyTypeName && candidateSignature) {
                    signature = candidateSignature;
                }

                result.push(signature.getSignatureTypeNameEx(prefix, shortform, brackets, scopeSymbol));
                if (getPrettyTypeName) {
                    break;
                }
            }

            if (getPrettyTypeName && result.length && len > 1) {
                var lastMemberName = result[result.length - 1];
                for (var i = i + 1; i < len; i++) {
                    if (signatures[i].isDefinition()) {
                        foundDefinition = true;
                        break;
                    }
                }
                var overloadString = TypeScript.getLocalizedText(TypeScript.DiagnosticCode._0_overload_s, [foundDefinition ? len - 2 : len - 1]);
                lastMemberName.add(TypeScript.MemberName.create(overloadString));
            }

            return result;
        };

        PullSignatureSymbol.prototype.toString = function (scopeSymbol, useConstraintInName) {
            var s = this.getSignatureTypeNameEx(this.getScopedNameEx().toString(), false, false, scopeSymbol, undefined, useConstraintInName).toString();
            return s;
        };

        PullSignatureSymbol.prototype.getSignatureTypeNameEx = function (prefix, shortform, brackets, scopeSymbol, getParamMarkerInfo, getTypeParamMarkerInfo) {
            var typeParamterBuilder = new TypeScript.MemberNameArray();

            typeParamterBuilder.add(PullSymbol.getTypeParameterStringEx(this.getTypeParameters(), scopeSymbol, getTypeParamMarkerInfo, true));

            if (brackets) {
                typeParamterBuilder.add(TypeScript.MemberName.create("["));
            } else {
                typeParamterBuilder.add(TypeScript.MemberName.create("("));
            }

            var builder = new TypeScript.MemberNameArray();
            builder.prefix = prefix;

            if (getTypeParamMarkerInfo) {
                builder.prefix = prefix;
                builder.addAll(typeParamterBuilder.entries);
            } else {
                builder.prefix = prefix + typeParamterBuilder.toString();
            }

            var params = this.parameters;
            var paramLen = params.length;
            for (var i = 0; i < paramLen; i++) {
                var paramType = params[i].type;
                var typeString = paramType ? ": " : "";
                var paramIsVarArg = params[i].isVarArg;
                var varArgPrefix = paramIsVarArg ? "..." : "";
                var optionalString = (!paramIsVarArg && params[i].isOptional) ? "?" : "";
                if (getParamMarkerInfo) {
                    builder.add(new TypeScript.MemberName());
                }
                builder.add(TypeScript.MemberName.create(varArgPrefix + params[i].getScopedNameEx(scopeSymbol).toString() + optionalString + typeString));
                if (paramType) {
                    builder.add(paramType.getScopedNameEx(scopeSymbol));
                }
                if (getParamMarkerInfo) {
                    builder.add(new TypeScript.MemberName());
                }
                if (i < paramLen - 1) {
                    builder.add(TypeScript.MemberName.create(", "));
                }
            }

            if (shortform) {
                if (brackets) {
                    builder.add(TypeScript.MemberName.create("] => "));
                } else {
                    builder.add(TypeScript.MemberName.create(") => "));
                }
            } else {
                if (brackets) {
                    builder.add(TypeScript.MemberName.create("]: "));
                } else {
                    builder.add(TypeScript.MemberName.create("): "));
                }
            }

            if (this.returnType) {
                builder.add(this.returnType.getScopedNameEx(scopeSymbol));
            } else {
                builder.add(TypeScript.MemberName.create("any"));
            }

            return builder;
        };

        PullSignatureSymbol.prototype.forAllParameterTypes = function (length, predicate) {
            if (this.parameters.length < length && !this.hasVarArgs) {
                length = this.parameters.length;
            }

            for (var i = 0; i < length; i++) {
                var paramType = this.getParameterTypeAtIndex(i);
                if (!predicate(paramType, i)) {
                    return false;
                }
            }

            return true;
        };

        PullSignatureSymbol.prototype.forAllCorrespondingParameterTypesInThisAndOtherSignature = function (otherSignature, predicate) {
            var length;
            if (this.hasVarArgs) {
                length = otherSignature.hasVarArgs ? Math.max(this.parameters.length, otherSignature.parameters.length) : otherSignature.parameters.length;
            } else {
                length = otherSignature.hasVarArgs ? this.parameters.length : Math.min(this.parameters.length, otherSignature.parameters.length);
            }

            for (var i = 0; i < length; i++) {
                var thisParamType = this.getParameterTypeAtIndex(i);
                var otherParamType = otherSignature.getParameterTypeAtIndex(i);
                if (!predicate(thisParamType, otherParamType, i)) {
                    return false;
                }
            }

            return true;
        };

        PullSignatureSymbol.prototype.wrapsSomeTypeParameter = function (typeParameterArgumentMap) {
            return this.getWrappingTypeParameterID(typeParameterArgumentMap) !== 0;
        };

        PullSignatureSymbol.prototype.getWrappingTypeParameterID = function (typeParameterArgumentMap) {
            var signature = this;
            if (signature.inWrapCheck) {
                return 0;
            }

            this._wrapsTypeParameterCache = this._wrapsTypeParameterCache || new TypeScript.WrapsTypeParameterCache();

            var wrappingTypeParameterID = this._wrapsTypeParameterCache.getWrapsTypeParameter(typeParameterArgumentMap);
            if (wrappingTypeParameterID === undefined) {
                wrappingTypeParameterID = this.getWrappingTypeParameterIDWorker(typeParameterArgumentMap);
                this._wrapsTypeParameterCache.setWrapsTypeParameter(typeParameterArgumentMap, wrappingTypeParameterID);
            }

            return wrappingTypeParameterID;
        };

        PullSignatureSymbol.prototype.getWrappingTypeParameterIDWorker = function (typeParameterArgumentMap) {
            var signature = this;
            signature.inWrapCheck = true;
            TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(signature);
            var wrappingTypeParameterID = signature.returnType ? signature.returnType.getWrappingTypeParameterID(typeParameterArgumentMap) : 0;

            var parameters = signature.parameters;
            for (var i = 0; !wrappingTypeParameterID && i < parameters.length; i++) {
                TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(parameters[i]);
                wrappingTypeParameterID = parameters[i].type.getWrappingTypeParameterID(typeParameterArgumentMap);
            }

            signature.inWrapCheck = false;

            return wrappingTypeParameterID;
        };

        PullSignatureSymbol.prototype._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReference = function (enclosingType, knownWrapMap) {
            var wrapsIntoInfinitelyExpandingTypeReference = knownWrapMap.valueAt(this.pullSymbolID, enclosingType.pullSymbolID);
            if (wrapsIntoInfinitelyExpandingTypeReference != undefined) {
                return wrapsIntoInfinitelyExpandingTypeReference;
            }

            if (this.inWrapInfiniteExpandingReferenceCheck) {
                return false;
            }

            this.inWrapInfiniteExpandingReferenceCheck = true;
            wrapsIntoInfinitelyExpandingTypeReference = this._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceWorker(enclosingType, knownWrapMap);
            knownWrapMap.setValueAt(this.pullSymbolID, enclosingType.pullSymbolID, wrapsIntoInfinitelyExpandingTypeReference);
            this.inWrapInfiniteExpandingReferenceCheck = false;

            return wrapsIntoInfinitelyExpandingTypeReference;
        };

        PullSignatureSymbol.prototype._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceWorker = function (enclosingType, knownWrapMap) {
            if (this.returnType && this.returnType._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceRecurse(enclosingType, knownWrapMap)) {
                return true;
            }

            var parameters = this.parameters;

            for (var i = 0; i < parameters.length; i++) {
                if (parameters[i].type && parameters[i].type._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceRecurse(enclosingType, knownWrapMap)) {
                    return true;
                }
            }

            return false;
        };
        return PullSignatureSymbol;
    })(PullSymbol);
    TypeScript.PullSignatureSymbol = PullSignatureSymbol;

    var PullTypeSymbol = (function (_super) {
        __extends(PullTypeSymbol, _super);
        function PullTypeSymbol(name, kind) {
            _super.call(this, name, kind);
            this._members = TypeScript.sentinelEmptyArray;
            this._enclosedMemberTypes = null;
            this._enclosedMemberContainers = null;
            this._typeParameters = null;
            this._allowedToReferenceTypeParameters = null;
            this._specializedVersionsOfThisType = null;
            this._arrayVersionOfThisType = null;
            this._implementedTypes = null;
            this._extendedTypes = null;
            this._typesThatExplicitlyImplementThisType = null;
            this._typesThatExtendThisType = null;
            this._callSignatures = null;
            this._allCallSignatures = null;
            this._constructSignatures = null;
            this._allConstructSignatures = null;
            this._indexSignatures = null;
            this._allIndexSignatures = null;
            this._allIndexSignaturesOfAugmentedType = null;
            this._memberNameCache = null;
            this._enclosedTypeNameCache = null;
            this._enclosedContainerCache = null;
            this._typeParameterNameCache = null;
            this._containedNonMemberNameCache = null;
            this._containedNonMemberTypeNameCache = null;
            this._containedNonMemberContainerCache = null;
            this._simpleInstantiationCache = null;
            this._complexInstantiationCache = null;
            this._hasGenericSignature = false;
            this._hasGenericMember = false;
            this._hasBaseTypeConflict = false;
            this._knownBaseTypeCount = 0;
            this._associatedContainerTypeSymbol = null;
            this._constructorMethod = null;
            this._hasDefaultConstructor = false;
            this._functionSymbol = null;
            this._inMemberTypeNameEx = false;
            this.inSymbolPrivacyCheck = false;
            this.inWrapCheck = false;
            this.inWrapInfiniteExpandingReferenceCheck = false;
            this.typeReference = null;
            this._widenedType = null;
            this._isArrayNamedTypeReference = undefined;
            this.type = this;
        }
        PullTypeSymbol.prototype.isArrayNamedTypeReference = function () {
            if (this._isArrayNamedTypeReference === undefined) {
                this._isArrayNamedTypeReference = this.computeIsArrayNamedTypeReference();
            }

            return this._isArrayNamedTypeReference;
        };

        PullTypeSymbol.prototype.computeIsArrayNamedTypeReference = function () {
            var typeArgs = this.getTypeArguments();
            if (typeArgs && this.getTypeArguments().length === 1 && this.name === "Array") {
                var declaration = this.getDeclarations()[0];

                if (declaration && declaration.getParentDecl() && declaration.getParentDecl().getParentDecl() === null) {
                    return true;
                }
            }

            return false;
        };

        PullTypeSymbol.prototype.isType = function () {
            return true;
        };
        PullTypeSymbol.prototype.isClass = function () {
            return this.kind === 8 /* Class */ || (this._constructorMethod !== null);
        };
        PullTypeSymbol.prototype.isFunction = function () {
            return (this.kind & (33554432 /* ConstructorType */ | 16777216 /* FunctionType */)) !== 0;
        };
        PullTypeSymbol.prototype.isConstructor = function () {
            return this.kind === 33554432 /* ConstructorType */ || (this._associatedContainerTypeSymbol && this._associatedContainerTypeSymbol.isClass());
        };
        PullTypeSymbol.prototype.isTypeParameter = function () {
            return false;
        };
        PullTypeSymbol.prototype.isTypeVariable = function () {
            return false;
        };
        PullTypeSymbol.prototype.isError = function () {
            return false;
        };
        PullTypeSymbol.prototype.isEnum = function () {
            return this.kind === 64 /* Enum */;
        };

        PullTypeSymbol.prototype.getTypeParameterArgumentMap = function () {
            return null;
        };

        PullTypeSymbol.prototype.isObject = function () {
            return TypeScript.hasFlag(this.kind, 8 /* Class */ | 33554432 /* ConstructorType */ | 64 /* Enum */ | 16777216 /* FunctionType */ | 16 /* Interface */ | 8388608 /* ObjectType */ | 256 /* ObjectLiteral */);
        };

        PullTypeSymbol.prototype.isFunctionType = function () {
            return this.getCallSignatures().length > 0 || this.getConstructSignatures().length > 0;
        };

        PullTypeSymbol.prototype.getKnownBaseTypeCount = function () {
            return this._knownBaseTypeCount;
        };
        PullTypeSymbol.prototype.resetKnownBaseTypeCount = function () {
            this._knownBaseTypeCount = 0;
        };
        PullTypeSymbol.prototype.incrementKnownBaseCount = function () {
            this._knownBaseTypeCount++;
        };

        PullTypeSymbol.prototype.setHasBaseTypeConflict = function () {
            this._hasBaseTypeConflict = true;
        };
        PullTypeSymbol.prototype.hasBaseTypeConflict = function () {
            return this._hasBaseTypeConflict;
        };

        PullTypeSymbol.prototype.hasMembers = function () {
            if (this._members !== TypeScript.sentinelEmptyArray) {
                return true;
            }

            var parents = this.getExtendedTypes();

            for (var i = 0; i < parents.length; i++) {
                if (parents[i].hasMembers()) {
                    return true;
                }
            }

            return false;
        };

        PullTypeSymbol.prototype.setHasGenericSignature = function () {
            this._hasGenericSignature = true;
        };
        PullTypeSymbol.prototype.getHasGenericSignature = function () {
            return this._hasGenericSignature;
        };

        PullTypeSymbol.prototype.setHasGenericMember = function () {
            this._hasGenericMember = true;
        };
        PullTypeSymbol.prototype.getHasGenericMember = function () {
            return this._hasGenericMember;
        };

        PullTypeSymbol.prototype.setAssociatedContainerType = function (type) {
            this._associatedContainerTypeSymbol = type;
        };

        PullTypeSymbol.prototype.getAssociatedContainerType = function () {
            return this._associatedContainerTypeSymbol;
        };

        PullTypeSymbol.prototype.getArrayType = function () {
            return this._arrayVersionOfThisType;
        };

        PullTypeSymbol.prototype.getElementType = function () {
            return null;
        };

        PullTypeSymbol.prototype.setArrayType = function (arrayType) {
            this._arrayVersionOfThisType = arrayType;
        };

        PullTypeSymbol.prototype.getFunctionSymbol = function () {
            return this._functionSymbol;
        };

        PullTypeSymbol.prototype.setFunctionSymbol = function (symbol) {
            if (symbol) {
                this._functionSymbol = symbol;
            }
        };

        PullTypeSymbol.prototype.findContainedNonMember = function (name) {
            if (!this._containedNonMemberNameCache) {
                return null;
            }

            return this._containedNonMemberNameCache[name];
        };

        PullTypeSymbol.prototype.findContainedNonMemberType = function (typeName, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            if (!this._containedNonMemberTypeNameCache) {
                return null;
            }

            var nonMemberSymbol = this._containedNonMemberTypeNameCache[typeName];

            if (nonMemberSymbol && kind !== 0 /* None */) {
                nonMemberSymbol = TypeScript.hasFlag(nonMemberSymbol.kind, kind) ? nonMemberSymbol : null;
            }

            return nonMemberSymbol;
        };

        PullTypeSymbol.prototype.findContainedNonMemberContainer = function (containerName, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            if (!this._containedNonMemberContainerCache) {
                return null;
            }

            var nonMemberSymbol = this._containedNonMemberContainerCache[containerName];

            if (nonMemberSymbol && kind !== 0 /* None */) {
                nonMemberSymbol = TypeScript.hasFlag(nonMemberSymbol.kind, kind) ? nonMemberSymbol : null;
            }

            return nonMemberSymbol;
        };

        PullTypeSymbol.prototype.addMember = function (memberSymbol) {
            if (!memberSymbol) {
                return;
            }

            memberSymbol.setContainer(this);

            if (!this._memberNameCache) {
                this._memberNameCache = TypeScript.createIntrinsicsObject();
            }

            if (this._members === TypeScript.sentinelEmptyArray) {
                this._members = [];
            }

            this._members.push(memberSymbol);
            this._memberNameCache[memberSymbol.name] = memberSymbol;
        };

        PullTypeSymbol.prototype.addEnclosedMemberType = function (enclosedType) {
            if (!enclosedType) {
                return;
            }

            enclosedType.setContainer(this);

            if (!this._enclosedTypeNameCache) {
                this._enclosedTypeNameCache = TypeScript.createIntrinsicsObject();
            }

            if (!this._enclosedMemberTypes) {
                this._enclosedMemberTypes = [];
            }

            this._enclosedMemberTypes[this._enclosedMemberTypes.length] = enclosedType;
            this._enclosedTypeNameCache[enclosedType.name] = enclosedType;
        };

        PullTypeSymbol.prototype.addEnclosedMemberContainer = function (enclosedContainer) {
            if (!enclosedContainer) {
                return;
            }

            enclosedContainer.setContainer(this);

            if (!this._enclosedContainerCache) {
                this._enclosedContainerCache = TypeScript.createIntrinsicsObject();
            }

            if (!this._enclosedMemberContainers) {
                this._enclosedMemberContainers = [];
            }

            this._enclosedMemberContainers[this._enclosedMemberContainers.length] = enclosedContainer;
            this._enclosedContainerCache[enclosedContainer.name] = enclosedContainer;
        };

        PullTypeSymbol.prototype.addEnclosedNonMember = function (enclosedNonMember) {
            if (!enclosedNonMember) {
                return;
            }

            enclosedNonMember.setContainer(this);

            if (!this._containedNonMemberNameCache) {
                this._containedNonMemberNameCache = TypeScript.createIntrinsicsObject();
            }

            this._containedNonMemberNameCache[enclosedNonMember.name] = enclosedNonMember;
        };

        PullTypeSymbol.prototype.addEnclosedNonMemberType = function (enclosedNonMemberType) {
            if (!enclosedNonMemberType) {
                return;
            }

            enclosedNonMemberType.setContainer(this);

            if (!this._containedNonMemberTypeNameCache) {
                this._containedNonMemberTypeNameCache = TypeScript.createIntrinsicsObject();
            }

            this._containedNonMemberTypeNameCache[enclosedNonMemberType.name] = enclosedNonMemberType;
        };

        PullTypeSymbol.prototype.addEnclosedNonMemberContainer = function (enclosedNonMemberContainer) {
            if (!enclosedNonMemberContainer) {
                return;
            }

            enclosedNonMemberContainer.setContainer(this);

            if (!this._containedNonMemberContainerCache) {
                this._containedNonMemberContainerCache = TypeScript.createIntrinsicsObject();
            }

            this._containedNonMemberContainerCache[enclosedNonMemberContainer.name] = enclosedNonMemberContainer;
        };

        PullTypeSymbol.prototype.addTypeParameter = function (typeParameter) {
            if (!typeParameter) {
                return;
            }

            if (!typeParameter.getContainer()) {
                typeParameter.setContainer(this);
            }

            if (!this._typeParameterNameCache) {
                this._typeParameterNameCache = TypeScript.createIntrinsicsObject();
            }

            if (!this._typeParameters) {
                this._typeParameters = [];
            }

            this._typeParameters[this._typeParameters.length] = typeParameter;
            this._typeParameterNameCache[typeParameter.getName()] = typeParameter;
        };

        PullTypeSymbol.prototype.getMembers = function () {
            return this._members;
        };

        PullTypeSymbol.prototype.setHasDefaultConstructor = function (hasOne) {
            if (typeof hasOne === "undefined") { hasOne = true; }
            this._hasDefaultConstructor = hasOne;
        };

        PullTypeSymbol.prototype.getHasDefaultConstructor = function () {
            return this._hasDefaultConstructor;
        };

        PullTypeSymbol.prototype.getConstructorMethod = function () {
            return this._constructorMethod;
        };

        PullTypeSymbol.prototype.setConstructorMethod = function (constructorMethod) {
            this._constructorMethod = constructorMethod;
        };

        PullTypeSymbol.prototype.getTypeParameters = function () {
            if (!this._typeParameters) {
                return TypeScript.sentinelEmptyArray;
            }

            return this._typeParameters;
        };

        PullTypeSymbol.prototype.getAllowedToReferenceTypeParameters = function () {
            if (!!(this.kind && 8216 /* SomeInstantiatableType */) && this.isNamedTypeSymbol() && !this.isTypeParameter()) {
                return this.getTypeParameters();
            }

            if (!this._allowedToReferenceTypeParameters) {
                this._allowedToReferenceTypeParameters = TypeScript.PullInstantiationHelpers.getAllowedToReferenceTypeParametersFromDecl(this.getDeclarations()[0]);
            }

            return this._allowedToReferenceTypeParameters;
        };

        PullTypeSymbol.prototype.isGeneric = function () {
            return (this._typeParameters && this._typeParameters.length > 0) || this._hasGenericSignature || this._hasGenericMember || this.isArrayNamedTypeReference();
        };

        PullTypeSymbol.prototype.canUseSimpleInstantiationCache = function (typeArgumentMap) {
            if (this.isTypeParameter()) {
                return true;
            }

            var typeParameters = this.getTypeParameters();
            return typeArgumentMap && this.isNamedTypeSymbol() && typeParameters.length === 1 && typeArgumentMap[typeParameters[0].pullSymbolID].kind !== 8388608 /* ObjectType */;
        };

        PullTypeSymbol.prototype.getSimpleInstantiationCacheId = function (typeArgumentMap) {
            if (this.isTypeParameter()) {
                return typeArgumentMap[0].pullSymbolID;
            }

            return typeArgumentMap[this.getTypeParameters()[0].pullSymbolID].pullSymbolID;
        };

        PullTypeSymbol.prototype.addSpecialization = function (specializedVersionOfThisType, typeArgumentMap) {
            if (this.canUseSimpleInstantiationCache(typeArgumentMap)) {
                if (!this._simpleInstantiationCache) {
                    this._simpleInstantiationCache = [];
                }

                this._simpleInstantiationCache[this.getSimpleInstantiationCacheId(typeArgumentMap)] = specializedVersionOfThisType;
            } else {
                if (!this._complexInstantiationCache) {
                    this._complexInstantiationCache = TypeScript.createIntrinsicsObject();
                }

                this._complexInstantiationCache[getIDForTypeSubstitutions(this, typeArgumentMap)] = specializedVersionOfThisType;
            }

            if (!this._specializedVersionsOfThisType) {
                this._specializedVersionsOfThisType = [];
            }

            this._specializedVersionsOfThisType.push(specializedVersionOfThisType);
        };

        PullTypeSymbol.prototype.getSpecialization = function (typeArgumentMap) {
            if (this.canUseSimpleInstantiationCache(typeArgumentMap)) {
                if (!this._simpleInstantiationCache) {
                    return null;
                }

                var result = this._simpleInstantiationCache[this.getSimpleInstantiationCacheId(typeArgumentMap)];
                return result || null;
            } else {
                if (!this._complexInstantiationCache) {
                    return null;
                }

                if (this.getAllowedToReferenceTypeParameters().length == 0) {
                    return this;
                }

                var result = this._complexInstantiationCache[getIDForTypeSubstitutions(this, typeArgumentMap)];
                return result || null;
            }
        };

        PullTypeSymbol.prototype.getKnownSpecializations = function () {
            if (!this._specializedVersionsOfThisType) {
                return TypeScript.sentinelEmptyArray;
            }

            return this._specializedVersionsOfThisType;
        };

        PullTypeSymbol.prototype.getTypeArguments = function () {
            return null;
        };

        PullTypeSymbol.prototype.getTypeArgumentsOrTypeParameters = function () {
            return this.getTypeParameters();
        };

        PullTypeSymbol.prototype.addCallOrConstructSignaturePrerequisiteBase = function (signature) {
            if (signature.isGeneric()) {
                this._hasGenericSignature = true;
            }

            signature.functionType = this;
        };

        PullTypeSymbol.prototype.addCallSignaturePrerequisite = function (callSignature) {
            if (!this._callSignatures) {
                this._callSignatures = [];
            }

            this.addCallOrConstructSignaturePrerequisiteBase(callSignature);
        };

        PullTypeSymbol.prototype.appendCallSignature = function (callSignature) {
            this.addCallSignaturePrerequisite(callSignature);
            this._callSignatures.push(callSignature);
        };

        PullTypeSymbol.prototype.insertCallSignatureAtIndex = function (callSignature, index) {
            this.addCallSignaturePrerequisite(callSignature);
            TypeScript.Debug.assert(index <= this._callSignatures.length);
            if (index === this._callSignatures.length) {
                this._callSignatures.push(callSignature);
            } else {
                this._callSignatures.splice(index, 0, callSignature);
            }
        };

        PullTypeSymbol.prototype.addConstructSignaturePrerequisite = function (constructSignature) {
            if (!this._constructSignatures) {
                this._constructSignatures = [];
            }

            this.addCallOrConstructSignaturePrerequisiteBase(constructSignature);
        };

        PullTypeSymbol.prototype.appendConstructSignature = function (constructSignature) {
            this.addConstructSignaturePrerequisite(constructSignature);
            this._constructSignatures.push(constructSignature);
        };

        PullTypeSymbol.prototype.insertConstructSignatureAtIndex = function (constructSignature, index) {
            this.addConstructSignaturePrerequisite(constructSignature);
            TypeScript.Debug.assert(index <= this._constructSignatures.length);
            if (index === this._constructSignatures.length) {
                this._constructSignatures.push(constructSignature);
            } else {
                this._constructSignatures.splice(index, 0, constructSignature);
            }
        };

        PullTypeSymbol.prototype.addIndexSignature = function (indexSignature) {
            if (!this._indexSignatures) {
                this._indexSignatures = [];
            }

            this._indexSignatures[this._indexSignatures.length] = indexSignature;

            if (indexSignature.isGeneric()) {
                this._hasGenericSignature = true;
            }

            indexSignature.functionType = this;
        };

        PullTypeSymbol.prototype.hasOwnCallSignatures = function () {
            return this._callSignatures !== null;
        };

        PullTypeSymbol.prototype.getOwnCallSignatures = function () {
            return this._callSignatures || TypeScript.sentinelEmptyArray;
        };

        PullTypeSymbol.prototype.getCallSignatures = function () {
            if (this._allCallSignatures) {
                return this._allCallSignatures;
            }

            var signatures = [];

            if (this._callSignatures) {
                signatures = signatures.concat(this._callSignatures);
            }

            if (this._extendedTypes && this.kind === 16 /* Interface */) {
                for (var i = 0; i < this._extendedTypes.length; i++) {
                    if (this._extendedTypes[i].hasBase(this)) {
                        continue;
                    }

                    this._getResolver()._addUnhiddenSignaturesFromBaseType(this._callSignatures, this._extendedTypes[i].getCallSignatures(), signatures);
                }
            }

            this._allCallSignatures = signatures;

            return signatures;
        };

        PullTypeSymbol.prototype.hasOwnConstructSignatures = function () {
            return this._constructSignatures !== null;
        };

        PullTypeSymbol.prototype.getOwnDeclaredConstructSignatures = function () {
            return this._constructSignatures || TypeScript.sentinelEmptyArray;
        };

        PullTypeSymbol.prototype.getConstructSignatures = function () {
            if (this._allConstructSignatures) {
                return this._allConstructSignatures;
            }

            var signatures = [];

            if (this._constructSignatures) {
                signatures = signatures.concat(this._constructSignatures);
            } else if (this.isConstructor()) {
                if (this._extendedTypes && this._extendedTypes.length > 0) {
                    signatures = this.getBaseClassConstructSignatures(this._extendedTypes[0]);
                } else {
                    signatures = [this.getDefaultClassConstructSignature()];
                }
            }

            if (this._extendedTypes && this.kind === 16 /* Interface */) {
                for (var i = 0; i < this._extendedTypes.length; i++) {
                    if (this._extendedTypes[i].hasBase(this)) {
                        continue;
                    }

                    this._getResolver()._addUnhiddenSignaturesFromBaseType(this._constructSignatures, this._extendedTypes[i].getConstructSignatures(), signatures);
                }
            }

            this._allConstructSignatures = signatures;

            return signatures;
        };

        PullTypeSymbol.prototype.hasOwnIndexSignatures = function () {
            return this._indexSignatures !== null;
        };

        PullTypeSymbol.prototype.getOwnIndexSignatures = function () {
            return this._indexSignatures || TypeScript.sentinelEmptyArray;
        };

        PullTypeSymbol.prototype.getIndexSignatures = function () {
            if (this._allIndexSignatures) {
                return this._allIndexSignatures;
            }

            var signatures = [];

            if (this._indexSignatures) {
                signatures = signatures.concat(this._indexSignatures);
            }

            if (this._extendedTypes) {
                for (var i = 0; i < this._extendedTypes.length; i++) {
                    if (this._extendedTypes[i].hasBase(this)) {
                        continue;
                    }

                    this._getResolver()._addUnhiddenSignaturesFromBaseType(this._indexSignatures, this._extendedTypes[i].getIndexSignatures(), signatures);
                }
            }

            this._allIndexSignatures = signatures;

            return signatures;
        };

        PullTypeSymbol.prototype.getIndexSignaturesOfAugmentedType = function (resolver, globalFunctionInterface, globalObjectInterface) {
            if (!this._allIndexSignaturesOfAugmentedType) {
                var initialIndexSignatures = this.getIndexSignatures();
                var shouldAddFunctionSignatures = false;
                var shouldAddObjectSignatures = false;

                if (globalFunctionInterface && this.isFunctionType() && this !== globalFunctionInterface) {
                    var functionIndexSignatures = globalFunctionInterface.getIndexSignatures();
                    if (functionIndexSignatures.length) {
                        shouldAddFunctionSignatures = true;
                    }
                }

                if (globalObjectInterface && this !== globalObjectInterface) {
                    var objectIndexSignatures = globalObjectInterface.getIndexSignatures();
                    if (objectIndexSignatures.length) {
                        shouldAddObjectSignatures = true;
                    }
                }

                if (shouldAddFunctionSignatures || shouldAddObjectSignatures) {
                    this._allIndexSignaturesOfAugmentedType = initialIndexSignatures.slice(0);
                    if (shouldAddFunctionSignatures) {
                        resolver._addUnhiddenSignaturesFromBaseType(initialIndexSignatures, functionIndexSignatures, this._allIndexSignaturesOfAugmentedType);
                    }
                    if (shouldAddObjectSignatures) {
                        if (shouldAddFunctionSignatures) {
                            initialIndexSignatures = initialIndexSignatures.concat(functionIndexSignatures);
                        }
                        resolver._addUnhiddenSignaturesFromBaseType(initialIndexSignatures, objectIndexSignatures, this._allIndexSignaturesOfAugmentedType);
                    }
                } else {
                    this._allIndexSignaturesOfAugmentedType = initialIndexSignatures;
                }
            }

            return this._allIndexSignaturesOfAugmentedType;
        };

        PullTypeSymbol.prototype.getBaseClassConstructSignatures = function (baseType) {
            TypeScript.Debug.assert(this.isConstructor() && baseType.isConstructor());
            var instanceTypeSymbol = this.getAssociatedContainerType();
            TypeScript.Debug.assert(instanceTypeSymbol.getDeclarations().length === 1);
            if (baseType.hasBase(this)) {
                return null;
            }

            var baseConstructSignatures = baseType.getConstructSignatures();
            var signatures = [];
            for (var i = 0; i < baseConstructSignatures.length; i++) {
                var baseSignature = baseConstructSignatures[i];

                baseSignature._resolveDeclaredSymbol();
                var currentSignature = new PullSignatureSymbol(2097152 /* ConstructSignature */, baseSignature.isDefinition());
                currentSignature.returnType = instanceTypeSymbol;
                currentSignature.addTypeParametersFromReturnType();
                for (var j = 0; j < baseSignature.parameters.length; j++) {
                    currentSignature.addParameter(baseSignature.parameters[j], baseSignature.parameters[j].isOptional);
                }
                if (baseSignature.parameters.length > 0) {
                    currentSignature.hasVarArgs = baseSignature.parameters[baseSignature.parameters.length - 1].isVarArg;
                }

                currentSignature.addDeclaration(instanceTypeSymbol.getDeclarations()[0]);
                this.addCallOrConstructSignaturePrerequisiteBase(currentSignature);
                signatures.push(currentSignature);
            }

            return signatures;
        };

        PullTypeSymbol.prototype.getDefaultClassConstructSignature = function () {
            TypeScript.Debug.assert(this.isConstructor());
            var instanceTypeSymbol = this.getAssociatedContainerType();
            TypeScript.Debug.assert(instanceTypeSymbol.getDeclarations().length == 1);
            var signature = new PullSignatureSymbol(2097152 /* ConstructSignature */, true);
            signature.returnType = instanceTypeSymbol;
            signature.addTypeParametersFromReturnType();
            signature.addDeclaration(instanceTypeSymbol.getDeclarations()[0]);
            this.addCallOrConstructSignaturePrerequisiteBase(signature);

            return signature;
        };

        PullTypeSymbol.prototype.addImplementedType = function (implementedType) {
            if (!implementedType) {
                return;
            }

            if (!this._implementedTypes) {
                this._implementedTypes = [];
            }

            this._implementedTypes[this._implementedTypes.length] = implementedType;

            implementedType.addTypeThatExplicitlyImplementsThisType(this);
        };

        PullTypeSymbol.prototype.getImplementedTypes = function () {
            if (!this._implementedTypes) {
                return TypeScript.sentinelEmptyArray;
            }

            return this._implementedTypes;
        };

        PullTypeSymbol.prototype.addExtendedType = function (extendedType) {
            if (!extendedType) {
                return;
            }

            if (!this._extendedTypes) {
                this._extendedTypes = [];
            }

            this._extendedTypes[this._extendedTypes.length] = extendedType;

            extendedType.addTypeThatExtendsThisType(this);
        };

        PullTypeSymbol.prototype.getExtendedTypes = function () {
            if (!this._extendedTypes) {
                return TypeScript.sentinelEmptyArray;
            }

            return this._extendedTypes;
        };

        PullTypeSymbol.prototype.addTypeThatExtendsThisType = function (type) {
            if (!type) {
                return;
            }

            if (!this._typesThatExtendThisType) {
                this._typesThatExtendThisType = [];
            }

            this._typesThatExtendThisType[this._typesThatExtendThisType.length] = type;
        };

        PullTypeSymbol.prototype.getTypesThatExtendThisType = function () {
            if (!this._typesThatExtendThisType) {
                this._typesThatExtendThisType = [];
            }

            return this._typesThatExtendThisType;
        };

        PullTypeSymbol.prototype.addTypeThatExplicitlyImplementsThisType = function (type) {
            if (!type) {
                return;
            }

            if (!this._typesThatExplicitlyImplementThisType) {
                this._typesThatExplicitlyImplementThisType = [];
            }

            this._typesThatExplicitlyImplementThisType[this._typesThatExplicitlyImplementThisType.length] = type;
        };

        PullTypeSymbol.prototype.getTypesThatExplicitlyImplementThisType = function () {
            if (!this._typesThatExplicitlyImplementThisType) {
                this._typesThatExplicitlyImplementThisType = [];
            }

            return this._typesThatExplicitlyImplementThisType;
        };

        PullTypeSymbol.prototype.hasBase = function (potentialBase, visited) {
            if (typeof visited === "undefined") { visited = []; }
            if (this === potentialBase || this.getRootSymbol() === potentialBase || this === potentialBase.getRootSymbol()) {
                return true;
            }

            if (TypeScript.ArrayUtilities.contains(visited, this)) {
                return true;
            }

            visited.push(this);

            var extendedTypes = this.getExtendedTypes();

            for (var i = 0; i < extendedTypes.length; i++) {
                if (extendedTypes[i].hasBase(potentialBase, visited)) {
                    return true;
                }
            }

            var implementedTypes = this.getImplementedTypes();

            for (var i = 0; i < implementedTypes.length; i++) {
                if (implementedTypes[i].hasBase(potentialBase, visited)) {
                    return true;
                }
            }

            visited.pop();

            return false;
        };

        PullTypeSymbol.prototype.isValidBaseKind = function (baseType, isExtendedType) {
            if (baseType.isError()) {
                return false;
            }

            var thisIsClass = this.isClass();
            if (isExtendedType) {
                if (thisIsClass) {
                    return baseType.kind === 8 /* Class */;
                }
            } else {
                if (!thisIsClass) {
                    return false;
                }
            }

            return !!(baseType.kind & (16 /* Interface */ | 8 /* Class */));
        };

        PullTypeSymbol.prototype.findMember = function (name, lookInParent) {
            var memberSymbol = null;

            if (this._memberNameCache) {
                memberSymbol = this._memberNameCache[name];
            }

            if (memberSymbol || !lookInParent) {
                return memberSymbol;
            }

            if (this._extendedTypes) {
                for (var i = 0; i < this._extendedTypes.length; i++) {
                    memberSymbol = this._extendedTypes[i].findMember(name, lookInParent);

                    if (memberSymbol) {
                        return memberSymbol;
                    }
                }
            }

            return null;
        };

        PullTypeSymbol.prototype.findNestedType = function (name, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            var memberSymbol;

            if (!this._enclosedTypeNameCache) {
                return null;
            }

            memberSymbol = this._enclosedTypeNameCache[name];

            if (memberSymbol && kind !== 0 /* None */) {
                memberSymbol = TypeScript.hasFlag(memberSymbol.kind, kind) ? memberSymbol : null;
            }

            return memberSymbol;
        };

        PullTypeSymbol.prototype.findNestedContainer = function (name, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            var memberSymbol;

            if (!this._enclosedContainerCache) {
                return null;
            }

            memberSymbol = this._enclosedContainerCache[name];

            if (memberSymbol && kind !== 0 /* None */) {
                memberSymbol = TypeScript.hasFlag(memberSymbol.kind, kind) ? memberSymbol : null;
            }

            return memberSymbol;
        };

        PullTypeSymbol.prototype.getAllMembers = function (searchDeclKind, memberVisiblity) {
            var allMembers = [];

            if (this._members !== TypeScript.sentinelEmptyArray) {
                for (var i = 0, n = this._members.length; i < n; i++) {
                    var member = this._members[i];
                    if ((member.kind & searchDeclKind) && (memberVisiblity !== 2 /* externallyVisible */ || !member.anyDeclHasFlag(2 /* Private */))) {
                        allMembers[allMembers.length] = member;
                    }
                }
            }

            if (this._extendedTypes) {
                var extenedMembersVisibility = memberVisiblity !== 0 /* all */ ? 2 /* externallyVisible */ : 0 /* all */;

                for (var i = 0, n = this._extendedTypes.length; i < n; i++) {
                    var extendedMembers = this._extendedTypes[i].getAllMembers(searchDeclKind, extenedMembersVisibility);

                    for (var j = 0, m = extendedMembers.length; j < m; j++) {
                        var extendedMember = extendedMembers[j];
                        if (!(this._memberNameCache && this._memberNameCache[extendedMember.name])) {
                            allMembers[allMembers.length] = extendedMember;
                        }
                    }
                }
            }

            if (this.isContainer()) {
                if (this._enclosedMemberTypes) {
                    for (var i = 0; i < this._enclosedMemberTypes.length; i++) {
                        allMembers[allMembers.length] = this._enclosedMemberTypes[i];
                    }
                }
                if (this._enclosedMemberContainers) {
                    for (var i = 0; i < this._enclosedMemberContainers.length; i++) {
                        allMembers[allMembers.length] = this._enclosedMemberContainers[i];
                    }
                }
            }

            return allMembers;
        };

        PullTypeSymbol.prototype.findTypeParameter = function (name) {
            if (!this._typeParameterNameCache) {
                return null;
            }

            return this._typeParameterNameCache[name];
        };

        PullTypeSymbol.prototype.setResolved = function () {
            _super.prototype.setResolved.call(this);
        };

        PullTypeSymbol.prototype.getNamePartForFullName = function () {
            var name = _super.prototype.getNamePartForFullName.call(this);

            var typars = this.getTypeArgumentsOrTypeParameters();
            var typarString = PullSymbol.getTypeParameterString(typars, this, true);
            return name + typarString;
        };

        PullTypeSymbol.prototype.getScopedName = function (scopeSymbol, skipTypeParametersInName, useConstraintInName, skipInternalAliasName) {
            return this.getScopedNameEx(scopeSymbol, skipTypeParametersInName, useConstraintInName, false, false, skipInternalAliasName).toString();
        };

        PullTypeSymbol.prototype.isNamedTypeSymbol = function () {
            var kind = this.kind;
            if (kind === 2 /* Primitive */ || kind === 8 /* Class */ || kind === 4 /* Container */ || kind === 32 /* DynamicModule */ || kind === 128 /* TypeAlias */ || kind === 64 /* Enum */ || kind === 8192 /* TypeParameter */ || ((kind === 16 /* Interface */ || kind === 8388608 /* ObjectType */) && this.name !== "")) {
                return true;
            }

            return false;
        };

        PullTypeSymbol.prototype.toString = function (scopeSymbol, useConstraintInName) {
            var s = this.getScopedNameEx(scopeSymbol, false, useConstraintInName).toString();
            return s;
        };

        PullTypeSymbol.prototype.getScopedNameEx = function (scopeSymbol, skipTypeParametersInName, useConstraintInName, getPrettyTypeName, getTypeParamMarkerInfo, skipInternalAliasName, shouldAllowArrayType) {
            if (typeof shouldAllowArrayType === "undefined") { shouldAllowArrayType = true; }
            if (this.isArrayNamedTypeReference() && shouldAllowArrayType) {
                var elementType = this.getElementType();
                var elementMemberName = elementType ? (elementType.isArrayNamedTypeReference() || elementType.isNamedTypeSymbol() ? elementType.getScopedNameEx(scopeSymbol, false, false, getPrettyTypeName, getTypeParamMarkerInfo, skipInternalAliasName) : elementType.getMemberTypeNameEx(false, scopeSymbol, getPrettyTypeName)) : TypeScript.MemberName.create("any");
                return TypeScript.MemberName.create(elementMemberName, "", "[]");
            }

            if (!this.isNamedTypeSymbol()) {
                return this.getMemberTypeNameEx(true, scopeSymbol, getPrettyTypeName);
            }

            if (skipTypeParametersInName) {
                return TypeScript.MemberName.create(_super.prototype.getScopedName.call(this, scopeSymbol, skipTypeParametersInName, useConstraintInName, skipInternalAliasName));
            } else {
                var builder = new TypeScript.MemberNameArray();
                builder.prefix = _super.prototype.getScopedName.call(this, scopeSymbol, skipTypeParametersInName, useConstraintInName, skipInternalAliasName);

                var typars = this.getTypeArgumentsOrTypeParameters();
                builder.add(PullSymbol.getTypeParameterStringEx(typars, scopeSymbol, getTypeParamMarkerInfo, useConstraintInName));

                return builder;
            }
        };

        PullTypeSymbol.prototype.hasOnlyOverloadCallSignatures = function () {
            var members = this.getMembers();
            var callSignatures = this.getCallSignatures();
            var constructSignatures = this.getConstructSignatures();
            return members.length === 0 && constructSignatures.length === 0 && callSignatures.length > 1;
        };

        PullTypeSymbol.prototype.getTypeOfSymbol = function () {
            var associatedContainerType = this.getAssociatedContainerType();
            if (associatedContainerType && associatedContainerType.isNamedTypeSymbol()) {
                return associatedContainerType;
            }

            var functionSymbol = this.getFunctionSymbol();
            if (functionSymbol && functionSymbol.kind === 16384 /* Function */ && !TypeScript.PullHelpers.isSymbolLocal(functionSymbol)) {
                return TypeScript.PullHelpers.isExportedSymbolInClodule(functionSymbol) ? null : functionSymbol;
            }

            return null;
        };

        PullTypeSymbol.prototype.getMemberTypeNameEx = function (topLevel, scopeSymbol, getPrettyTypeName) {
            var members = this.getMembers();
            var callSignatures = this.getCallSignatures();
            var constructSignatures = this.getConstructSignatures();
            var indexSignatures = this.getIndexSignatures();

            var typeOfSymbol = this.getTypeOfSymbol();
            if (typeOfSymbol) {
                var nameForTypeOf = typeOfSymbol.getScopedNameEx(scopeSymbol, true);
                return TypeScript.MemberName.create(nameForTypeOf, "typeof ", "");
            }

            if (members.length > 0 || callSignatures.length > 0 || constructSignatures.length > 0 || indexSignatures.length > 0) {
                if (this._inMemberTypeNameEx) {
                    return TypeScript.MemberName.create("any");
                }

                this._inMemberTypeNameEx = true;

                var allMemberNames = new TypeScript.MemberNameArray();
                var curlies = !topLevel || indexSignatures.length !== 0;
                var delim = "; ";
                for (var i = 0; i < members.length; i++) {
                    if (members[i].kind === 65536 /* Method */ && members[i].type.hasOnlyOverloadCallSignatures()) {
                        var methodCallSignatures = members[i].type.getCallSignatures();
                        var nameStr = members[i].getDisplayName(scopeSymbol) + (members[i].isOptional ? "?" : "");
                        ;
                        var methodMemberNames = PullSignatureSymbol.getSignaturesTypeNameEx(methodCallSignatures, nameStr, false, false, scopeSymbol);
                        allMemberNames.addAll(methodMemberNames);
                    } else {
                        var memberTypeName = members[i].getNameAndTypeNameEx(scopeSymbol);
                        if (memberTypeName.isArray() && memberTypeName.delim === delim) {
                            allMemberNames.addAll(memberTypeName.entries);
                        } else {
                            allMemberNames.add(memberTypeName);
                        }
                    }
                    curlies = true;
                }

                var getPrettyFunctionOverload = getPrettyTypeName && !curlies && this.hasOnlyOverloadCallSignatures();

                var signatureCount = callSignatures.length + constructSignatures.length + indexSignatures.length;
                var useShortFormSignature = !curlies && (signatureCount === 1);
                var signatureMemberName;

                if (callSignatures.length > 0) {
                    signatureMemberName = PullSignatureSymbol.getSignaturesTypeNameEx(callSignatures, "", useShortFormSignature, false, scopeSymbol, getPrettyFunctionOverload);
                    allMemberNames.addAll(signatureMemberName);
                }

                if (constructSignatures.length > 0) {
                    signatureMemberName = PullSignatureSymbol.getSignaturesTypeNameEx(constructSignatures, "new", useShortFormSignature, false, scopeSymbol);
                    allMemberNames.addAll(signatureMemberName);
                }

                if (indexSignatures.length > 0) {
                    signatureMemberName = PullSignatureSymbol.getSignaturesTypeNameEx(indexSignatures, "", useShortFormSignature, true, scopeSymbol);
                    allMemberNames.addAll(signatureMemberName);
                }

                if ((curlies) || (!getPrettyFunctionOverload && (signatureCount > 1) && topLevel)) {
                    allMemberNames.prefix = "{ ";
                    allMemberNames.suffix = "}";
                    allMemberNames.delim = delim;
                } else if (allMemberNames.entries.length > 1) {
                    allMemberNames.delim = delim;
                }

                this._inMemberTypeNameEx = false;

                return allMemberNames;
            }

            return TypeScript.MemberName.create("{}");
        };

        PullTypeSymbol.prototype.getGenerativeTypeClassification = function (enclosingType) {
            return 2 /* Closed */;
        };

        PullTypeSymbol.prototype.wrapsSomeTypeParameter = function (typeParameterArgumentMap, skipTypeArgumentCheck) {
            return this.getWrappingTypeParameterID(typeParameterArgumentMap, skipTypeArgumentCheck) != 0;
        };

        PullTypeSymbol.prototype.getWrappingTypeParameterID = function (typeParameterArgumentMap, skipTypeArgumentCheck) {
            var type = this;

            if (type.isTypeParameter()) {
                if (typeParameterArgumentMap[type.pullSymbolID] || typeParameterArgumentMap[type.getRootSymbol().pullSymbolID]) {
                    return type.pullSymbolID;
                }

                var constraint = type.getConstraint();
                var wrappingTypeParameterID = constraint ? constraint.getWrappingTypeParameterID(typeParameterArgumentMap) : 0;
                return wrappingTypeParameterID;
            }

            if (type.inWrapCheck) {
                return 0;
            }

            this._wrapsTypeParameterCache = this._wrapsTypeParameterCache || new TypeScript.WrapsTypeParameterCache();
            var wrappingTypeParameterID = this._wrapsTypeParameterCache.getWrapsTypeParameter(typeParameterArgumentMap);
            if (wrappingTypeParameterID === undefined) {
                wrappingTypeParameterID = this.getWrappingTypeParameterIDWorker(typeParameterArgumentMap, skipTypeArgumentCheck);

                this._wrapsTypeParameterCache.setWrapsTypeParameter(typeParameterArgumentMap, wrappingTypeParameterID);
            }
            return wrappingTypeParameterID;
        };

        PullTypeSymbol.prototype.getWrappingTypeParameterIDFromSignatures = function (signatures, typeParameterArgumentMap) {
            for (var i = 0; i < signatures.length; i++) {
                var wrappingTypeParameterID = signatures[i].getWrappingTypeParameterID(typeParameterArgumentMap);
                if (wrappingTypeParameterID !== 0) {
                    return wrappingTypeParameterID;
                }
            }

            return 0;
        };

        PullTypeSymbol.prototype.getWrappingTypeParameterIDWorker = function (typeParameterArgumentMap, skipTypeArgumentCheck) {
            var type = this;
            var wrappingTypeParameterID = 0;

            if (!skipTypeArgumentCheck) {
                type.inWrapCheck = true;

                var typeArguments = type.getTypeArguments();

                if (type.isGeneric() && !typeArguments) {
                    typeArguments = type.getTypeParameters();
                }

                if (typeArguments) {
                    for (var i = 0; !wrappingTypeParameterID && i < typeArguments.length; i++) {
                        wrappingTypeParameterID = typeArguments[i].getWrappingTypeParameterID(typeParameterArgumentMap);
                    }
                }
            }

            if (skipTypeArgumentCheck || !(type.kind & 8216 /* SomeInstantiatableType */) || !type.name) {
                var members = type.getAllMembers(68147712 /* SomeValue */, 0 /* all */);
                for (var i = 0; !wrappingTypeParameterID && i < members.length; i++) {
                    TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(members[i]);
                    wrappingTypeParameterID = members[i].type.getWrappingTypeParameterID(typeParameterArgumentMap);
                }

                wrappingTypeParameterID = wrappingTypeParameterID || this.getWrappingTypeParameterIDFromSignatures(type.getCallSignatures(), typeParameterArgumentMap) || this.getWrappingTypeParameterIDFromSignatures(type.getConstructSignatures(), typeParameterArgumentMap) || this.getWrappingTypeParameterIDFromSignatures(type.getIndexSignatures(), typeParameterArgumentMap);
            }

            if (!skipTypeArgumentCheck) {
                type.inWrapCheck = false;
            }

            return wrappingTypeParameterID;
        };

        PullTypeSymbol.prototype.wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReference = function (enclosingType) {
            TypeScript.Debug.assert(this.isNamedTypeSymbol());
            TypeScript.Debug.assert(TypeScript.PullHelpers.getRootType(enclosingType) == enclosingType);
            var knownWrapMap = TypeScript.BitMatrix.getBitMatrix(true);
            var wrapsIntoInfinitelyExpandingTypeReference = this._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceRecurse(enclosingType, knownWrapMap);
            knownWrapMap.release();
            return wrapsIntoInfinitelyExpandingTypeReference;
        };

        PullTypeSymbol.prototype._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceRecurse = function (enclosingType, knownWrapMap) {
            var wrapsIntoInfinitelyExpandingTypeReference = knownWrapMap.valueAt(this.pullSymbolID, enclosingType.pullSymbolID);
            if (wrapsIntoInfinitelyExpandingTypeReference != undefined) {
                return wrapsIntoInfinitelyExpandingTypeReference;
            }

            if (this.inWrapInfiniteExpandingReferenceCheck) {
                return false;
            }

            this.inWrapInfiniteExpandingReferenceCheck = true;
            wrapsIntoInfinitelyExpandingTypeReference = this._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceWorker(enclosingType, knownWrapMap);
            knownWrapMap.setValueAt(this.pullSymbolID, enclosingType.pullSymbolID, wrapsIntoInfinitelyExpandingTypeReference);
            this.inWrapInfiniteExpandingReferenceCheck = false;

            return wrapsIntoInfinitelyExpandingTypeReference;
        };

        PullTypeSymbol.prototype._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceWorker = function (enclosingType, knownWrapMap) {
            var thisRootType = TypeScript.PullHelpers.getRootType(this);

            if (thisRootType != enclosingType) {
                var thisIsNamedType = this.isNamedTypeSymbol();

                if (thisIsNamedType) {
                    if (thisRootType.inWrapInfiniteExpandingReferenceCheck) {
                        return false;
                    }

                    thisRootType.inWrapInfiniteExpandingReferenceCheck = true;
                }

                var wrapsIntoInfinitelyExpandingTypeReference = this._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceStructure(enclosingType, knownWrapMap);

                if (thisIsNamedType) {
                    thisRootType.inWrapInfiniteExpandingReferenceCheck = false;
                }

                return wrapsIntoInfinitelyExpandingTypeReference;
            }

            var enclosingTypeParameters = enclosingType.getTypeParameters();
            var typeArguments = this.getTypeArguments();
            for (var i = 0; i < typeArguments.length; i++) {
                if (TypeScript.ArrayUtilities.contains(enclosingTypeParameters, typeArguments[i])) {
                    continue;
                }

                if (typeArguments[i].wrapsSomeTypeParameter(this.getTypeParameterArgumentMap())) {
                    return true;
                }
            }

            return false;
        };

        PullTypeSymbol.prototype._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceStructure = function (enclosingType, knownWrapMap) {
            var members = this.getAllMembers(68147712 /* SomeValue */, 0 /* all */);
            for (var i = 0; i < members.length; i++) {
                if (members[i].type && members[i].type._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReferenceRecurse(enclosingType, knownWrapMap)) {
                    return true;
                }
            }

            var sigs = this.getCallSignatures();
            for (var i = 0; i < sigs.length; i++) {
                if (sigs[i]._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReference(enclosingType, knownWrapMap)) {
                    return true;
                }
            }

            sigs = this.getConstructSignatures();
            for (var i = 0; i < sigs.length; i++) {
                if (sigs[i]._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReference(enclosingType, knownWrapMap)) {
                    return true;
                }
            }

            sigs = this.getIndexSignatures();
            for (var i = 0; i < sigs.length; i++) {
                if (sigs[i]._wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReference(enclosingType, knownWrapMap)) {
                    return true;
                }
            }

            return false;
        };

        PullTypeSymbol.prototype.widenedType = function (resolver, ast, context) {
            if (!this._widenedType) {
                this._widenedType = resolver.widenType(this, ast, context);
            }
            return this._widenedType;
        };
        return PullTypeSymbol;
    })(PullSymbol);
    TypeScript.PullTypeSymbol = PullTypeSymbol;

    var PullPrimitiveTypeSymbol = (function (_super) {
        __extends(PullPrimitiveTypeSymbol, _super);
        function PullPrimitiveTypeSymbol(name) {
            _super.call(this, name, 2 /* Primitive */);

            this.isResolved = true;
        }
        PullPrimitiveTypeSymbol.prototype.isAny = function () {
            return !this.isStringConstant() && this.name === "any";
        };

        PullPrimitiveTypeSymbol.prototype.isNull = function () {
            return !this.isStringConstant() && this.name === "null";
        };

        PullPrimitiveTypeSymbol.prototype.isUndefined = function () {
            return !this.isStringConstant() && this.name === "undefined";
        };

        PullPrimitiveTypeSymbol.prototype.isStringConstant = function () {
            return false;
        };

        PullPrimitiveTypeSymbol.prototype.setUnresolved = function () {
        };

        PullPrimitiveTypeSymbol.prototype.getDisplayName = function () {
            if (this.isNull() || this.isUndefined()) {
                return "any";
            } else {
                return _super.prototype.getDisplayName.call(this);
            }
        };
        return PullPrimitiveTypeSymbol;
    })(PullTypeSymbol);
    TypeScript.PullPrimitiveTypeSymbol = PullPrimitiveTypeSymbol;

    var PullStringConstantTypeSymbol = (function (_super) {
        __extends(PullStringConstantTypeSymbol, _super);
        function PullStringConstantTypeSymbol(name) {
            _super.call(this, name);
        }
        PullStringConstantTypeSymbol.prototype.isStringConstant = function () {
            return true;
        };
        return PullStringConstantTypeSymbol;
    })(PullPrimitiveTypeSymbol);
    TypeScript.PullStringConstantTypeSymbol = PullStringConstantTypeSymbol;

    var PullErrorTypeSymbol = (function (_super) {
        __extends(PullErrorTypeSymbol, _super);
        function PullErrorTypeSymbol(_anyType, name) {
            _super.call(this, name);
            this._anyType = _anyType;

            TypeScript.Debug.assert(this._anyType);
            this.isResolved = true;
        }
        PullErrorTypeSymbol.prototype.isError = function () {
            return true;
        };

        PullErrorTypeSymbol.prototype._getResolver = function () {
            return this._anyType._getResolver();
        };

        PullErrorTypeSymbol.prototype.getName = function (scopeSymbol, useConstraintInName) {
            return this._anyType.getName(scopeSymbol, useConstraintInName);
        };

        PullErrorTypeSymbol.prototype.getDisplayName = function (scopeSymbol, useConstraintInName, skipInternalAliasName) {
            return this._anyType.getName(scopeSymbol, useConstraintInName);
        };

        PullErrorTypeSymbol.prototype.toString = function (scopeSymbol, useConstraintInName) {
            return this._anyType.getName(scopeSymbol, useConstraintInName);
        };
        return PullErrorTypeSymbol;
    })(PullPrimitiveTypeSymbol);
    TypeScript.PullErrorTypeSymbol = PullErrorTypeSymbol;

    var PullContainerSymbol = (function (_super) {
        __extends(PullContainerSymbol, _super);
        function PullContainerSymbol(name, kind) {
            _super.call(this, name, kind);
            this.instanceSymbol = null;
            this.assignedValue = null;
            this.assignedType = null;
            this.assignedContainer = null;
        }
        PullContainerSymbol.prototype.isContainer = function () {
            return true;
        };

        PullContainerSymbol.prototype.setInstanceSymbol = function (symbol) {
            this.instanceSymbol = symbol;
        };

        PullContainerSymbol.prototype.getInstanceSymbol = function () {
            return this.instanceSymbol;
        };

        PullContainerSymbol.prototype.setExportAssignedValueSymbol = function (symbol) {
            this.assignedValue = symbol;
        };

        PullContainerSymbol.prototype.getExportAssignedValueSymbol = function () {
            return this.assignedValue;
        };

        PullContainerSymbol.prototype.setExportAssignedTypeSymbol = function (type) {
            this.assignedType = type;
        };

        PullContainerSymbol.prototype.getExportAssignedTypeSymbol = function () {
            return this.assignedType;
        };

        PullContainerSymbol.prototype.setExportAssignedContainerSymbol = function (container) {
            this.assignedContainer = container;
        };

        PullContainerSymbol.prototype.getExportAssignedContainerSymbol = function () {
            return this.assignedContainer;
        };

        PullContainerSymbol.prototype.hasExportAssignment = function () {
            return !!this.assignedValue || !!this.assignedType || !!this.assignedContainer;
        };

        PullContainerSymbol.usedAsSymbol = function (containerSymbol, symbol) {
            if (!containerSymbol || !containerSymbol.isContainer()) {
                return false;
            }

            if (!containerSymbol.isAlias() && containerSymbol.type === symbol) {
                return true;
            }

            var moduleSymbol = containerSymbol;
            var valueExportSymbol = moduleSymbol.getExportAssignedValueSymbol();
            var typeExportSymbol = moduleSymbol.getExportAssignedTypeSymbol();
            var containerExportSymbol = moduleSymbol.getExportAssignedContainerSymbol();
            if (valueExportSymbol || typeExportSymbol || containerExportSymbol) {
                if (valueExportSymbol === symbol || typeExportSymbol == symbol || containerExportSymbol == symbol) {
                    return true;
                }

                if (containerExportSymbol != containerSymbol) {
                    return PullContainerSymbol.usedAsSymbol(containerExportSymbol, symbol);
                }
            }

            return false;
        };

        PullContainerSymbol.prototype.getInstanceType = function () {
            return this.instanceSymbol ? this.instanceSymbol.type : null;
        };
        return PullContainerSymbol;
    })(PullTypeSymbol);
    TypeScript.PullContainerSymbol = PullContainerSymbol;

    var PullTypeAliasSymbol = (function (_super) {
        __extends(PullTypeAliasSymbol, _super);
        function PullTypeAliasSymbol(name) {
            _super.call(this, name, 128 /* TypeAlias */);
            this._assignedValue = null;
            this._assignedType = null;
            this._assignedContainer = null;
            this._isUsedAsValue = false;
            this._typeUsedExternally = false;
            this._isUsedInExportAlias = false;
            this.retrievingExportAssignment = false;
            this.linkedAliasSymbols = null;
        }
        PullTypeAliasSymbol.prototype.isUsedInExportedAlias = function () {
            this._resolveDeclaredSymbol();
            return this._isUsedInExportAlias;
        };

        PullTypeAliasSymbol.prototype.typeUsedExternally = function () {
            this._resolveDeclaredSymbol();
            return this._typeUsedExternally;
        };

        PullTypeAliasSymbol.prototype.isUsedAsValue = function () {
            this._resolveDeclaredSymbol();
            return this._isUsedAsValue;
        };

        PullTypeAliasSymbol.prototype.setTypeUsedExternally = function () {
            this._typeUsedExternally = true;
        };

        PullTypeAliasSymbol.prototype.setIsUsedInExportedAlias = function () {
            this._isUsedInExportAlias = true;
            if (this.linkedAliasSymbols) {
                this.linkedAliasSymbols.forEach(function (s) {
                    return s.setIsUsedInExportedAlias();
                });
            }
        };

        PullTypeAliasSymbol.prototype.addLinkedAliasSymbol = function (contingentValueSymbol) {
            if (!this.linkedAliasSymbols) {
                this.linkedAliasSymbols = [contingentValueSymbol];
            } else {
                this.linkedAliasSymbols.push(contingentValueSymbol);
            }
        };

        PullTypeAliasSymbol.prototype.setIsUsedAsValue = function () {
            this._isUsedAsValue = true;
            if (this.linkedAliasSymbols) {
                this.linkedAliasSymbols.forEach(function (s) {
                    return s.setIsUsedAsValue();
                });
            }
        };

        PullTypeAliasSymbol.prototype.assignedValue = function () {
            this._resolveDeclaredSymbol();
            return this._assignedValue;
        };

        PullTypeAliasSymbol.prototype.assignedType = function () {
            this._resolveDeclaredSymbol();
            return this._assignedType;
        };

        PullTypeAliasSymbol.prototype.assignedContainer = function () {
            this._resolveDeclaredSymbol();
            return this._assignedContainer;
        };

        PullTypeAliasSymbol.prototype.isAlias = function () {
            return true;
        };
        PullTypeAliasSymbol.prototype.isContainer = function () {
            return true;
        };

        PullTypeAliasSymbol.prototype.setAssignedValueSymbol = function (symbol) {
            this._assignedValue = symbol;
        };

        PullTypeAliasSymbol.prototype.getExportAssignedValueSymbol = function () {
            if (this._assignedValue) {
                return this._assignedValue;
            }

            if (this.retrievingExportAssignment) {
                return null;
            }

            if (this._assignedContainer) {
                if (this._assignedContainer.hasExportAssignment()) {
                    this.retrievingExportAssignment = true;
                    var sym = this._assignedContainer.getExportAssignedValueSymbol();
                    this.retrievingExportAssignment = false;
                    return sym;
                }

                return this._assignedContainer.getInstanceSymbol();
            }

            return null;
        };

        PullTypeAliasSymbol.prototype.setAssignedTypeSymbol = function (type) {
            this._assignedType = type;
        };

        PullTypeAliasSymbol.prototype.getExportAssignedTypeSymbol = function () {
            if (this.retrievingExportAssignment) {
                return null;
            }

            if (this._assignedType) {
                if (this._assignedType.isAlias()) {
                    this.retrievingExportAssignment = true;
                    var sym = this._assignedType.getExportAssignedTypeSymbol();
                    this.retrievingExportAssignment = false;
                } else if (this._assignedType !== this._assignedContainer) {
                    return this._assignedType;
                }
            }

            if (this._assignedContainer) {
                this.retrievingExportAssignment = true;
                var sym = this._assignedContainer.getExportAssignedTypeSymbol();
                this.retrievingExportAssignment = false;
                if (sym) {
                    return sym;
                }
            }

            return this._assignedContainer;
        };

        PullTypeAliasSymbol.prototype.setAssignedContainerSymbol = function (container) {
            this._assignedContainer = container;
        };

        PullTypeAliasSymbol.prototype.getExportAssignedContainerSymbol = function () {
            if (this.retrievingExportAssignment) {
                return null;
            }

            if (this._assignedContainer) {
                this.retrievingExportAssignment = true;
                var sym = this._assignedContainer.getExportAssignedContainerSymbol();
                this.retrievingExportAssignment = false;
                if (sym) {
                    return sym;
                }
            }

            return this._assignedContainer;
        };

        PullTypeAliasSymbol.prototype.getMembers = function () {
            if (this._assignedType) {
                return this._assignedType.getMembers();
            }

            return TypeScript.sentinelEmptyArray;
        };

        PullTypeAliasSymbol.prototype.getCallSignatures = function () {
            if (this._assignedType) {
                return this._assignedType.getCallSignatures();
            }

            return TypeScript.sentinelEmptyArray;
        };

        PullTypeAliasSymbol.prototype.getConstructSignatures = function () {
            if (this._assignedType) {
                return this._assignedType.getConstructSignatures();
            }

            return TypeScript.sentinelEmptyArray;
        };

        PullTypeAliasSymbol.prototype.getIndexSignatures = function () {
            if (this._assignedType) {
                return this._assignedType.getIndexSignatures();
            }

            return TypeScript.sentinelEmptyArray;
        };

        PullTypeAliasSymbol.prototype.findMember = function (name) {
            if (this._assignedType) {
                return this._assignedType.findMember(name, true);
            }

            return null;
        };

        PullTypeAliasSymbol.prototype.findNestedType = function (name) {
            if (this._assignedType) {
                return this._assignedType.findNestedType(name);
            }

            return null;
        };

        PullTypeAliasSymbol.prototype.findNestedContainer = function (name) {
            if (this._assignedType) {
                return this._assignedType.findNestedContainer(name);
            }

            return null;
        };

        PullTypeAliasSymbol.prototype.getAllMembers = function (searchDeclKind, memberVisibility) {
            if (this._assignedType) {
                return this._assignedType.getAllMembers(searchDeclKind, memberVisibility);
            }

            return TypeScript.sentinelEmptyArray;
        };
        return PullTypeAliasSymbol;
    })(PullTypeSymbol);
    TypeScript.PullTypeAliasSymbol = PullTypeAliasSymbol;

    var PullTypeParameterSymbol = (function (_super) {
        __extends(PullTypeParameterSymbol, _super);
        function PullTypeParameterSymbol(name) {
            _super.call(this, name, 8192 /* TypeParameter */);
            this._constraint = null;
        }
        PullTypeParameterSymbol.prototype.isTypeParameter = function () {
            return true;
        };

        PullTypeParameterSymbol.prototype.setConstraint = function (constraintType) {
            this._constraint = constraintType;
        };

        PullTypeParameterSymbol.prototype.getConstraint = function () {
            return this._constraint;
        };

        PullTypeParameterSymbol.prototype.getBaseConstraint = function (semanticInfoChain) {
            var preBaseConstraint = this.getConstraintRecursively({});
            TypeScript.Debug.assert(preBaseConstraint === null || !preBaseConstraint.isTypeParameter());
            return preBaseConstraint || semanticInfoChain.emptyTypeSymbol;
        };

        PullTypeParameterSymbol.prototype.getConstraintRecursively = function (visitedTypeParameters) {
            var constraint = this.getConstraint();

            if (constraint) {
                if (constraint.isTypeParameter()) {
                    var constraintAsTypeParameter = constraint;
                    if (!visitedTypeParameters[constraintAsTypeParameter.pullSymbolID]) {
                        visitedTypeParameters[constraintAsTypeParameter.pullSymbolID] = constraintAsTypeParameter;
                        return constraintAsTypeParameter.getConstraintRecursively(visitedTypeParameters);
                    }
                } else {
                    return constraint;
                }
            }

            return null;
        };

        PullTypeParameterSymbol.prototype.getDefaultConstraint = function (semanticInfoChain) {
            return this._constraint || semanticInfoChain.emptyTypeSymbol;
        };

        PullTypeParameterSymbol.prototype.getCallSignatures = function () {
            if (this._constraint) {
                return this._constraint.getCallSignatures();
            }

            return _super.prototype.getCallSignatures.call(this);
        };

        PullTypeParameterSymbol.prototype.getConstructSignatures = function () {
            if (this._constraint) {
                return this._constraint.getConstructSignatures();
            }

            return _super.prototype.getConstructSignatures.call(this);
        };

        PullTypeParameterSymbol.prototype.getIndexSignatures = function () {
            if (this._constraint) {
                return this._constraint.getIndexSignatures();
            }

            return _super.prototype.getIndexSignatures.call(this);
        };

        PullTypeParameterSymbol.prototype.isGeneric = function () {
            return true;
        };

        PullTypeParameterSymbol.prototype.fullName = function (scopeSymbol) {
            var name = this.getDisplayName(scopeSymbol);
            var container = this.getContainer();
            if (container) {
                var containerName = container.fullName(scopeSymbol);
                name = name + " in " + containerName;
            }

            return name;
        };

        PullTypeParameterSymbol.prototype.getName = function (scopeSymbol, useConstraintInName) {
            var name = _super.prototype.getName.call(this, scopeSymbol);

            if (this.isPrinting) {
                return name;
            }

            this.isPrinting = true;

            if (useConstraintInName && this._constraint) {
                name += " extends " + this._constraint.toString(scopeSymbol);
            }

            this.isPrinting = false;

            return name;
        };

        PullTypeParameterSymbol.prototype.getDisplayName = function (scopeSymbol, useConstraintInName, skipInternalAliasName) {
            var name = _super.prototype.getDisplayName.call(this, scopeSymbol, useConstraintInName, skipInternalAliasName);

            if (this.isPrinting) {
                return name;
            }

            this.isPrinting = true;

            if (useConstraintInName && this._constraint) {
                name += " extends " + this._constraint.toString(scopeSymbol);
            }

            this.isPrinting = false;

            return name;
        };

        PullTypeParameterSymbol.prototype.isExternallyVisible = function (inIsExternallyVisibleSymbols) {
            return true;
        };
        return PullTypeParameterSymbol;
    })(PullTypeSymbol);
    TypeScript.PullTypeParameterSymbol = PullTypeParameterSymbol;

    var PullAccessorSymbol = (function (_super) {
        __extends(PullAccessorSymbol, _super);
        function PullAccessorSymbol(name) {
            _super.call(this, name, 4096 /* Property */);
            this._getterSymbol = null;
            this._setterSymbol = null;
        }
        PullAccessorSymbol.prototype.isAccessor = function () {
            return true;
        };

        PullAccessorSymbol.prototype.setSetter = function (setter) {
            if (!setter) {
                return;
            }

            this._setterSymbol = setter;
        };

        PullAccessorSymbol.prototype.getSetter = function () {
            return this._setterSymbol;
        };

        PullAccessorSymbol.prototype.setGetter = function (getter) {
            if (!getter) {
                return;
            }

            this._getterSymbol = getter;
        };

        PullAccessorSymbol.prototype.getGetter = function () {
            return this._getterSymbol;
        };
        return PullAccessorSymbol;
    })(PullSymbol);
    TypeScript.PullAccessorSymbol = PullAccessorSymbol;

    function getIDForTypeSubstitutions(instantiatingTypeOrSignature, typeArgumentMap) {
        var substitution = "";
        var members = null;

        var allowedToReferenceTypeParameters = instantiatingTypeOrSignature.getAllowedToReferenceTypeParameters();
        for (var i = 0; i < allowedToReferenceTypeParameters.length; i++) {
            var typeParameter = allowedToReferenceTypeParameters[i];
            var typeParameterID = typeParameter.pullSymbolID;
            var typeArg = typeArgumentMap[typeParameterID];
            if (!typeArg) {
                typeArg = typeParameter;
            }
            substitution += typeParameterID + ":" + getIDForTypeSubstitutionsOfType(typeArg);
        }

        return substitution;
    }
    TypeScript.getIDForTypeSubstitutions = getIDForTypeSubstitutions;

    function getIDForTypeSubstitutionsOfType(type) {
        var structure;
        if (type.isError()) {
            structure = "E" + getIDForTypeSubstitutionsOfType(type._anyType);
        } else if (!type.isNamedTypeSymbol()) {
            structure = getIDForTypeSubstitutionsFromObjectType(type);
        }

        if (!structure) {
            structure = type.pullSymbolID + "#";
        }

        return structure;
    }

    function getIDForTypeSubstitutionsFromObjectType(type) {
        if (type.isResolved) {
            var getIDForTypeSubStitutionWalker = new GetIDForTypeSubStitutionWalker();
            TypeScript.PullHelpers.walkPullTypeSymbolStructure(type, getIDForTypeSubStitutionWalker);
        }

        return null;
    }

    var GetIDForTypeSubStitutionWalker = (function () {
        function GetIDForTypeSubStitutionWalker() {
            this.structure = "";
        }
        GetIDForTypeSubStitutionWalker.prototype.memberSymbolWalk = function (memberSymbol) {
            this.structure += memberSymbol.name + "@" + getIDForTypeSubstitutionsOfType(memberSymbol.type);
            return true;
        };
        GetIDForTypeSubStitutionWalker.prototype.callSignatureWalk = function (signatureSymbol) {
            this.structure += "(";
            return true;
        };
        GetIDForTypeSubStitutionWalker.prototype.constructSignatureWalk = function (signatureSymbol) {
            this.structure += "new(";
            return true;
        };
        GetIDForTypeSubStitutionWalker.prototype.indexSignatureWalk = function (signatureSymbol) {
            this.structure += "[](";
            return true;
        };
        GetIDForTypeSubStitutionWalker.prototype.signatureParameterWalk = function (parameterSymbol) {
            this.structure += parameterSymbol.name + "@" + getIDForTypeSubstitutionsOfType(parameterSymbol.type);
            return true;
        };
        GetIDForTypeSubStitutionWalker.prototype.signatureReturnTypeWalk = function (returnType) {
            this.structure += ")" + getIDForTypeSubstitutionsOfType(returnType);
            return true;
        };
        return GetIDForTypeSubStitutionWalker;
    })();

    (function (GetAllMembersVisiblity) {
        GetAllMembersVisiblity[GetAllMembersVisiblity["all"] = 0] = "all";

        GetAllMembersVisiblity[GetAllMembersVisiblity["internallyVisible"] = 1] = "internallyVisible";

        GetAllMembersVisiblity[GetAllMembersVisiblity["externallyVisible"] = 2] = "externallyVisible";
    })(TypeScript.GetAllMembersVisiblity || (TypeScript.GetAllMembersVisiblity = {}));
    var GetAllMembersVisiblity = TypeScript.GetAllMembersVisiblity;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var EnclosingTypeWalkerState = (function () {
        function EnclosingTypeWalkerState() {
        }
        EnclosingTypeWalkerState.getDefaultEnclosingTypeWalkerState = function () {
            var defaultEnclosingTypeWalkerState = new EnclosingTypeWalkerState();
            defaultEnclosingTypeWalkerState._hasSetEnclosingType = false;
            return defaultEnclosingTypeWalkerState;
        };

        EnclosingTypeWalkerState.getNonGenericEnclosingTypeWalkerState = function () {
            var defaultEnclosingTypeWalkerState = new EnclosingTypeWalkerState();
            defaultEnclosingTypeWalkerState._hasSetEnclosingType = true;
            return defaultEnclosingTypeWalkerState;
        };

        EnclosingTypeWalkerState.getGenericEnclosingTypeWalkerState = function (genericEnclosingType) {
            var defaultEnclosingTypeWalkerState = new EnclosingTypeWalkerState();
            defaultEnclosingTypeWalkerState._hasSetEnclosingType = true;
            defaultEnclosingTypeWalkerState._currentSymbols = [TypeScript.PullHelpers.getRootType(genericEnclosingType)];
            return defaultEnclosingTypeWalkerState;
        };
        return EnclosingTypeWalkerState;
    })();
    TypeScript.EnclosingTypeWalkerState = EnclosingTypeWalkerState;

    var PullTypeEnclosingTypeWalker = (function () {
        function PullTypeEnclosingTypeWalker() {
            this.setDefaultTypeWalkerState();
        }
        PullTypeEnclosingTypeWalker.prototype.setDefaultTypeWalkerState = function () {
            this.enclosingTypeWalkerState = PullTypeEnclosingTypeWalker._defaultEnclosingTypeWalkerState;
        };

        PullTypeEnclosingTypeWalker.prototype.setNonGenericEnclosingTypeWalkerState = function () {
            this.enclosingTypeWalkerState = PullTypeEnclosingTypeWalker._nonGenericEnclosingTypeWalkerState;
        };

        PullTypeEnclosingTypeWalker.prototype.canSymbolOrDeclBeUsedAsEnclosingTypeHelper = function (name, kind) {
            return name && (kind === 8 /* Class */ || kind === 16 /* Interface */);
        };

        PullTypeEnclosingTypeWalker.prototype.canDeclBeUsedAsEnclosingType = function (decl) {
            return this.canSymbolOrDeclBeUsedAsEnclosingTypeHelper(decl.name, decl.kind);
        };

        PullTypeEnclosingTypeWalker.prototype.canSymbolBeUsedAsEnclosingType = function (symbol) {
            return this.canSymbolOrDeclBeUsedAsEnclosingTypeHelper(symbol.name, symbol.kind);
        };

        PullTypeEnclosingTypeWalker.prototype.getEnclosingType = function () {
            var currentSymbols = this.enclosingTypeWalkerState._currentSymbols;
            if (currentSymbols) {
                TypeScript.Debug.assert(currentSymbols.length > 0);
                return currentSymbols[0];
            }

            return null;
        };

        PullTypeEnclosingTypeWalker.prototype._canWalkStructure = function () {
            var enclosingType = this.getEnclosingType();
            TypeScript.Debug.assert(!enclosingType || enclosingType.isGeneric());
            return !!enclosingType;
        };

        PullTypeEnclosingTypeWalker.prototype._getCurrentSymbol = function () {
            var currentSymbols = this.enclosingTypeWalkerState._currentSymbols;
            if (currentSymbols && currentSymbols.length) {
                return currentSymbols[currentSymbols.length - 1];
            }

            return null;
        };

        PullTypeEnclosingTypeWalker.prototype.getGenerativeClassification = function () {
            if (this._canWalkStructure()) {
                var currentType = this._getCurrentSymbol();
                if (!currentType) {
                    return 0 /* Unknown */;
                }

                var variableNeededToFixNodeJitterBug = this.getEnclosingType();

                return currentType.getGenerativeTypeClassification(variableNeededToFixNodeJitterBug);
            }

            return 2 /* Closed */;
        };

        PullTypeEnclosingTypeWalker.prototype._pushSymbol = function (symbol) {
            return this.enclosingTypeWalkerState._currentSymbols.push(symbol);
        };

        PullTypeEnclosingTypeWalker.prototype._popSymbol = function () {
            return this.enclosingTypeWalkerState._currentSymbols.pop();
        };

        PullTypeEnclosingTypeWalker.prototype.setSymbolAsEnclosingType = function (type) {
            if (type.isGeneric()) {
                this.enclosingTypeWalkerState = EnclosingTypeWalkerState.getGenericEnclosingTypeWalkerState(type);
            } else {
                this.setNonGenericEnclosingTypeWalkerState();
            }
        };

        PullTypeEnclosingTypeWalker.prototype._setEnclosingTypeOfParentDecl = function (decl, setSignature) {
            var parentDecl = decl.getParentDecl();

            if (parentDecl && !(parentDecl.kind & (164 /* SomeContainer */ | 1 /* Script */))) {
                if (this.canDeclBeUsedAsEnclosingType(parentDecl)) {
                    this.setSymbolAsEnclosingType(parentDecl.getSymbol());
                } else {
                    this._setEnclosingTypeOfParentDecl(parentDecl, true);
                }

                if (this._canWalkStructure()) {
                    var symbol = decl.getSymbol();
                    if (symbol) {
                        if (!symbol.isType() && !symbol.isSignature()) {
                            symbol = symbol.type;
                        }

                        this._pushSymbol(symbol);
                    }

                    if (setSignature) {
                        var signature = decl.getSignatureSymbol();
                        if (signature) {
                            this._pushSymbol(signature);
                        }
                    }
                }
            }
        };

        PullTypeEnclosingTypeWalker.prototype.setEnclosingTypeForSymbol = function (symbol) {
            var currentEnclosingTypeWalkerState = this.enclosingTypeWalkerState;
            if (this.canSymbolBeUsedAsEnclosingType(symbol)) {
                this.setSymbolAsEnclosingType(symbol);
            } else {
                this.setDefaultTypeWalkerState();

                var decls = symbol.getDeclarations();
                for (var i = 0; i < decls.length; i++) {
                    var decl = decls[i];
                    this._setEnclosingTypeOfParentDecl(decl, symbol.isSignature());

                    if (this.enclosingTypeWalkerState._hasSetEnclosingType) {
                        break;
                    }
                }

                if (!this.enclosingTypeWalkerState._hasSetEnclosingType) {
                    this.setNonGenericEnclosingTypeWalkerState();
                }
            }
            return currentEnclosingTypeWalkerState;
        };

        PullTypeEnclosingTypeWalker.prototype.startWalkingType = function (symbol) {
            var currentState = this.enclosingTypeWalkerState;

            var setEnclosingTypeForSymbol = !this.enclosingTypeWalkerState._hasSetEnclosingType || this.canSymbolBeUsedAsEnclosingType(symbol);
            if (setEnclosingTypeForSymbol) {
                this.setEnclosingTypeForSymbol(symbol);
            }
            return currentState;
        };

        PullTypeEnclosingTypeWalker.prototype.endWalkingType = function (stateWhenStartedWalkingTypes) {
            this.enclosingTypeWalkerState = stateWhenStartedWalkingTypes;
        };

        PullTypeEnclosingTypeWalker.prototype.walkMemberType = function (memberName, resolver) {
            if (this._canWalkStructure()) {
                var currentType = this._getCurrentSymbol();
                var memberSymbol = currentType ? resolver._getNamedPropertySymbolOfAugmentedType(memberName, currentType) : null;
                this._pushSymbol(memberSymbol ? memberSymbol.type : null);
            }
        };

        PullTypeEnclosingTypeWalker.prototype.postWalkMemberType = function () {
            if (this._canWalkStructure()) {
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.walkSignature = function (kind, index) {
            if (this._canWalkStructure()) {
                var currentType = this._getCurrentSymbol();
                var signatures;
                if (currentType) {
                    if (kind == 1048576 /* CallSignature */) {
                        signatures = currentType.getCallSignatures();
                    } else if (kind == 2097152 /* ConstructSignature */) {
                        signatures = currentType.getConstructSignatures();
                    } else {
                        signatures = currentType.getIndexSignatures();
                    }
                }

                this._pushSymbol(signatures ? signatures[index] : null);
            }
        };

        PullTypeEnclosingTypeWalker.prototype.postWalkSignature = function () {
            if (this._canWalkStructure()) {
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.walkTypeArgument = function (index) {
            if (this._canWalkStructure()) {
                var typeArgument = null;
                var currentType = this._getCurrentSymbol();
                if (currentType) {
                    var typeArguments = currentType.getTypeArguments();
                    typeArgument = typeArguments ? typeArguments[index] : null;
                }
                this._pushSymbol(typeArgument);
            }
        };

        PullTypeEnclosingTypeWalker.prototype.postWalkTypeArgument = function () {
            if (this._canWalkStructure()) {
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.walkTypeParameterConstraint = function (index) {
            if (this._canWalkStructure()) {
                var typeParameters;
                var currentSymbol = this._getCurrentSymbol();
                if (currentSymbol) {
                    if (currentSymbol.isSignature()) {
                        typeParameters = currentSymbol.getTypeParameters();
                    } else {
                        TypeScript.Debug.assert(currentSymbol.isType());
                        typeParameters = currentSymbol.getTypeParameters();
                    }
                }
                this._pushSymbol(typeParameters ? typeParameters[index].getConstraint() : null);
            }
        };

        PullTypeEnclosingTypeWalker.prototype.postWalkTypeParameterConstraint = function () {
            if (this._canWalkStructure()) {
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.walkReturnType = function () {
            if (this._canWalkStructure()) {
                var currentSignature = this._getCurrentSymbol();
                this._pushSymbol(currentSignature ? currentSignature.returnType : null);
            }
        };

        PullTypeEnclosingTypeWalker.prototype.postWalkReturnType = function () {
            if (this._canWalkStructure()) {
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.walkParameterType = function (iParam) {
            if (this._canWalkStructure()) {
                var currentSignature = this._getCurrentSymbol();
                this._pushSymbol(currentSignature ? currentSignature.getParameterTypeAtIndex(iParam) : null);
            }
        };
        PullTypeEnclosingTypeWalker.prototype.postWalkParameterType = function () {
            if (this._canWalkStructure()) {
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.getBothKindOfIndexSignatures = function (resolver, context, includeAugmentedType) {
            if (this._canWalkStructure()) {
                var currentType = this._getCurrentSymbol();
                if (currentType) {
                    return resolver._getBothKindsOfIndexSignatures(currentType, context, includeAugmentedType);
                }
            }
            return null;
        };

        PullTypeEnclosingTypeWalker.prototype.walkIndexSignatureReturnType = function (indexSigInfo, useStringIndexSignature, onlySignature) {
            if (this._canWalkStructure()) {
                var indexSig = indexSigInfo ? (useStringIndexSignature ? indexSigInfo.stringSignature : indexSigInfo.numericSignature) : null;
                this._pushSymbol(indexSig);
                if (!onlySignature) {
                    this._pushSymbol(indexSig ? indexSig.returnType : null);
                }
            }
        };

        PullTypeEnclosingTypeWalker.prototype.postWalkIndexSignatureReturnType = function (onlySignature) {
            if (this._canWalkStructure()) {
                if (!onlySignature) {
                    this._popSymbol();
                }
                this._popSymbol();
            }
        };

        PullTypeEnclosingTypeWalker.prototype.resetEnclosingTypeWalkerState = function () {
            var currentState = this.enclosingTypeWalkerState;
            this.setDefaultTypeWalkerState();
            return currentState;
        };

        PullTypeEnclosingTypeWalker.prototype.setEnclosingTypeWalkerState = function (enclosingTypeWalkerState) {
            if (enclosingTypeWalkerState) {
                this.enclosingTypeWalkerState = enclosingTypeWalkerState;
            } else {
                this.setDefaultTypeWalkerState();
            }
        };
        PullTypeEnclosingTypeWalker._defaultEnclosingTypeWalkerState = EnclosingTypeWalkerState.getDefaultEnclosingTypeWalkerState();

        PullTypeEnclosingTypeWalker._nonGenericEnclosingTypeWalkerState = EnclosingTypeWalkerState.getNonGenericEnclosingTypeWalkerState();
        return PullTypeEnclosingTypeWalker;
    })();
    TypeScript.PullTypeEnclosingTypeWalker = PullTypeEnclosingTypeWalker;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var CandidateInferenceInfo = (function () {
        function CandidateInferenceInfo() {
            this.typeParameter = null;
            this._inferredTypeAfterFixing = null;
            this.inferenceCandidates = [];
        }
        CandidateInferenceInfo.prototype.addCandidate = function (candidate) {
            if (!this._inferredTypeAfterFixing) {
                this.inferenceCandidates[this.inferenceCandidates.length] = candidate;
            }
        };

        CandidateInferenceInfo.prototype.isFixed = function () {
            return !!this._inferredTypeAfterFixing;
        };

        CandidateInferenceInfo.prototype.fixTypeParameter = function (resolver, context) {
            var _this = this;
            if (!this._inferredTypeAfterFixing) {
                var collection = {
                    getLength: function () {
                        return _this.inferenceCandidates.length;
                    },
                    getTypeAtIndex: function (index) {
                        return _this.inferenceCandidates[index].type;
                    }
                };

                var bestCommonType = resolver.findBestCommonType(collection, context, new TypeScript.TypeComparisonInfo());
                this._inferredTypeAfterFixing = bestCommonType.widenedType(resolver, null, context);
            }
        };
        return CandidateInferenceInfo;
    })();
    TypeScript.CandidateInferenceInfo = CandidateInferenceInfo;

    var TypeArgumentInferenceContext = (function () {
        function TypeArgumentInferenceContext(resolver, context, signatureBeingInferred) {
            this.resolver = resolver;
            this.context = context;
            this.signatureBeingInferred = signatureBeingInferred;
            this.inferenceCache = TypeScript.BitMatrix.getBitMatrix(false);
            this.candidateCache = [];
            var typeParameters = signatureBeingInferred.getTypeParameters();
            for (var i = 0; i < typeParameters.length; i++) {
                this.addInferenceRoot(typeParameters[i]);
            }
        }
        TypeArgumentInferenceContext.prototype.alreadyRelatingTypes = function (objectType, parameterType) {
            if (this.inferenceCache.valueAt(objectType.pullSymbolID, parameterType.pullSymbolID)) {
                return true;
            } else {
                this.inferenceCache.setValueAt(objectType.pullSymbolID, parameterType.pullSymbolID, true);
                return false;
            }
        };

        TypeArgumentInferenceContext.prototype.resetRelationshipCache = function () {
            this.inferenceCache.release();
            this.inferenceCache = TypeScript.BitMatrix.getBitMatrix(false);
        };

        TypeArgumentInferenceContext.prototype.addInferenceRoot = function (param) {
            var info = this.candidateCache[param.pullSymbolID];

            if (!info) {
                info = new CandidateInferenceInfo();
                info.typeParameter = param;
                this.candidateCache[param.pullSymbolID] = info;
            }
        };

        TypeArgumentInferenceContext.prototype.getInferenceInfo = function (param) {
            return this.candidateCache[param.pullSymbolID];
        };

        TypeArgumentInferenceContext.prototype.addCandidateForInference = function (param, candidate) {
            var info = this.getInferenceInfo(param);

            if (info && candidate && info.inferenceCandidates.indexOf(candidate) < 0) {
                info.addCandidate(candidate);
            }
        };

        TypeArgumentInferenceContext.prototype.inferTypeArguments = function () {
            throw TypeScript.Errors.abstract();
        };

        TypeArgumentInferenceContext.prototype.fixTypeParameter = function (typeParameter) {
            var candidateInfo = this.candidateCache[typeParameter.pullSymbolID];
            if (candidateInfo) {
                candidateInfo.fixTypeParameter(this.resolver, this.context);
            }
        };

        TypeArgumentInferenceContext.prototype._finalizeInferredTypeArguments = function () {
            var results = [];
            var typeParameters = this.signatureBeingInferred.getTypeParameters();
            for (var i = 0; i < typeParameters.length; i++) {
                var info = this.candidateCache[typeParameters[i].pullSymbolID];

                info.fixTypeParameter(this.resolver, this.context);

                for (var i = 0; i < results.length; i++) {
                    if (results[i].type === info.typeParameter) {
                        results[i].type = info._inferredTypeAfterFixing;
                    }
                }

                results.push(info._inferredTypeAfterFixing);
            }

            return results;
        };

        TypeArgumentInferenceContext.prototype.isInvocationInferenceContext = function () {
            throw TypeScript.Errors.abstract();
        };
        return TypeArgumentInferenceContext;
    })();
    TypeScript.TypeArgumentInferenceContext = TypeArgumentInferenceContext;

    var InvocationTypeArgumentInferenceContext = (function (_super) {
        __extends(InvocationTypeArgumentInferenceContext, _super);
        function InvocationTypeArgumentInferenceContext(resolver, context, signatureBeingInferred, argumentASTs) {
            _super.call(this, resolver, context, signatureBeingInferred);
            this.argumentASTs = argumentASTs;
        }
        InvocationTypeArgumentInferenceContext.prototype.isInvocationInferenceContext = function () {
            return true;
        };

        InvocationTypeArgumentInferenceContext.prototype.inferTypeArguments = function () {
            var _this = this;
            this.signatureBeingInferred.forAllParameterTypes(this.argumentASTs.nonSeparatorCount(), function (parameterType, argumentIndex) {
                var argumentAST = _this.argumentASTs.nonSeparatorAt(argumentIndex);

                _this.context.pushInferentialType(parameterType, _this);
                var argumentType = _this.resolver.resolveAST(argumentAST, true, _this.context).type;
                _this.resolver.relateTypeToTypeParametersWithNewEnclosingTypes(argumentType, parameterType, _this, _this.context);
                _this.context.popAnyContextualType();

                return true;
            });

            return this._finalizeInferredTypeArguments();
        };
        return InvocationTypeArgumentInferenceContext;
    })(TypeArgumentInferenceContext);
    TypeScript.InvocationTypeArgumentInferenceContext = InvocationTypeArgumentInferenceContext;

    var ContextualSignatureInstantiationTypeArgumentInferenceContext = (function (_super) {
        __extends(ContextualSignatureInstantiationTypeArgumentInferenceContext, _super);
        function ContextualSignatureInstantiationTypeArgumentInferenceContext(resolver, context, signatureBeingInferred, contextualSignature, shouldFixContextualSignatureParameterTypes) {
            _super.call(this, resolver, context, signatureBeingInferred);
            this.contextualSignature = contextualSignature;
            this.shouldFixContextualSignatureParameterTypes = shouldFixContextualSignatureParameterTypes;
        }
        ContextualSignatureInstantiationTypeArgumentInferenceContext.prototype.isInvocationInferenceContext = function () {
            return false;
        };

        ContextualSignatureInstantiationTypeArgumentInferenceContext.prototype.inferTypeArguments = function () {
            var _this = this;
            var relateTypesCallback = function (parameterTypeBeingInferred, contextualParameterType) {
                if (_this.shouldFixContextualSignatureParameterTypes) {
                    contextualParameterType = _this.context.fixAllTypeParametersReferencedByType(contextualParameterType, _this.resolver, _this);
                }
                _this.resolver.relateTypeToTypeParametersWithNewEnclosingTypes(contextualParameterType, parameterTypeBeingInferred, _this, _this.context);

                return true;
            };

            this.signatureBeingInferred.forAllCorrespondingParameterTypesInThisAndOtherSignature(this.contextualSignature, relateTypesCallback);

            return this._finalizeInferredTypeArguments();
        };
        return ContextualSignatureInstantiationTypeArgumentInferenceContext;
    })(TypeArgumentInferenceContext);
    TypeScript.ContextualSignatureInstantiationTypeArgumentInferenceContext = ContextualSignatureInstantiationTypeArgumentInferenceContext;

    var PullContextualTypeContext = (function () {
        function PullContextualTypeContext(contextualType, provisional, isInferentiallyTyping, typeArgumentInferenceContext) {
            this.contextualType = contextualType;
            this.provisional = provisional;
            this.isInferentiallyTyping = isInferentiallyTyping;
            this.typeArgumentInferenceContext = typeArgumentInferenceContext;
            this.provisionallyTypedSymbols = [];
            this.hasProvisionalErrors = false;
            this.astSymbolMap = [];
        }
        PullContextualTypeContext.prototype.recordProvisionallyTypedSymbol = function (symbol) {
            this.provisionallyTypedSymbols[this.provisionallyTypedSymbols.length] = symbol;
        };

        PullContextualTypeContext.prototype.invalidateProvisionallyTypedSymbols = function () {
            for (var i = 0; i < this.provisionallyTypedSymbols.length; i++) {
                this.provisionallyTypedSymbols[i].setUnresolved();
            }
        };

        PullContextualTypeContext.prototype.setSymbolForAST = function (ast, symbol) {
            this.astSymbolMap[ast.syntaxID()] = symbol;
        };

        PullContextualTypeContext.prototype.getSymbolForAST = function (ast) {
            return this.astSymbolMap[ast.syntaxID()];
        };
        return PullContextualTypeContext;
    })();
    TypeScript.PullContextualTypeContext = PullContextualTypeContext;

    var PullTypeResolutionContext = (function () {
        function PullTypeResolutionContext(resolver, inTypeCheck, fileName) {
            if (typeof inTypeCheck === "undefined") { inTypeCheck = false; }
            if (typeof fileName === "undefined") { fileName = null; }
            this.resolver = resolver;
            this.inTypeCheck = inTypeCheck;
            this.fileName = fileName;
            this.contextStack = [];
            this.typeCheckedNodes = null;
            this.enclosingTypeWalker1 = null;
            this.enclosingTypeWalker2 = null;
            this.inBaseTypeResolution = false;
            if (inTypeCheck) {
                TypeScript.Debug.assert(fileName, "A file name must be provided if you are typechecking");
                this.typeCheckedNodes = TypeScript.BitVector.getBitVector(false);
            }
        }
        PullTypeResolutionContext.prototype.setTypeChecked = function (ast) {
            if (!this.inProvisionalResolution()) {
                this.typeCheckedNodes.setValueAt(ast.syntaxID(), true);
            }
        };

        PullTypeResolutionContext.prototype.canTypeCheckAST = function (ast) {
            return this.typeCheck() && !this.typeCheckedNodes.valueAt(ast.syntaxID()) && this.fileName === ast.fileName();
        };

        PullTypeResolutionContext.prototype._pushAnyContextualType = function (type, provisional, isInferentiallyTyping, argContext) {
            this.contextStack.push(new PullContextualTypeContext(type, provisional, isInferentiallyTyping, argContext));
        };

        PullTypeResolutionContext.prototype.pushNewContextualType = function (type) {
            this._pushAnyContextualType(type, this.inProvisionalResolution(), false, null);
        };

        PullTypeResolutionContext.prototype.propagateContextualType = function (type) {
            this._pushAnyContextualType(type, this.inProvisionalResolution(), this.isInferentiallyTyping(), this.getCurrentTypeArgumentInferenceContext());
        };

        PullTypeResolutionContext.prototype.pushInferentialType = function (type, typeArgumentInferenceContext) {
            this._pushAnyContextualType(type, true, true, typeArgumentInferenceContext);
        };

        PullTypeResolutionContext.prototype.pushProvisionalType = function (type) {
            this._pushAnyContextualType(type, true, false, null);
        };

        PullTypeResolutionContext.prototype.popAnyContextualType = function () {
            var tc = this.contextStack.pop();

            tc.invalidateProvisionallyTypedSymbols();

            if (tc.hasProvisionalErrors && this.inProvisionalResolution()) {
                this.contextStack[this.contextStack.length - 1].hasProvisionalErrors = true;
            }

            return tc;
        };

        PullTypeResolutionContext.prototype.hasProvisionalErrors = function () {
            return this.contextStack.length ? this.contextStack[this.contextStack.length - 1].hasProvisionalErrors : false;
        };

        PullTypeResolutionContext.prototype.getContextualType = function () {
            var context = !this.contextStack.length ? null : this.contextStack[this.contextStack.length - 1];

            if (context) {
                var type = context.contextualType;

                if (!type) {
                    return null;
                }

                return type;
            }

            return null;
        };

        PullTypeResolutionContext.prototype.fixAllTypeParametersReferencedByType = function (type, resolver, argContext) {
            var argContext = this.getCurrentTypeArgumentInferenceContext();
            if (type.wrapsSomeTypeParameter(argContext.candidateCache)) {
                var typeParameterArgumentMap = [];

                for (var n in argContext.candidateCache) {
                    var typeParameter = argContext.candidateCache[n] && argContext.candidateCache[n].typeParameter;
                    if (typeParameter) {
                        var dummyMap = [];
                        dummyMap[typeParameter.pullSymbolID] = typeParameter;
                        if (type.wrapsSomeTypeParameter(dummyMap)) {
                            argContext.fixTypeParameter(typeParameter);
                            TypeScript.Debug.assert(argContext.candidateCache[n]._inferredTypeAfterFixing);
                            typeParameterArgumentMap[typeParameter.pullSymbolID] = argContext.candidateCache[n]._inferredTypeAfterFixing;
                        }
                    }
                }

                return resolver.instantiateType(type, typeParameterArgumentMap);
            }

            return type;
        };

        PullTypeResolutionContext.prototype.getCurrentTypeArgumentInferenceContext = function () {
            return this.contextStack.length ? this.contextStack[this.contextStack.length - 1].typeArgumentInferenceContext : null;
        };

        PullTypeResolutionContext.prototype.isInferentiallyTyping = function () {
            return this.contextStack.length > 0 && this.contextStack[this.contextStack.length - 1].isInferentiallyTyping;
        };

        PullTypeResolutionContext.prototype.inProvisionalResolution = function () {
            return (!this.contextStack.length ? false : this.contextStack[this.contextStack.length - 1].provisional);
        };

        PullTypeResolutionContext.prototype.isInBaseTypeResolution = function () {
            return this.inBaseTypeResolution;
        };

        PullTypeResolutionContext.prototype.startBaseTypeResolution = function () {
            var wasInBaseTypeResoltion = this.inBaseTypeResolution;
            this.inBaseTypeResolution = true;
            return wasInBaseTypeResoltion;
        };

        PullTypeResolutionContext.prototype.doneBaseTypeResolution = function (wasInBaseTypeResolution) {
            this.inBaseTypeResolution = wasInBaseTypeResolution;
        };

        PullTypeResolutionContext.prototype.setTypeInContext = function (symbol, type) {
            if (symbol.type && symbol.type.isError() && !type.isError()) {
                return;
            }
            symbol.type = type;

            if (this.contextStack.length && this.inProvisionalResolution()) {
                this.contextStack[this.contextStack.length - 1].recordProvisionallyTypedSymbol(symbol);
            }
        };

        PullTypeResolutionContext.prototype.postDiagnostic = function (diagnostic) {
            if (diagnostic) {
                if (this.inProvisionalResolution()) {
                    (this.contextStack[this.contextStack.length - 1]).hasProvisionalErrors = true;
                } else if (this.inTypeCheck && this.resolver) {
                    this.resolver.semanticInfoChain.addDiagnostic(diagnostic);
                }
            }
        };

        PullTypeResolutionContext.prototype.typeCheck = function () {
            return this.inTypeCheck && !this.inProvisionalResolution();
        };

        PullTypeResolutionContext.prototype.setSymbolForAST = function (ast, symbol) {
            this.contextStack[this.contextStack.length - 1].setSymbolForAST(ast, symbol);
        };

        PullTypeResolutionContext.prototype.getSymbolForAST = function (ast) {
            for (var i = this.contextStack.length - 1; i >= 0; i--) {
                var typeContext = this.contextStack[i];
                if (!typeContext.provisional) {
                    break;
                }

                var symbol = typeContext.getSymbolForAST(ast);
                if (symbol) {
                    return symbol;
                }
            }

            return null;
        };

        PullTypeResolutionContext.prototype.startWalkingTypes = function (symbol1, symbol2) {
            if (!this.enclosingTypeWalker1) {
                this.enclosingTypeWalker1 = new TypeScript.PullTypeEnclosingTypeWalker();
            }
            var stateWhenStartedWalkingTypes1 = this.enclosingTypeWalker1.startWalkingType(symbol1);
            if (!this.enclosingTypeWalker2) {
                this.enclosingTypeWalker2 = new TypeScript.PullTypeEnclosingTypeWalker();
            }
            var stateWhenStartedWalkingTypes2 = this.enclosingTypeWalker2.startWalkingType(symbol2);
            return {
                stateWhenStartedWalkingTypes1: stateWhenStartedWalkingTypes1,
                stateWhenStartedWalkingTypes2: stateWhenStartedWalkingTypes2
            };
        };

        PullTypeResolutionContext.prototype.endWalkingTypes = function (statesWhenStartedWalkingTypes) {
            this.enclosingTypeWalker1.endWalkingType(statesWhenStartedWalkingTypes.stateWhenStartedWalkingTypes1);
            this.enclosingTypeWalker2.endWalkingType(statesWhenStartedWalkingTypes.stateWhenStartedWalkingTypes2);
        };

        PullTypeResolutionContext.prototype.setEnclosingTypeForSymbols = function (symbol1, symbol2) {
            if (!this.enclosingTypeWalker1) {
                this.enclosingTypeWalker1 = new TypeScript.PullTypeEnclosingTypeWalker();
            }
            var enclosingTypeWalkerState1 = this.enclosingTypeWalker1.setEnclosingTypeForSymbol(symbol1);
            if (!this.enclosingTypeWalker2) {
                this.enclosingTypeWalker2 = new TypeScript.PullTypeEnclosingTypeWalker();
            }
            var enclosingTypeWalkerState2 = this.enclosingTypeWalker2.setEnclosingTypeForSymbol(symbol2);
            return {
                enclosingTypeWalkerState1: enclosingTypeWalkerState1,
                enclosingTypeWalkerState2: enclosingTypeWalkerState2
            };
        };

        PullTypeResolutionContext.prototype.walkMemberTypes = function (memberName) {
            this.enclosingTypeWalker1.walkMemberType(memberName, this.resolver);
            this.enclosingTypeWalker2.walkMemberType(memberName, this.resolver);
        };

        PullTypeResolutionContext.prototype.postWalkMemberTypes = function () {
            this.enclosingTypeWalker1.postWalkMemberType();
            this.enclosingTypeWalker2.postWalkMemberType();
        };

        PullTypeResolutionContext.prototype.walkSignatures = function (kind, index, index2) {
            this.enclosingTypeWalker1.walkSignature(kind, index);
            this.enclosingTypeWalker2.walkSignature(kind, index2 == undefined ? index : index2);
        };

        PullTypeResolutionContext.prototype.postWalkSignatures = function () {
            this.enclosingTypeWalker1.postWalkSignature();
            this.enclosingTypeWalker2.postWalkSignature();
        };

        PullTypeResolutionContext.prototype.walkTypeParameterConstraints = function (index) {
            this.enclosingTypeWalker1.walkTypeParameterConstraint(index);
            this.enclosingTypeWalker2.walkTypeParameterConstraint(index);
        };

        PullTypeResolutionContext.prototype.postWalkTypeParameterConstraints = function () {
            this.enclosingTypeWalker1.postWalkTypeParameterConstraint();
            this.enclosingTypeWalker2.postWalkTypeParameterConstraint();
        };

        PullTypeResolutionContext.prototype.walkTypeArgument = function (index) {
            this.enclosingTypeWalker1.walkTypeArgument(index);
            this.enclosingTypeWalker2.walkTypeArgument(index);
        };

        PullTypeResolutionContext.prototype.postWalkTypeArgument = function () {
            this.enclosingTypeWalker1.postWalkTypeArgument();
            this.enclosingTypeWalker2.postWalkTypeArgument();
        };

        PullTypeResolutionContext.prototype.walkReturnTypes = function () {
            this.enclosingTypeWalker1.walkReturnType();
            this.enclosingTypeWalker2.walkReturnType();
        };

        PullTypeResolutionContext.prototype.postWalkReturnTypes = function () {
            this.enclosingTypeWalker1.postWalkReturnType();
            this.enclosingTypeWalker2.postWalkReturnType();
        };

        PullTypeResolutionContext.prototype.walkParameterTypes = function (iParam) {
            this.enclosingTypeWalker1.walkParameterType(iParam);
            this.enclosingTypeWalker2.walkParameterType(iParam);
        };

        PullTypeResolutionContext.prototype.postWalkParameterTypes = function () {
            this.enclosingTypeWalker1.postWalkParameterType();
            this.enclosingTypeWalker2.postWalkParameterType();
        };

        PullTypeResolutionContext.prototype.getBothKindOfIndexSignatures = function (includeAugmentedType1, includeAugmentedType2) {
            var indexSigs1 = this.enclosingTypeWalker1.getBothKindOfIndexSignatures(this.resolver, this, includeAugmentedType1);
            var indexSigs2 = this.enclosingTypeWalker2.getBothKindOfIndexSignatures(this.resolver, this, includeAugmentedType2);
            return { indexSigs1: indexSigs1, indexSigs2: indexSigs2 };
        };

        PullTypeResolutionContext.prototype.walkIndexSignatureReturnTypes = function (indexSigs, useStringIndexSignature1, useStringIndexSignature2, onlySignature) {
            this.enclosingTypeWalker1.walkIndexSignatureReturnType(indexSigs.indexSigs1, useStringIndexSignature1, onlySignature);
            this.enclosingTypeWalker2.walkIndexSignatureReturnType(indexSigs.indexSigs2, useStringIndexSignature2, onlySignature);
        };

        PullTypeResolutionContext.prototype.postWalkIndexSignatureReturnTypes = function (onlySignature) {
            this.enclosingTypeWalker1.postWalkIndexSignatureReturnType(onlySignature);
            this.enclosingTypeWalker2.postWalkIndexSignatureReturnType(onlySignature);
        };

        PullTypeResolutionContext.prototype.swapEnclosingTypeWalkers = function () {
            var tempEnclosingWalker1 = this.enclosingTypeWalker1;
            this.enclosingTypeWalker1 = this.enclosingTypeWalker2;
            this.enclosingTypeWalker2 = tempEnclosingWalker1;
        };

        PullTypeResolutionContext.prototype.oneOfClassificationsIsInfinitelyExpanding = function () {
            var generativeClassification1 = this.enclosingTypeWalker1.getGenerativeClassification();
            if (generativeClassification1 === 3 /* InfinitelyExpanding */) {
                return true;
            }
            var generativeClassification2 = this.enclosingTypeWalker2.getGenerativeClassification();
            if (generativeClassification2 === 3 /* InfinitelyExpanding */) {
                return true;
            }

            return false;
        };

        PullTypeResolutionContext.prototype.resetEnclosingTypeWalkerStates = function () {
            var enclosingTypeWalkerState1 = this.enclosingTypeWalker1 ? this.enclosingTypeWalker1.resetEnclosingTypeWalkerState() : null;
            var enclosingTypeWalkerState2 = this.enclosingTypeWalker2 ? this.enclosingTypeWalker2.resetEnclosingTypeWalkerState() : null;
            return {
                enclosingTypeWalkerState1: enclosingTypeWalkerState1,
                enclosingTypeWalkerState2: enclosingTypeWalkerState2
            };
        };

        PullTypeResolutionContext.prototype.setEnclosingTypeWalkerStates = function (enclosingTypeWalkerStates) {
            TypeScript.Debug.assert(this.enclosingTypeWalker1 || !enclosingTypeWalkerStates.enclosingTypeWalkerState1);
            if (this.enclosingTypeWalker1) {
                this.enclosingTypeWalker1.setEnclosingTypeWalkerState(enclosingTypeWalkerStates.enclosingTypeWalkerState1);
            }
            TypeScript.Debug.assert(this.enclosingTypeWalker2 || !enclosingTypeWalkerStates.enclosingTypeWalkerState2);
            if (this.enclosingTypeWalker2) {
                this.enclosingTypeWalker2.setEnclosingTypeWalkerState(enclosingTypeWalkerStates.enclosingTypeWalkerState2);
            }
        };
        return PullTypeResolutionContext;
    })();
    TypeScript.PullTypeResolutionContext = PullTypeResolutionContext;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var OverloadApplicabilityStatus;
    (function (OverloadApplicabilityStatus) {
        OverloadApplicabilityStatus[OverloadApplicabilityStatus["NotAssignable"] = 0] = "NotAssignable";
        OverloadApplicabilityStatus[OverloadApplicabilityStatus["AssignableButWithProvisionalErrors"] = 1] = "AssignableButWithProvisionalErrors";
        OverloadApplicabilityStatus[OverloadApplicabilityStatus["AssignableWithNoProvisionalErrors"] = 2] = "AssignableWithNoProvisionalErrors";
        OverloadApplicabilityStatus[OverloadApplicabilityStatus["Subtype"] = 3] = "Subtype";
    })(OverloadApplicabilityStatus || (OverloadApplicabilityStatus = {}));

    var PullAdditionalCallResolutionData = (function () {
        function PullAdditionalCallResolutionData() {
            this.targetSymbol = null;
            this.resolvedSignatures = null;
            this.candidateSignature = null;
            this.actualParametersContextTypeSymbols = null;
            this.diagnosticsFromOverloadResolution = [];
        }
        return PullAdditionalCallResolutionData;
    })();
    TypeScript.PullAdditionalCallResolutionData = PullAdditionalCallResolutionData;

    var PullAdditionalObjectLiteralResolutionData = (function () {
        function PullAdditionalObjectLiteralResolutionData() {
            this.membersContextTypeSymbols = null;
        }
        return PullAdditionalObjectLiteralResolutionData;
    })();
    TypeScript.PullAdditionalObjectLiteralResolutionData = PullAdditionalObjectLiteralResolutionData;

    var MemberWithBaseOrigin = (function () {
        function MemberWithBaseOrigin(memberSymbol, baseOrigin) {
            this.memberSymbol = memberSymbol;
            this.baseOrigin = baseOrigin;
        }
        return MemberWithBaseOrigin;
    })();

    var SignatureWithBaseOrigin = (function () {
        function SignatureWithBaseOrigin(signature, baseOrigin) {
            this.signature = signature;
            this.baseOrigin = baseOrigin;
        }
        return SignatureWithBaseOrigin;
    })();

    var InheritedIndexSignatureInfo = (function () {
        function InheritedIndexSignatureInfo() {
        }
        return InheritedIndexSignatureInfo;
    })();

    var CompilerReservedName;
    (function (CompilerReservedName) {
        CompilerReservedName[CompilerReservedName["_this"] = 1] = "_this";
        CompilerReservedName[CompilerReservedName["_super"] = 2] = "_super";
        CompilerReservedName[CompilerReservedName["arguments"] = 3] = "arguments";
        CompilerReservedName[CompilerReservedName["_i"] = 4] = "_i";
        CompilerReservedName[CompilerReservedName["require"] = 5] = "require";
        CompilerReservedName[CompilerReservedName["exports"] = 6] = "exports";
    })(CompilerReservedName || (CompilerReservedName = {}));

    function getCompilerReservedName(name) {
        var nameText = name.valueText();
        return CompilerReservedName[nameText];
    }

    var PullTypeResolver = (function () {
        function PullTypeResolver(compilationSettings, semanticInfoChain) {
            this.compilationSettings = compilationSettings;
            this.semanticInfoChain = semanticInfoChain;
            this._cachedArrayInterfaceType = null;
            this._cachedNumberInterfaceType = null;
            this._cachedStringInterfaceType = null;
            this._cachedBooleanInterfaceType = null;
            this._cachedObjectInterfaceType = null;
            this._cachedFunctionInterfaceType = null;
            this._cachedIArgumentsInterfaceType = null;
            this._cachedRegExpInterfaceType = null;
            this._cachedAnyTypeArgs = null;
            this.typeCheckCallBacks = [];
            this.postTypeCheckWorkitems = [];
            this._cachedFunctionArgumentsSymbol = null;
            this.assignableCache = TypeScript.BitMatrix.getBitMatrix(true);
            this.subtypeCache = TypeScript.BitMatrix.getBitMatrix(true);
            this.identicalCache = TypeScript.BitMatrix.getBitMatrix(true);
            this.inResolvingOtherDeclsWalker = new TypeScript.PullHelpers.OtherPullDeclsWalker();
        }
        PullTypeResolver.prototype.cachedArrayInterfaceType = function () {
            if (!this._cachedArrayInterfaceType) {
                this._cachedArrayInterfaceType = this.getSymbolFromDeclPath("Array", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (!this._cachedArrayInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedArrayInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedArrayInterfaceType;
        };

        PullTypeResolver.prototype.getArrayNamedType = function () {
            return this.cachedArrayInterfaceType();
        };

        PullTypeResolver.prototype.cachedNumberInterfaceType = function () {
            if (!this._cachedNumberInterfaceType) {
                this._cachedNumberInterfaceType = this.getSymbolFromDeclPath("Number", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (this._cachedNumberInterfaceType && !this._cachedNumberInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedNumberInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedNumberInterfaceType;
        };

        PullTypeResolver.prototype.cachedStringInterfaceType = function () {
            if (!this._cachedStringInterfaceType) {
                this._cachedStringInterfaceType = this.getSymbolFromDeclPath("String", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (this._cachedStringInterfaceType && !this._cachedStringInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedStringInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedStringInterfaceType;
        };

        PullTypeResolver.prototype.cachedBooleanInterfaceType = function () {
            if (!this._cachedBooleanInterfaceType) {
                this._cachedBooleanInterfaceType = this.getSymbolFromDeclPath("Boolean", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (this._cachedBooleanInterfaceType && !this._cachedBooleanInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedBooleanInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedBooleanInterfaceType;
        };

        PullTypeResolver.prototype.cachedObjectInterfaceType = function () {
            if (!this._cachedObjectInterfaceType) {
                this._cachedObjectInterfaceType = this.getSymbolFromDeclPath("Object", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (!this._cachedObjectInterfaceType) {
                this._cachedObjectInterfaceType = this.semanticInfoChain.anyTypeSymbol;
            }

            if (!this._cachedObjectInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedObjectInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedObjectInterfaceType;
        };

        PullTypeResolver.prototype.cachedFunctionInterfaceType = function () {
            if (!this._cachedFunctionInterfaceType) {
                this._cachedFunctionInterfaceType = this.getSymbolFromDeclPath("Function", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (this._cachedFunctionInterfaceType && !this._cachedFunctionInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedFunctionInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedFunctionInterfaceType;
        };

        PullTypeResolver.prototype.cachedIArgumentsInterfaceType = function () {
            if (!this._cachedIArgumentsInterfaceType) {
                this._cachedIArgumentsInterfaceType = this.getSymbolFromDeclPath("IArguments", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (this._cachedIArgumentsInterfaceType && !this._cachedIArgumentsInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedIArgumentsInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedIArgumentsInterfaceType;
        };

        PullTypeResolver.prototype.cachedRegExpInterfaceType = function () {
            if (!this._cachedRegExpInterfaceType) {
                this._cachedRegExpInterfaceType = this.getSymbolFromDeclPath("RegExp", [], 16 /* Interface */) || this.semanticInfoChain.emptyTypeSymbol;
            }

            if (this._cachedRegExpInterfaceType && !this._cachedRegExpInterfaceType.isResolved) {
                this.resolveDeclaredSymbol(this._cachedRegExpInterfaceType, new TypeScript.PullTypeResolutionContext(this));
            }

            return this._cachedRegExpInterfaceType;
        };

        PullTypeResolver.prototype.cachedFunctionArgumentsSymbol = function () {
            if (!this._cachedFunctionArgumentsSymbol) {
                this._cachedFunctionArgumentsSymbol = new TypeScript.PullSymbol("arguments", 512 /* Variable */);
                this._cachedFunctionArgumentsSymbol.type = this.cachedIArgumentsInterfaceType() || this.semanticInfoChain.anyTypeSymbol;
                this._cachedFunctionArgumentsSymbol.setResolved();

                var functionArgumentsDecl = new TypeScript.PullSynthesizedDecl("arguments", "arguments", 2048 /* Parameter */, 0 /* None */, null, this.semanticInfoChain);
                functionArgumentsDecl.setSymbol(this._cachedFunctionArgumentsSymbol);
                this._cachedFunctionArgumentsSymbol.addDeclaration(functionArgumentsDecl);
            }

            return this._cachedFunctionArgumentsSymbol;
        };

        PullTypeResolver.prototype.getApparentType = function (type) {
            if (type.isTypeParameter()) {
                var baseConstraint = type.getBaseConstraint(this.semanticInfoChain);
                if (baseConstraint === this.semanticInfoChain.anyTypeSymbol) {
                    return this.semanticInfoChain.emptyTypeSymbol;
                } else {
                    type = baseConstraint;
                }
            }
            if (type.isPrimitive()) {
                if (type === this.semanticInfoChain.numberTypeSymbol) {
                    return this.cachedNumberInterfaceType();
                }
                if (type === this.semanticInfoChain.booleanTypeSymbol) {
                    return this.cachedBooleanInterfaceType();
                }
                if (type === this.semanticInfoChain.stringTypeSymbol) {
                    return this.cachedStringInterfaceType();
                }
                return type;
            }
            if (type.isEnum()) {
                return this.cachedNumberInterfaceType();
            }
            return type;
        };

        PullTypeResolver.prototype.setTypeChecked = function (ast, context) {
            context.setTypeChecked(ast);
        };

        PullTypeResolver.prototype.canTypeCheckAST = function (ast, context) {
            return context.canTypeCheckAST(ast);
        };

        PullTypeResolver.prototype.setSymbolForAST = function (ast, symbol, context) {
            if (context && context.inProvisionalResolution()) {
                context.setSymbolForAST(ast, symbol);
            } else {
                this.semanticInfoChain.setSymbolForAST(ast, symbol);
            }
        };

        PullTypeResolver.prototype.getSymbolForAST = function (ast, context) {
            var symbol = this.semanticInfoChain.getSymbolForAST(ast);

            if (!symbol) {
                if (context && context.inProvisionalResolution()) {
                    symbol = context.getSymbolForAST(ast);
                }
            }

            return symbol;
        };

        PullTypeResolver.prototype.getASTForDecl = function (decl) {
            return this.semanticInfoChain.getASTForDecl(decl);
        };

        PullTypeResolver.prototype.getNewErrorTypeSymbol = function (name) {
            if (typeof name === "undefined") { name = null; }
            return new TypeScript.PullErrorTypeSymbol(this.semanticInfoChain.anyTypeSymbol, name);
        };

        PullTypeResolver.prototype.getEnclosingDecl = function (decl) {
            var declPath = decl.getParentPath();

            if (declPath.length > 1 && declPath[declPath.length - 1] === decl) {
                return declPath[declPath.length - 2];
            } else {
                return declPath[declPath.length - 1];
            }
        };

        PullTypeResolver.prototype.getExportedMemberSymbol = function (symbol, parent) {
            if (!(symbol.kind & (65536 /* Method */ | 4096 /* Property */))) {
                var isContainer = (parent.kind & (4 /* Container */ | 32 /* DynamicModule */)) !== 0;
                var containerType = !isContainer ? parent.getAssociatedContainerType() : parent;

                if (isContainer && containerType) {
                    if (symbol.anyDeclHasFlag(1 /* Exported */)) {
                        return symbol;
                    }

                    return null;
                }
            }

            return symbol;
        };

        PullTypeResolver.prototype._getNamedPropertySymbolOfAugmentedType = function (symbolName, parent) {
            var memberSymbol = this.getNamedPropertySymbol(symbolName, 68147712 /* SomeValue */, parent);
            if (memberSymbol) {
                return memberSymbol;
            }

            if (this.cachedFunctionInterfaceType() && parent.isFunctionType()) {
                memberSymbol = this.cachedFunctionInterfaceType().findMember(symbolName, true);
                if (memberSymbol) {
                    return memberSymbol;
                }
            }

            if (this.cachedObjectInterfaceType()) {
                return this.cachedObjectInterfaceType().findMember(symbolName, true);
            }

            return null;
        };

        PullTypeResolver.prototype.getNamedPropertySymbol = function (symbolName, declSearchKind, parent) {
            var member = null;

            if (declSearchKind & 68147712 /* SomeValue */) {
                member = parent.findMember(symbolName, true);
            } else if (declSearchKind & 58728795 /* SomeType */) {
                member = parent.findNestedType(symbolName);
            } else if (declSearchKind & 164 /* SomeContainer */) {
                member = parent.findNestedContainer(symbolName);
            }

            if (member) {
                return this.getExportedMemberSymbol(member, parent);
            }

            var containerType = parent.getAssociatedContainerType();

            if (containerType) {
                if (containerType.isClass()) {
                    return null;
                }

                parent = containerType;

                if (declSearchKind & 68147712 /* SomeValue */) {
                    member = parent.findMember(symbolName, true);
                } else if (declSearchKind & 58728795 /* SomeType */) {
                    member = parent.findNestedType(symbolName);
                } else if (declSearchKind & 164 /* SomeContainer */) {
                    member = parent.findNestedContainer(symbolName);
                }

                if (member) {
                    return this.getExportedMemberSymbol(member, parent);
                }
            }

            if (parent.kind & 164 /* SomeContainer */) {
                var typeDeclarations = parent.getDeclarations();
                var childDecls = null;

                for (var j = 0; j < typeDeclarations.length; j++) {
                    childDecls = typeDeclarations[j].searchChildDecls(symbolName, declSearchKind);

                    if (childDecls.length) {
                        member = childDecls[0].getSymbol();

                        if (!member) {
                            member = childDecls[0].getSignatureSymbol();
                        }
                        return this.getExportedMemberSymbol(member, parent);
                    }

                    if ((declSearchKind & 58728795 /* SomeType */) !== 0 || (declSearchKind & 68147712 /* SomeValue */) !== 0) {
                        childDecls = typeDeclarations[j].searchChildDecls(symbolName, 128 /* TypeAlias */);
                        if (childDecls.length && childDecls[0].kind === 128 /* TypeAlias */) {
                            var aliasSymbol = this.getExportedMemberSymbol(childDecls[0].getSymbol(), parent);
                            if (aliasSymbol) {
                                if ((declSearchKind & 58728795 /* SomeType */) !== 0) {
                                    var typeSymbol = aliasSymbol.getExportAssignedTypeSymbol();
                                    if (typeSymbol) {
                                        return typeSymbol;
                                    }
                                } else {
                                    var valueSymbol = aliasSymbol.getExportAssignedValueSymbol();
                                    if (valueSymbol) {
                                        aliasSymbol.setIsUsedAsValue();
                                        return valueSymbol;
                                    }
                                }

                                return aliasSymbol;
                            }
                        }
                    }
                }
            }
        };

        PullTypeResolver.prototype.getSymbolFromDeclPath = function (symbolName, declPath, declSearchKind) {
            var _this = this;
            var symbol = null;

            var decl = null;
            var childDecls;
            var declSymbol = null;
            var declMembers;
            var pathDeclKind;
            var valDecl = null;
            var kind;
            var instanceSymbol = null;
            var instanceType = null;
            var childSymbol = null;

            var allowedContainerDeclKind = 4 /* Container */ | 32 /* DynamicModule */;
            if (TypeScript.hasFlag(declSearchKind, 67108864 /* EnumMember */)) {
                allowedContainerDeclKind |= 64 /* Enum */;
            }

            var isAcceptableAlias = function (symbol) {
                if (symbol.isAlias()) {
                    _this.resolveDeclaredSymbol(symbol);
                    if (TypeScript.hasFlag(declSearchKind, 164 /* SomeContainer */)) {
                        if (symbol.assignedContainer() || symbol.getExportAssignedContainerSymbol()) {
                            return true;
                        }
                    } else if (TypeScript.hasFlag(declSearchKind, 58728795 /* SomeType */)) {
                        var type = symbol.getExportAssignedTypeSymbol();
                        if (type && type.kind !== 32 /* DynamicModule */) {
                            return true;
                        }

                        var type = symbol.assignedType();
                        if (type && type.kind !== 32 /* DynamicModule */) {
                            return true;
                        }
                    } else if (TypeScript.hasFlag(declSearchKind, 68147712 /* SomeValue */ & ~67108864 /* EnumMember */)) {
                        if (symbol.assignedType() && symbol.assignedType().isError()) {
                            return true;
                        } else if (symbol.assignedValue() || symbol.getExportAssignedValueSymbol()) {
                            return true;
                        } else {
                            var assignedType = symbol.assignedType();
                            if (assignedType && assignedType.isContainer() && assignedType.getInstanceType()) {
                                return true;
                            }

                            var decls = symbol.getDeclarations();
                            var ast = decls[0].ast();
                            return ast.moduleReference.kind() === 245 /* ExternalModuleReference */;
                        }
                    }
                }

                return false;
            };

            var tryFindAlias = function (decl) {
                var childDecls = decl.searchChildDecls(symbolName, 128 /* TypeAlias */);

                if (childDecls.length) {
                    var sym = childDecls[0].getSymbol();
                    if (isAcceptableAlias(sym)) {
                        return sym;
                    }
                }
                return null;
            };

            for (var i = declPath.length - 1; i >= 0; i--) {
                decl = declPath[i];
                pathDeclKind = decl.kind;

                if (decl.flags & 2097152 /* DeclaredInAWithBlock */) {
                    return this.semanticInfoChain.anyTypeSymbol;
                }

                if (pathDeclKind & allowedContainerDeclKind) {
                    childDecls = decl.searchChildDecls(symbolName, declSearchKind);

                    if (childDecls.length) {
                        return childDecls[0].getSymbol();
                    }

                    var alias = tryFindAlias(decl);
                    if (alias) {
                        return alias;
                    }

                    if (declSearchKind & 68147712 /* SomeValue */) {
                        instanceSymbol = decl.getSymbol().getInstanceSymbol();

                        if (instanceSymbol) {
                            instanceType = instanceSymbol.type;

                            childSymbol = this.getNamedPropertySymbol(symbolName, declSearchKind, instanceType);

                            if (childSymbol && (childSymbol.kind & declSearchKind) && !childSymbol.anyDeclHasFlag(16 /* Static */)) {
                                return childSymbol;
                            }
                        }

                        valDecl = decl.getValueDecl();

                        if (valDecl) {
                            decl = valDecl;
                        }
                    }

                    declSymbol = decl.getSymbol().type;

                    var childSymbol = this.getNamedPropertySymbol(symbolName, declSearchKind, declSymbol);

                    if (childSymbol && (childSymbol.kind & declSearchKind) && !childSymbol.anyDeclHasFlag(16 /* Static */)) {
                        return childSymbol;
                    }
                } else if ((declSearchKind & (58728795 /* SomeType */ | 164 /* SomeContainer */)) || !(pathDeclKind & 8 /* Class */)) {
                    var candidateSymbol = null;

                    if (pathDeclKind === 131072 /* FunctionExpression */ && symbolName === decl.getFunctionExpressionName()) {
                        candidateSymbol = decl.getSymbol();
                    }

                    childDecls = decl.searchChildDecls(symbolName, declSearchKind);

                    if (childDecls.length) {
                        if (decl.kind & 1032192 /* SomeFunction */) {
                            decl.ensureSymbolIsBound();
                        }
                        return childDecls[0].getSymbol();
                    }

                    if (candidateSymbol) {
                        return candidateSymbol;
                    }

                    var alias = tryFindAlias(decl);
                    if (alias) {
                        return alias;
                    }
                }
            }

            symbol = this.semanticInfoChain.findSymbol([symbolName], declSearchKind);
            if (symbol) {
                return symbol;
            }

            if (!TypeScript.hasFlag(declSearchKind, 128 /* TypeAlias */)) {
                symbol = this.semanticInfoChain.findSymbol([symbolName], 128 /* TypeAlias */);
                if (symbol && isAcceptableAlias(symbol)) {
                    return symbol;
                }
            }

            return null;
        };

        PullTypeResolver.prototype.getVisibleDeclsFromDeclPath = function (declPath, declSearchKind) {
            var result = [];
            var decl = null;
            var childDecls;
            var pathDeclKind;

            for (var i = declPath.length - 1; i >= 0; i--) {
                decl = declPath[i];
                pathDeclKind = decl.kind;

                var declKind = decl.kind;

                if (declKind !== 8 /* Class */ && declKind !== 16 /* Interface */) {
                    this.addFilteredDecls(decl.getChildDecls(), declSearchKind, result);
                }

                switch (declKind) {
                    case 4 /* Container */:
                    case 32 /* DynamicModule */:
                        var otherDecls = this.semanticInfoChain.findDeclsFromPath(declPath.slice(0, i + 1), 164 /* SomeContainer */);
                        for (var j = 0, m = otherDecls.length; j < m; j++) {
                            var otherDecl = otherDecls[j];
                            if (otherDecl === decl) {
                                continue;
                            }

                            var otherDeclChildren = otherDecl.getChildDecls();
                            for (var k = 0, s = otherDeclChildren.length; k < s; k++) {
                                var otherDeclChild = otherDeclChildren[k];
                                if ((otherDeclChild.flags & 1 /* Exported */) && (otherDeclChild.kind & declSearchKind)) {
                                    result.push(otherDeclChild);
                                }
                            }
                        }

                        break;

                    case 8 /* Class */:
                    case 16 /* Interface */:
                        var parameters = decl.getTypeParameters();
                        if (parameters && parameters.length) {
                            this.addFilteredDecls(parameters, declSearchKind, result);
                        }

                        break;

                    case 131072 /* FunctionExpression */:
                        var functionExpressionName = decl.getFunctionExpressionName();
                        if (functionExpressionName) {
                            result.push(decl);
                        }

                    case 16384 /* Function */:
                    case 32768 /* ConstructorMethod */:
                    case 65536 /* Method */:
                        var parameters = decl.getTypeParameters();
                        if (parameters && parameters.length) {
                            this.addFilteredDecls(parameters, declSearchKind, result);
                        }

                        break;
                }
            }

            var topLevelDecls = this.semanticInfoChain.topLevelDecls();
            for (var i = 0, n = topLevelDecls.length; i < n; i++) {
                var topLevelDecl = topLevelDecls[i];
                if (declPath.length > 0 && topLevelDecl.fileName() === declPath[0].fileName()) {
                    continue;
                }

                if (!topLevelDecl.isExternalModule()) {
                    this.addFilteredDecls(topLevelDecl.getChildDecls(), declSearchKind, result);
                }
            }

            return result;
        };

        PullTypeResolver.prototype.addFilteredDecls = function (decls, declSearchKind, result) {
            if (decls.length) {
                for (var i = 0, n = decls.length; i < n; i++) {
                    var decl = decls[i];
                    if (decl.kind & declSearchKind) {
                        result.push(decl);
                    }
                }
            }
        };

        PullTypeResolver.prototype.getVisibleDecls = function (enclosingDecl) {
            var declPath = enclosingDecl.getParentPath();

            var declSearchKind = 58728795 /* SomeType */ | 164 /* SomeContainer */ | 68147712 /* SomeValue */;

            return this.getVisibleDeclsFromDeclPath(declPath, declSearchKind);
        };

        PullTypeResolver.prototype.getVisibleContextSymbols = function (enclosingDecl, context) {
            var contextualTypeSymbol = context.getContextualType();
            if (!contextualTypeSymbol || this.isAnyOrEquivalent(contextualTypeSymbol)) {
                return null;
            }

            var declSearchKind = 58728795 /* SomeType */ | 164 /* SomeContainer */ | 68147712 /* SomeValue */;
            var members = contextualTypeSymbol.getAllMembers(declSearchKind, 2 /* externallyVisible */);

            for (var i = 0; i < members.length; i++) {
                members[i].setUnresolved();
            }

            return members;
        };

        PullTypeResolver.prototype.getVisibleMembersFromExpression = function (expression, enclosingDecl, context) {
            var lhs = this.resolveAST(expression, false, context);

            if (isTypesOnlyLocation(expression) && (lhs.kind === 8 /* Class */ || lhs.kind === 16 /* Interface */ || lhs.kind === 64 /* Enum */)) {
                return null;
            }

            var lhsType = lhs.type;
            if (!lhsType) {
                return null;
            }

            this.resolveDeclaredSymbol(lhsType, context);

            if (lhsType.isContainer() && lhsType.isAlias()) {
                lhsType = lhsType.getExportAssignedTypeSymbol();
            }

            if (this.isAnyOrEquivalent(lhsType)) {
                return null;
            }

            var memberVisibilty = 2 /* externallyVisible */;
            var containerSymbol = lhsType;
            if (containerSymbol.kind === 33554432 /* ConstructorType */) {
                containerSymbol = containerSymbol.getConstructSignatures()[0].returnType;
            }

            if (containerSymbol && containerSymbol.isClass()) {
                var declPath = enclosingDecl.getParentPath();
                if (declPath && declPath.length) {
                    var declarations = containerSymbol.getDeclarations();
                    for (var i = 0, n = declarations.length; i < n; i++) {
                        var declaration = declarations[i];
                        if (TypeScript.ArrayUtilities.contains(declPath, declaration)) {
                            memberVisibilty = 1 /* internallyVisible */;
                            break;
                        }
                    }
                }
            }

            var declSearchKind = 58728795 /* SomeType */ | 164 /* SomeContainer */ | 68147712 /* SomeValue */;

            var members = [];

            if (lhsType.isContainer()) {
                var exportedAssignedContainerSymbol = lhsType.getExportAssignedContainerSymbol();
                if (exportedAssignedContainerSymbol) {
                    lhsType = exportedAssignedContainerSymbol;
                }
            }

            lhsType = this.getApparentType(lhsType);

            if (!lhsType.isResolved) {
                var potentiallySpecializedType = this.resolveDeclaredSymbol(lhsType, context);

                if (potentiallySpecializedType !== lhsType) {
                    if (!lhs.isType()) {
                        context.setTypeInContext(lhs, potentiallySpecializedType);
                    }

                    lhsType = potentiallySpecializedType;
                }
            }

            members = lhsType.getAllMembers(declSearchKind, memberVisibilty);

            if (lhsType.isContainer()) {
                var associatedInstance = lhsType.getInstanceSymbol();
                if (associatedInstance) {
                    var instanceType = associatedInstance.type;
                    this.resolveDeclaredSymbol(instanceType, context);
                    var instanceMembers = instanceType.getAllMembers(declSearchKind, memberVisibilty);
                    members = members.concat(instanceMembers);
                }

                var exportedContainer = lhsType.getExportAssignedContainerSymbol();
                if (exportedContainer) {
                    var exportedContainerMembers = exportedContainer.getAllMembers(declSearchKind, memberVisibilty);
                    members = members.concat(exportedContainerMembers);
                }
            } else if (!lhsType.isConstructor() && !lhsType.isEnum()) {
                var associatedContainerSymbol = lhsType.getAssociatedContainerType();
                if (associatedContainerSymbol) {
                    var containerType = associatedContainerSymbol.type;
                    this.resolveDeclaredSymbol(containerType, context);
                    var containerMembers = containerType.getAllMembers(declSearchKind, memberVisibilty);
                    members = members.concat(containerMembers);
                }
            }

            if (lhsType.isFunctionType() && this.cachedFunctionInterfaceType()) {
                members = members.concat(this.cachedFunctionInterfaceType().getAllMembers(declSearchKind, 2 /* externallyVisible */));
            }

            return members;
        };

        PullTypeResolver.prototype.isAnyOrEquivalent = function (type) {
            return (type === this.semanticInfoChain.anyTypeSymbol) || type.isError();
        };

        PullTypeResolver.prototype.resolveExternalModuleReference = function (idText, currentFileName) {
            var originalIdText = idText;
            var symbol = null;

            if (TypeScript.isRelative(originalIdText)) {
                var path = TypeScript.getRootFilePath(TypeScript.switchToForwardSlashes(currentFileName));
                symbol = this.semanticInfoChain.findExternalModule(path + idText);
            } else {
                idText = originalIdText;

                symbol = this.semanticInfoChain.findAmbientExternalModuleInGlobalContext(TypeScript.quoteStr(originalIdText));

                if (!symbol) {
                    var path = TypeScript.getRootFilePath(TypeScript.switchToForwardSlashes(currentFileName));

                    while (symbol === null && path != "") {
                        symbol = this.semanticInfoChain.findExternalModule(path + idText);
                        if (symbol === null) {
                            if (path === '/') {
                                path = '';
                            } else {
                                path = TypeScript.normalizePath(path + "..");
                                path = path && path != '/' ? path + '/' : path;
                            }
                        }
                    }
                }
            }

            return symbol;
        };

        PullTypeResolver.prototype.resolveDeclaredSymbol = function (symbol, context) {
            if (!symbol || symbol.isResolved || symbol.isTypeReference()) {
                return symbol;
            }

            if (!context) {
                context = new TypeScript.PullTypeResolutionContext(this);
            }

            return this.resolveDeclaredSymbolWorker(symbol, context);
        };

        PullTypeResolver.prototype.resolveDeclaredSymbolWorker = function (symbol, context) {
            if (!symbol || symbol.isResolved) {
                return symbol;
            }

            if (symbol.inResolution) {
                if (!symbol.type && !symbol.isType()) {
                    symbol.type = this.semanticInfoChain.anyTypeSymbol;
                }

                return symbol;
            }

            var decls = symbol.getDeclarations();

            for (var i = 0; i < decls.length; i++) {
                var decl = decls[i];

                var ast = this.semanticInfoChain.getASTForDecl(decl);

                if (!ast || (ast.kind() === 139 /* GetAccessor */ && ast.parent.parent.kind() === 215 /* ObjectLiteralExpression */) || (ast.kind() === 140 /* SetAccessor */ && ast.parent.parent.kind() === 215 /* ObjectLiteralExpression */)) {
                    return symbol;
                }

                if (ast.parent && ast.parent.kind() === 236 /* CatchClause */ && ast.parent.identifier === ast) {
                    return symbol;
                }

                if (ast.parent && ast.parent.kind() === 219 /* SimpleArrowFunctionExpression */ && ast.parent.identifier === ast) {
                    return symbol;
                }

                var enclosingModule = TypeScript.ASTHelpers.getModuleDeclarationFromNameAST(ast);
                var resolvedSymbol;
                if (enclosingModule) {
                    resolvedSymbol = this.resolveSingleModuleDeclaration(enclosingModule, ast, context);
                } else if (ast.kind() === 120 /* SourceUnit */ && decl.kind === 32 /* DynamicModule */) {
                    resolvedSymbol = this.resolveModuleSymbol(decl.getSymbol(), context, null, null, ast);
                } else {
                    TypeScript.Debug.assert(ast.kind() !== 11 /* IdentifierName */ && ast.kind() !== 212 /* MemberAccessExpression */);
                    resolvedSymbol = this.resolveAST(ast, false, context);
                }

                if (decl.kind === 2048 /* Parameter */ && !symbol.isResolved && !symbol.type && resolvedSymbol && symbol.anyDeclHasFlag(8388608 /* PropertyParameter */ | 67108864 /* ConstructorParameter */)) {
                    symbol.type = resolvedSymbol.type;
                    symbol.setResolved();
                }
            }

            if (!symbol.isResolved) {
                TypeScript.Debug.assert(!symbol.inResolution);

                symbol.setResolved();
            }

            return symbol;
        };

        PullTypeResolver.prototype.resolveOtherDecl = function (otherDecl, context) {
            var astForOtherDecl = this.getASTForDecl(otherDecl);
            var moduleDecl = TypeScript.ASTHelpers.getModuleDeclarationFromNameAST(astForOtherDecl);
            if (moduleDecl) {
                this.resolveSingleModuleDeclaration(moduleDecl, astForOtherDecl, context);
            } else {
                this.resolveAST(astForOtherDecl, false, context);
            }
        };

        PullTypeResolver.prototype.resolveOtherDeclarations = function (astName, context) {
            var _this = this;
            var resolvedDecl = this.semanticInfoChain.getDeclForAST(astName);
            var symbol = resolvedDecl.getSymbol();

            var allDecls = symbol.getDeclarations();
            this.inResolvingOtherDeclsWalker.walkOtherPullDecls(resolvedDecl, symbol.getDeclarations(), function (otherDecl) {
                return _this.resolveOtherDecl(otherDecl, context);
            });
        };

        PullTypeResolver.prototype.resolveSourceUnit = function (sourceUnit, context) {
            var enclosingDecl = this.getEnclosingDeclForAST(sourceUnit);
            var moduleSymbol = enclosingDecl.getSymbol();
            this.ensureAllSymbolsAreBound(moduleSymbol);

            this.resolveFirstExportAssignmentStatement(sourceUnit.moduleElements, context);
            this.resolveAST(sourceUnit.moduleElements, false, context);

            if (this.canTypeCheckAST(sourceUnit, context)) {
                this.typeCheckSourceUnit(sourceUnit, context);
            }

            return moduleSymbol;
        };

        PullTypeResolver.prototype.typeCheckSourceUnit = function (sourceUnit, context) {
            var _this = this;
            this.setTypeChecked(sourceUnit, context);

            this.resolveAST(sourceUnit.moduleElements, false, context);

            this.typeCheckCallBacks.push(function (context) {
                return _this.verifyUniquenessOfImportNamesInSourceUnit(sourceUnit);
            });
        };

        PullTypeResolver.prototype.verifyUniquenessOfImportNamesInSourceUnit = function (sourceUnit) {
            var _this = this;
            var enclosingDecl = this.semanticInfoChain.getDeclForAST(sourceUnit);

            var doesImportNameExistInOtherFiles = function (name) {
                var importSymbol = _this.semanticInfoChain.findTopLevelSymbol(name, 128 /* TypeAlias */, null);
                return importSymbol && importSymbol.isAlias();
            };

            this.checkUniquenessOfImportNames([enclosingDecl], doesImportNameExistInOtherFiles);
        };

        PullTypeResolver.prototype.resolveEnumDeclaration = function (ast, context) {
            var containerDecl = this.semanticInfoChain.getDeclForAST(ast);
            var containerSymbol = containerDecl.getSymbol();

            if (containerSymbol.isResolved || containerSymbol.inResolution) {
                return containerSymbol;
            }

            containerSymbol.inResolution = true;

            var containerDecls = containerSymbol.getDeclarations();

            for (var i = 0; i < containerDecls.length; i++) {
                var childDecls = containerDecls[i].getChildDecls();

                for (var j = 0; j < childDecls.length; j++) {
                    childDecls[j].ensureSymbolIsBound();
                }
            }

            containerSymbol.setResolved();

            this.resolveOtherDeclarations(ast, context);

            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckEnumDeclaration(ast, context);
            }

            return containerSymbol;
        };

        PullTypeResolver.prototype.typeCheckEnumDeclaration = function (ast, context) {
            var _this = this;
            this.setTypeChecked(ast, context);

            this.resolveAST(ast.enumElements, false, context);
            var containerDecl = this.semanticInfoChain.getDeclForAST(ast);
            this.validateVariableDeclarationGroups(containerDecl, context);

            this.typeCheckCallBacks.push(function (context) {
                return _this.checkInitializersInEnumDeclarations(containerDecl, context);
            });

            if (!TypeScript.ASTHelpers.enumIsElided(ast)) {
                this.checkNameForCompilerGeneratedDeclarationCollision(ast, true, ast.identifier, context);
            }
        };

        PullTypeResolver.prototype.postTypeCheckEnumDeclaration = function (ast, context) {
            this.checkThisCaptureVariableCollides(ast, true, context);
        };

        PullTypeResolver.prototype.checkInitializersInEnumDeclarations = function (decl, context) {
            var symbol = decl.getSymbol();

            var declarations = symbol.getDeclarations();
            if (decl !== declarations[0]) {
                return;
            }

            var seenEnumDeclWithNoFirstMember = false;
            for (var i = 0; i < declarations.length; ++i) {
                var currentDecl = declarations[i];

                var ast = currentDecl.ast();
                if (ast.enumElements.nonSeparatorCount() === 0) {
                    continue;
                }

                var firstVariable = ast.enumElements.nonSeparatorAt(0);
                if (!firstVariable.equalsValueClause) {
                    if (!seenEnumDeclWithNoFirstMember) {
                        seenEnumDeclWithNoFirstMember = true;
                    } else {
                        this.semanticInfoChain.addDiagnosticFromAST(firstVariable, TypeScript.DiagnosticCode.In_enums_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_the_first_enum_element);
                    }
                }
            }
        };

        PullTypeResolver.prototype.resolveModuleDeclaration = function (ast, context) {
            var result;

            if (ast.stringLiteral) {
                result = this.resolveSingleModuleDeclaration(ast, ast.stringLiteral, context);
            } else {
                var moduleNames = TypeScript.ASTHelpers.getModuleNames(ast.name);
                for (var i = 0, n = moduleNames.length; i < n; i++) {
                    result = this.resolveSingleModuleDeclaration(ast, moduleNames[i], context);
                }
            }

            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckModuleDeclaration(ast, context);
            }

            return result;
        };

        PullTypeResolver.prototype.ensureAllSymbolsAreBound = function (containerSymbol) {
            if (containerSymbol) {
                var containerDecls = containerSymbol.getDeclarations();

                for (var i = 0; i < containerDecls.length; i++) {
                    var childDecls = containerDecls[i].getChildDecls();

                    for (var j = 0; j < childDecls.length; j++) {
                        childDecls[j].ensureSymbolIsBound();
                    }
                }
            }
        };

        PullTypeResolver.prototype.resolveModuleSymbol = function (containerSymbol, context, moduleDeclAST, moduleDeclNameAST, sourceUnitAST) {
            if (containerSymbol.isResolved || containerSymbol.inResolution) {
                return containerSymbol;
            }

            containerSymbol.inResolution = true;
            this.ensureAllSymbolsAreBound(containerSymbol);

            var instanceSymbol = containerSymbol.getInstanceSymbol();

            if (instanceSymbol) {
                this.resolveDeclaredSymbol(instanceSymbol, context);
            }

            var isLastName = TypeScript.ASTHelpers.isLastNameOfModule(moduleDeclAST, moduleDeclNameAST);
            if (isLastName) {
                this.resolveFirstExportAssignmentStatement(moduleDeclAST.moduleElements, context);
            } else if (sourceUnitAST) {
                this.resolveFirstExportAssignmentStatement(sourceUnitAST.moduleElements, context);
            }

            containerSymbol.setResolved();

            if (moduleDeclNameAST) {
                this.resolveOtherDeclarations(moduleDeclNameAST, context);
            }

            return containerSymbol;
        };

        PullTypeResolver.prototype.resolveFirstExportAssignmentStatement = function (moduleElements, context) {
            for (var i = 0, n = moduleElements.childCount(); i < n; i++) {
                var moduleElement = moduleElements.childAt(i);
                if (moduleElement.kind() === 134 /* ExportAssignment */) {
                    this.resolveExportAssignmentStatement(moduleElement, context);
                    return;
                }
            }
        };

        PullTypeResolver.prototype.resolveSingleModuleDeclaration = function (ast, astName, context) {
            var containerDecl = this.semanticInfoChain.getDeclForAST(astName);
            var containerSymbol = containerDecl.getSymbol();

            return this.resolveModuleSymbol(containerSymbol, context, ast, astName, null);
        };

        PullTypeResolver.prototype.typeCheckModuleDeclaration = function (ast, context) {
            if (ast.stringLiteral) {
                this.typeCheckSingleModuleDeclaration(ast, ast.stringLiteral, context);
            } else {
                var moduleNames = TypeScript.ASTHelpers.getModuleNames(ast.name);
                for (var i = 0, n = moduleNames.length; i < n; i++) {
                    this.typeCheckSingleModuleDeclaration(ast, moduleNames[i], context);
                }
            }
        };

        PullTypeResolver.prototype.typeCheckSingleModuleDeclaration = function (ast, astName, context) {
            var _this = this;
            this.setTypeChecked(ast, context);

            if (TypeScript.ASTHelpers.isLastNameOfModule(ast, astName)) {
                this.resolveAST(ast.moduleElements, false, context);
            }

            var containerDecl = this.semanticInfoChain.getDeclForAST(astName);
            this.validateVariableDeclarationGroups(containerDecl, context);

            if (ast.stringLiteral) {
                if (TypeScript.isRelative(ast.stringLiteral.valueText())) {
                    this.semanticInfoChain.addDiagnosticFromAST(ast.stringLiteral, TypeScript.DiagnosticCode.Ambient_external_module_declaration_cannot_specify_relative_module_name);
                }
            }

            if (!TypeScript.ASTHelpers.moduleIsElided(ast) && !ast.stringLiteral) {
                this.checkNameForCompilerGeneratedDeclarationCollision(astName, true, astName, context);
            }

            this.typeCheckCallBacks.push(function (context) {
                return _this.verifyUniquenessOfImportNamesInModule(containerDecl);
            });
        };

        PullTypeResolver.prototype.verifyUniquenessOfImportNamesInModule = function (decl) {
            var symbol = decl.getSymbol();
            if (!symbol) {
                return;
            }

            var decls = symbol.getDeclarations();

            if (decls[0] !== decl) {
                return;
            }

            this.checkUniquenessOfImportNames(decls);
        };

        PullTypeResolver.prototype.checkUniquenessOfImportNames = function (decls, doesNameExistOutside) {
            var _this = this;
            var importDeclarationNames;

            for (var i = 0; i < decls.length; ++i) {
                var childDecls = decls[i].getChildDecls();
                for (var j = 0; j < childDecls.length; ++j) {
                    var childDecl = childDecls[j];
                    if (childDecl.kind === 128 /* TypeAlias */) {
                        importDeclarationNames = importDeclarationNames || TypeScript.createIntrinsicsObject();
                        importDeclarationNames[childDecl.name] = true;
                    }
                }
            }

            if (!importDeclarationNames && !doesNameExistOutside) {
                return;
            }

            for (var i = 0; i < decls.length; ++i) {
                this.scanVariableDeclarationGroups(decls[i], function (firstDeclInGroup) {
                    var nameConflict = importDeclarationNames && importDeclarationNames[firstDeclInGroup.name];
                    if (!nameConflict) {
                        nameConflict = doesNameExistOutside && doesNameExistOutside(firstDeclInGroup.name);
                        if (nameConflict) {
                            importDeclarationNames = importDeclarationNames || TypeScript.createIntrinsicsObject();
                            importDeclarationNames[firstDeclInGroup.name] = true;
                        }
                    }

                    if (nameConflict) {
                        _this.semanticInfoChain.addDiagnosticFromAST(firstDeclInGroup.ast(), TypeScript.DiagnosticCode.Variable_declaration_cannot_have_the_same_name_as_an_import_declaration);
                    }
                });
            }
        };

        PullTypeResolver.prototype.scanVariableDeclarationGroups = function (enclosingDecl, firstDeclHandler, subsequentDeclHandler) {
            var declGroups = enclosingDecl.getVariableDeclGroups();

            for (var i = 0; i < declGroups.length; i++) {
                var firstSymbol = null;
                var enclosingDeclForFirstSymbol = null;

                if (enclosingDecl.kind === 1 /* Script */ && declGroups[i].length) {
                    var name = declGroups[i][0].name;
                    var candidateSymbol = this.semanticInfoChain.findTopLevelSymbol(name, 512 /* Variable */, enclosingDecl);
                    if (candidateSymbol) {
                        if (!candidateSymbol.anyDeclHasFlag(118784 /* ImplicitVariable */)) {
                            if (!candidateSymbol.isResolved) {
                                this.resolveDeclaredSymbol(candidateSymbol);
                            }
                            firstSymbol = candidateSymbol;
                        }
                    }
                }

                for (var j = 0; j < declGroups[i].length; j++) {
                    var decl = declGroups[i][j];

                    var name = decl.name;

                    var symbol = decl.getSymbol();

                    if (j === 0) {
                        firstDeclHandler(decl);
                        if (!subsequentDeclHandler) {
                            break;
                        }

                        if (!firstSymbol || !firstSymbol.type) {
                            firstSymbol = symbol;
                            continue;
                        }
                    }

                    subsequentDeclHandler(decl, firstSymbol);
                }
            }
        };

        PullTypeResolver.prototype.postTypeCheckModuleDeclaration = function (ast, context) {
            this.checkThisCaptureVariableCollides(ast, true, context);
        };

        PullTypeResolver.prototype.isTypeRefWithoutTypeArgs = function (term) {
            if (term.kind() === 11 /* IdentifierName */) {
                return true;
            } else if (term.kind() === 121 /* QualifiedName */) {
                var binex = term;

                if (binex.right.kind() === 11 /* IdentifierName */) {
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.createInstantiatedType = function (type, typeArguments) {
            if (!type.isGeneric()) {
                return type;
            }

            var typeParameters = type.getTypeArgumentsOrTypeParameters();

            var typeParameterArgumentMap = [];

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameterArgumentMap[typeParameters[i].pullSymbolID] = typeArguments[i] || new TypeScript.PullErrorTypeSymbol(this.semanticInfoChain.anyTypeSymbol, typeParameters[i].name);
            }

            return TypeScript.PullInstantiatedTypeReferenceSymbol.create(this, type, typeParameterArgumentMap);
        };

        PullTypeResolver.prototype.resolveReferenceTypeDeclaration = function (classOrInterface, name, heritageClauses, context) {
            var _this = this;
            var typeDecl = this.semanticInfoChain.getDeclForAST(classOrInterface);
            var enclosingDecl = this.getEnclosingDecl(typeDecl);
            var typeDeclSymbol = typeDecl.getSymbol();
            var typeDeclIsClass = classOrInterface.kind() === 131 /* ClassDeclaration */;
            var hasVisited = this.getSymbolForAST(classOrInterface, context) !== null;

            if ((typeDeclSymbol.isResolved && hasVisited) || (typeDeclSymbol.inResolution && !context.isInBaseTypeResolution())) {
                return typeDeclSymbol;
            }

            var wasResolving = typeDeclSymbol.inResolution;
            typeDeclSymbol.startResolving();

            var typeRefDecls = typeDeclSymbol.getDeclarations();

            for (var i = 0; i < typeRefDecls.length; i++) {
                var childDecls = typeRefDecls[i].getChildDecls();

                for (var j = 0; j < childDecls.length; j++) {
                    childDecls[j].ensureSymbolIsBound();
                }
            }

            if (!typeDeclSymbol.isResolved) {
                var typeDeclTypeParameters = typeDeclSymbol.getTypeParameters();
                for (var i = 0; i < typeDeclTypeParameters.length; i++) {
                    this.resolveDeclaredSymbol(typeDeclTypeParameters[i], context);
                }
            }

            var wasInBaseTypeResolution = context.startBaseTypeResolution();

            if (!typeDeclIsClass && !hasVisited) {
                typeDeclSymbol.resetKnownBaseTypeCount();
            }

            var extendsClause = TypeScript.ASTHelpers.getExtendsHeritageClause(heritageClauses);
            if (extendsClause) {
                for (var i = typeDeclSymbol.getKnownBaseTypeCount(); i < extendsClause.typeNames.nonSeparatorCount(); i = typeDeclSymbol.getKnownBaseTypeCount()) {
                    typeDeclSymbol.incrementKnownBaseCount();
                    var parentType = this.resolveTypeReference(extendsClause.typeNames.nonSeparatorAt(i), context);

                    if (typeDeclSymbol.isValidBaseKind(parentType, true)) {
                        this.setSymbolForAST(extendsClause.typeNames.nonSeparatorAt(i), parentType, null);

                        if (!typeDeclSymbol.hasBase(parentType) && !parentType.hasBase(typeDeclSymbol)) {
                            typeDeclSymbol.addExtendedType(parentType);

                            var specializations = typeDeclSymbol.getKnownSpecializations();

                            for (var j = 0; j < specializations.length; j++) {
                                specializations[j].addExtendedType(parentType);
                            }
                        }
                    } else if (parentType && !this.getSymbolForAST(extendsClause.typeNames.nonSeparatorAt(i), context)) {
                        this.setSymbolForAST(extendsClause.typeNames.nonSeparatorAt(i), parentType, null);
                    }
                }
            }

            var implementsClause = TypeScript.ASTHelpers.getImplementsHeritageClause(heritageClauses);
            if (implementsClause && typeDeclIsClass) {
                var extendsCount = extendsClause ? extendsClause.typeNames.nonSeparatorCount() : 0;
                for (var i = typeDeclSymbol.getKnownBaseTypeCount(); ((i - extendsCount) >= 0) && ((i - extendsCount) < implementsClause.typeNames.nonSeparatorCount()); i = typeDeclSymbol.getKnownBaseTypeCount()) {
                    typeDeclSymbol.incrementKnownBaseCount();
                    var implementedTypeAST = implementsClause.typeNames.nonSeparatorAt(i - extendsCount);
                    var implementedType = this.resolveTypeReference(implementedTypeAST, context);

                    if (typeDeclSymbol.isValidBaseKind(implementedType, false)) {
                        this.setSymbolForAST(implementsClause.typeNames.nonSeparatorAt(i - extendsCount), implementedType, null);

                        if (!typeDeclSymbol.hasBase(implementedType) && !implementedType.hasBase(typeDeclSymbol)) {
                            typeDeclSymbol.addImplementedType(implementedType);
                        }
                    } else if (implementedType && !this.getSymbolForAST(implementsClause.typeNames.nonSeparatorAt(i - extendsCount), context)) {
                        this.setSymbolForAST(implementsClause.typeNames.nonSeparatorAt(i - extendsCount), implementedType, null);
                    }
                }
            }

            context.doneBaseTypeResolution(wasInBaseTypeResolution);

            if (wasInBaseTypeResolution) {
                typeDeclSymbol.inResolution = false;

                this.typeCheckCallBacks.push(function (context) {
                    if (classOrInterface.kind() === 131 /* ClassDeclaration */) {
                        _this.resolveClassDeclaration(classOrInterface, context);
                    } else {
                        _this.resolveInterfaceDeclaration(classOrInterface, context);
                    }
                });

                return typeDeclSymbol;
            }

            this.setSymbolForAST(name, typeDeclSymbol, context);
            this.setSymbolForAST(classOrInterface, typeDeclSymbol, context);

            typeDeclSymbol.setResolved();

            return typeDeclSymbol;
        };

        PullTypeResolver.prototype.resolveClassDeclaration = function (classDeclAST, context) {
            var classDecl = this.semanticInfoChain.getDeclForAST(classDeclAST);
            var classDeclSymbol = classDecl.getSymbol();

            if (!classDeclSymbol.isResolved) {
                this.resolveReferenceTypeDeclaration(classDeclAST, classDeclAST.identifier, classDeclAST.heritageClauses, context);

                var constructorMethod = classDeclSymbol.getConstructorMethod();
                var extendedTypes = classDeclSymbol.getExtendedTypes();
                var parentType = extendedTypes.length ? extendedTypes[0] : null;

                if (constructorMethod) {
                    if (parentType) {
                        var parentConstructorSymbol = parentType.getConstructorMethod();

                        if (parentConstructorSymbol) {
                            var parentConstructorTypeSymbol = parentConstructorSymbol.type;
                            var constructorTypeSymbol = constructorMethod.type;
                            if (!constructorTypeSymbol.hasBase(parentConstructorTypeSymbol)) {
                                constructorTypeSymbol.addExtendedType(parentConstructorTypeSymbol);
                            }
                        }
                    }

                    if (!classDeclSymbol.isResolved) {
                        return classDeclSymbol;
                    }
                }

                this.resolveOtherDeclarations(classDeclAST, context);
            }

            if (this.canTypeCheckAST(classDeclAST, context)) {
                this.typeCheckClassDeclaration(classDeclAST, context);
            }

            return classDeclSymbol;
        };

        PullTypeResolver.prototype.typeCheckTypeParametersOfTypeDeclaration = function (classOrInterface, context) {
            var _this = this;
            var typeParametersList = classOrInterface.kind() == 131 /* ClassDeclaration */ ? classOrInterface.typeParameterList : classOrInterface.typeParameterList;

            if (typeParametersList) {
                var typeDecl = this.semanticInfoChain.getDeclForAST(classOrInterface);
                var typeDeclSymbol = typeDecl.getSymbol();

                for (var i = 0; i < typeParametersList.typeParameters.nonSeparatorCount(); i++) {
                    var typeParameterAST = typeParametersList.typeParameters.nonSeparatorAt(i);
                    this.resolveTypeParameterDeclaration(typeParameterAST, context);

                    var typeParameterDecl = this.semanticInfoChain.getDeclForAST(typeParameterAST);
                    var typeParameterSymbol = typeParameterDecl.getSymbol();

                    this.checkSymbolPrivacy(typeDeclSymbol, typeParameterSymbol, function (symbol) {
                        return _this.typeParameterOfTypeDeclarationPrivacyErrorReporter(classOrInterface, typeParameterAST, typeParameterSymbol, symbol, context);
                    });
                }
            }
        };

        PullTypeResolver.prototype.typeCheckClassDeclaration = function (classDeclAST, context) {
            this.setTypeChecked(classDeclAST, context);

            var classDecl = this.semanticInfoChain.getDeclForAST(classDeclAST);
            var classDeclSymbol = classDecl.getSymbol();

            this.checkNameForCompilerGeneratedDeclarationCollision(classDeclAST, true, classDeclAST.identifier, context);
            this.resolveAST(classDeclAST.classElements, false, context);

            this.typeCheckTypeParametersOfTypeDeclaration(classDeclAST, context);
            this.typeCheckBases(classDeclAST, classDeclAST.identifier, classDeclAST.heritageClauses, classDeclSymbol, this.getEnclosingDecl(classDecl), context);

            if (!classDeclSymbol.hasBaseTypeConflict()) {
                this.typeCheckMembersAgainstIndexer(classDeclSymbol, classDecl, context);
            }

            this.checkTypeForDuplicateIndexSignatures(classDeclSymbol);
        };

        PullTypeResolver.prototype.postTypeCheckClassDeclaration = function (classDeclAST, context) {
            this.checkThisCaptureVariableCollides(classDeclAST, true, context);
        };

        PullTypeResolver.prototype.resolveTypeSymbolSignatures = function (typeSymbol, context) {
            var callSignatures = typeSymbol.getCallSignatures();
            for (var i = 0; i < callSignatures.length; i++) {
                this.resolveDeclaredSymbol(callSignatures[i], context);
            }

            var constructSignatures = typeSymbol.getConstructSignatures();
            for (var i = 0; i < constructSignatures.length; i++) {
                this.resolveDeclaredSymbol(constructSignatures[i], context);
            }

            var indexSignatures = typeSymbol.getIndexSignatures();
            for (var i = 0; i < indexSignatures.length; i++) {
                this.resolveDeclaredSymbol(indexSignatures[i], context);
            }
        };

        PullTypeResolver.prototype.resolveInterfaceDeclaration = function (interfaceDeclAST, context) {
            this.resolveReferenceTypeDeclaration(interfaceDeclAST, interfaceDeclAST.identifier, interfaceDeclAST.heritageClauses, context);

            var interfaceDecl = this.semanticInfoChain.getDeclForAST(interfaceDeclAST);
            var interfaceDeclSymbol = interfaceDecl.getSymbol();

            this.resolveTypeSymbolSignatures(interfaceDeclSymbol, context);

            if (interfaceDeclSymbol.isResolved) {
                this.resolveOtherDeclarations(interfaceDeclAST, context);

                if (this.canTypeCheckAST(interfaceDeclAST, context)) {
                    this.typeCheckInterfaceDeclaration(interfaceDeclAST, context);
                }
            }

            return interfaceDeclSymbol;
        };

        PullTypeResolver.prototype.typeCheckInterfaceDeclaration = function (interfaceDeclAST, context) {
            this.setTypeChecked(interfaceDeclAST, context);

            var interfaceDecl = this.semanticInfoChain.getDeclForAST(interfaceDeclAST);
            var interfaceDeclSymbol = interfaceDecl.getSymbol();

            this.resolveAST(interfaceDeclAST.body.typeMembers, false, context);

            this.typeCheckTypeParametersOfTypeDeclaration(interfaceDeclAST, context);
            this.typeCheckBases(interfaceDeclAST, interfaceDeclAST.identifier, interfaceDeclAST.heritageClauses, interfaceDeclSymbol, this.getEnclosingDecl(interfaceDecl), context);

            if (!interfaceDeclSymbol.hasBaseTypeConflict()) {
                this.typeCheckMembersAgainstIndexer(interfaceDeclSymbol, interfaceDecl, context);
            }

            var allInterfaceDecls = interfaceDeclSymbol.getDeclarations();
            if (interfaceDecl === allInterfaceDecls[allInterfaceDecls.length - 1]) {
                this.checkTypeForDuplicateIndexSignatures(interfaceDeclSymbol);
            }

            if (!this.checkInterfaceDeclForIdenticalTypeParameters(interfaceDeclAST, context)) {
                this.semanticInfoChain.addDiagnosticFromAST(interfaceDeclAST.identifier, TypeScript.DiagnosticCode.All_declarations_of_an_interface_must_have_identical_type_parameters);
            }
        };

        PullTypeResolver.prototype.checkInterfaceDeclForIdenticalTypeParameters = function (interfaceDeclAST, context) {
            var interfaceDecl = this.semanticInfoChain.getDeclForAST(interfaceDeclAST);
            var interfaceDeclSymbol = interfaceDecl.getSymbol();

            if (!interfaceDeclSymbol.isGeneric()) {
                return true;
            }

            var firstInterfaceDecl = interfaceDeclSymbol.getDeclarations()[0];
            if (firstInterfaceDecl == interfaceDecl) {
                return true;
            }

            var typeParameters = interfaceDecl.getTypeParameters();
            var firstInterfaceDeclTypeParameters = firstInterfaceDecl.getTypeParameters();

            if (typeParameters.length != firstInterfaceDeclTypeParameters.length) {
                return false;
            }

            for (var i = 0; i < typeParameters.length; i++) {
                var typeParameter = typeParameters[i];
                var firstInterfaceDeclTypeParameter = firstInterfaceDeclTypeParameters[i];

                if (typeParameter.name != firstInterfaceDeclTypeParameter.name) {
                    return false;
                }

                var typeParameterSymbol = typeParameter.getSymbol();
                var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter);
                var firstInterfaceDeclTypeParameterAST = this.semanticInfoChain.getASTForDecl(firstInterfaceDeclTypeParameter);

                if (!!typeParameterAST.constraint != !!firstInterfaceDeclTypeParameterAST.constraint) {
                    return false;
                }

                if (typeParameterAST.constraint) {
                    var typeParameterConstraint = this.resolveAST(typeParameterAST.constraint, false, context);
                    if (!this.typesAreIdenticalWithNewEnclosingTypes(typeParameterConstraint, typeParameterSymbol.getConstraint(), context)) {
                        return false;
                    }
                }
            }

            return true;
        };

        PullTypeResolver.prototype.checkTypeForDuplicateIndexSignatures = function (enclosingTypeSymbol) {
            var indexSignatures = enclosingTypeSymbol.getOwnIndexSignatures();
            var firstStringIndexer = null;
            var firstNumberIndexer = null;
            for (var i = 0; i < indexSignatures.length; i++) {
                var currentIndexer = indexSignatures[i];
                var currentParameterType = currentIndexer.parameters[0].type;
                TypeScript.Debug.assert(currentParameterType);
                if (currentParameterType === this.semanticInfoChain.stringTypeSymbol) {
                    if (firstStringIndexer) {
                        this.semanticInfoChain.addDiagnosticFromAST(currentIndexer.getDeclarations()[0].ast(), TypeScript.DiagnosticCode.Duplicate_string_index_signature, null, [this.semanticInfoChain.locationFromAST(firstStringIndexer.getDeclarations()[0].ast())]);
                        return;
                    } else {
                        firstStringIndexer = currentIndexer;
                    }
                } else if (currentParameterType === this.semanticInfoChain.numberTypeSymbol) {
                    if (firstNumberIndexer) {
                        this.semanticInfoChain.addDiagnosticFromAST(currentIndexer.getDeclarations()[0].ast(), TypeScript.DiagnosticCode.Duplicate_number_index_signature, null, [this.semanticInfoChain.locationFromAST(firstNumberIndexer.getDeclarations()[0].ast())]);
                        return;
                    } else {
                        firstNumberIndexer = currentIndexer;
                    }
                }
            }
        };

        PullTypeResolver.prototype.filterSymbol = function (symbol, kind, enclosingDecl, context) {
            if (symbol) {
                if (symbol.kind & kind) {
                    return symbol;
                }

                if (symbol.isAlias()) {
                    this.resolveDeclaredSymbol(symbol, context);

                    var alias = symbol;
                    if (kind & 164 /* SomeContainer */) {
                        return alias.getExportAssignedContainerSymbol();
                    } else if (kind & 58728795 /* SomeType */) {
                        return alias.getExportAssignedTypeSymbol();
                    } else if (kind & 68147712 /* SomeValue */) {
                        return alias.getExportAssignedValueSymbol();
                    }
                }
            }
            return null;
        };

        PullTypeResolver.prototype.getMemberSymbolOfKind = function (symbolName, kind, pullTypeSymbol, enclosingDecl, context) {
            var memberSymbol = this.getNamedPropertySymbol(symbolName, kind, pullTypeSymbol);

            return {
                symbol: this.filterSymbol(memberSymbol, kind, enclosingDecl, context),
                aliasSymbol: memberSymbol && memberSymbol.isAlias() ? memberSymbol : null
            };
        };

        PullTypeResolver.prototype.resolveIdentifierOfInternalModuleReference = function (importDecl, identifier, moduleSymbol, enclosingDecl, context) {
            var rhsName = identifier.valueText();
            if (rhsName.length === 0) {
                return null;
            }

            var moduleTypeSymbol = moduleSymbol.type;
            var memberSymbol = this.getMemberSymbolOfKind(rhsName, 164 /* SomeContainer */, moduleTypeSymbol, enclosingDecl, context);
            var containerSymbol = memberSymbol.symbol;
            var valueSymbol = null;
            var typeSymbol = null;
            var aliasSymbol = null;

            var acceptableAlias = true;

            if (containerSymbol) {
                acceptableAlias = (containerSymbol.kind & 59753052 /* AcceptableAlias */) !== 0;
                aliasSymbol = memberSymbol.aliasSymbol;
            }

            if (!acceptableAlias && containerSymbol && containerSymbol.kind === 128 /* TypeAlias */) {
                this.resolveDeclaredSymbol(containerSymbol, context);
                var aliasedAssignedValue = containerSymbol.getExportAssignedValueSymbol();
                var aliasedAssignedType = containerSymbol.getExportAssignedTypeSymbol();
                var aliasedAssignedContainer = containerSymbol.getExportAssignedContainerSymbol();

                if (aliasedAssignedValue || aliasedAssignedType || aliasedAssignedContainer) {
                    aliasSymbol = containerSymbol;
                    valueSymbol = aliasedAssignedValue;
                    typeSymbol = aliasedAssignedType;
                    containerSymbol = aliasedAssignedContainer;
                    acceptableAlias = true;
                }
            }

            if (!acceptableAlias) {
                this.semanticInfoChain.addDiagnosticFromAST(identifier, TypeScript.DiagnosticCode.Import_declaration_referencing_identifier_from_internal_module_can_only_be_made_with_variables_functions_classes_interfaces_enums_and_internal_modules);
                return null;
            }

            if (!valueSymbol) {
                if (moduleTypeSymbol.getInstanceSymbol()) {
                    memberSymbol = this.getMemberSymbolOfKind(rhsName, 68147712 /* SomeValue */, moduleTypeSymbol.getInstanceSymbol().type, enclosingDecl, context);
                    valueSymbol = memberSymbol.symbol;
                    if (valueSymbol && memberSymbol.aliasSymbol) {
                        aliasSymbol = memberSymbol.aliasSymbol;
                    }
                }
            }

            if (!typeSymbol) {
                memberSymbol = this.getMemberSymbolOfKind(rhsName, 58728795 /* SomeType */, moduleTypeSymbol, enclosingDecl, context);
                typeSymbol = memberSymbol.symbol;
                if (typeSymbol && memberSymbol.aliasSymbol) {
                    aliasSymbol = memberSymbol.aliasSymbol;
                }
            }

            if (!valueSymbol && !typeSymbol && !containerSymbol) {
                this.semanticInfoChain.addDiagnosticFromAST(identifier, TypeScript.DiagnosticCode.Could_not_find_symbol_0_in_module_1, [rhsName, moduleSymbol.toString()]);
                return null;
            }

            if (!typeSymbol && containerSymbol) {
                typeSymbol = containerSymbol;
            }

            return {
                valueSymbol: valueSymbol,
                typeSymbol: typeSymbol,
                containerSymbol: containerSymbol,
                aliasSymbol: aliasSymbol
            };
        };

        PullTypeResolver.prototype.resolveModuleReference = function (importDecl, moduleNameExpr, enclosingDecl, context, declPath) {
            TypeScript.Debug.assert(moduleNameExpr.kind() === 121 /* QualifiedName */ || moduleNameExpr.kind() === 11 /* IdentifierName */ || moduleNameExpr.kind() === 14 /* StringLiteral */, "resolving module reference should always be either name or member reference");

            var moduleSymbol = null;
            var moduleName;

            if (moduleNameExpr.kind() === 121 /* QualifiedName */) {
                var dottedNameAST = moduleNameExpr;
                var moduleContainer = this.resolveModuleReference(importDecl, dottedNameAST.left, enclosingDecl, context, declPath);
                if (moduleContainer) {
                    moduleName = dottedNameAST.right.valueText();

                    moduleSymbol = this.getMemberSymbolOfKind(moduleName, 4 /* Container */, moduleContainer.type, enclosingDecl, context).symbol;
                    if (!moduleSymbol) {
                        this.semanticInfoChain.addDiagnosticFromAST(dottedNameAST.right, TypeScript.DiagnosticCode.Could_not_find_module_0_in_module_1, [moduleName, moduleContainer.toString()]);
                    }
                }
            } else {
                var valueText = moduleNameExpr.kind() === 11 /* IdentifierName */ ? moduleNameExpr.valueText() : moduleNameExpr.valueText();
                var text = moduleNameExpr.kind() === 11 /* IdentifierName */ ? moduleNameExpr.text() : moduleNameExpr.text();

                if (text.length > 0) {
                    var resolvedModuleNameSymbol = this.getSymbolFromDeclPath(valueText, declPath, 4 /* Container */);
                    moduleSymbol = this.filterSymbol(resolvedModuleNameSymbol, 4 /* Container */, enclosingDecl, context);
                    if (moduleSymbol) {
                        this.semanticInfoChain.setSymbolForAST(moduleNameExpr, moduleSymbol);
                        if (resolvedModuleNameSymbol.isAlias()) {
                            this.semanticInfoChain.setAliasSymbolForAST(moduleNameExpr, resolvedModuleNameSymbol);
                            var importDeclSymbol = importDecl.getSymbol();
                            importDeclSymbol.addLinkedAliasSymbol(resolvedModuleNameSymbol);
                        }
                    } else {
                        this.semanticInfoChain.addDiagnosticFromAST(moduleNameExpr, TypeScript.DiagnosticCode.Unable_to_resolve_module_reference_0, [valueText]);
                    }
                }
            }

            return moduleSymbol;
        };

        PullTypeResolver.prototype.resolveInternalModuleReference = function (importStatementAST, context) {
            var importDecl = this.semanticInfoChain.getDeclForAST(importStatementAST);
            var enclosingDecl = this.getEnclosingDecl(importDecl);

            var moduleReference = importStatementAST.moduleReference;

            var aliasExpr = moduleReference.kind() === 245 /* ExternalModuleReference */ ? moduleReference.stringLiteral : moduleReference.moduleName;

            var declPath = enclosingDecl.getParentPath();
            var aliasedType = null;
            var importDeclSymbol = importDecl.getSymbol();

            if (aliasExpr.kind() === 11 /* IdentifierName */ || aliasExpr.kind() === 14 /* StringLiteral */) {
                var moduleSymbol = this.resolveModuleReference(importDecl, aliasExpr, enclosingDecl, context, declPath);
                if (moduleSymbol) {
                    aliasedType = moduleSymbol.type;
                    this.semanticInfoChain.setAliasSymbolForAST(moduleReference, this.semanticInfoChain.getAliasSymbolForAST(aliasExpr));
                    if (aliasedType.anyDeclHasFlag(32768 /* InitializedModule */)) {
                        var moduleName = aliasExpr.kind() === 11 /* IdentifierName */ ? aliasExpr.valueText() : aliasExpr.valueText();
                        var valueSymbol = this.getSymbolFromDeclPath(moduleName, declPath, 68147712 /* SomeValue */);
                        var instanceSymbol = aliasedType.getInstanceSymbol();

                        if (valueSymbol && (instanceSymbol != valueSymbol || valueSymbol.type === aliasedType)) {
                            var text = aliasExpr.kind() === 11 /* IdentifierName */ ? aliasExpr.text() : aliasExpr.text();
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(aliasExpr, TypeScript.DiagnosticCode.Internal_module_reference_0_in_import_declaration_does_not_reference_module_instance_for_1, [text, moduleSymbol.type.toString(enclosingDecl ? enclosingDecl.getSymbol() : null)]));
                        } else {
                            importDeclSymbol.setAssignedValueSymbol(valueSymbol);
                        }
                    }
                } else {
                    aliasedType = this.getNewErrorTypeSymbol();
                }
            } else if (aliasExpr.kind() === 121 /* QualifiedName */) {
                var dottedNameAST = aliasExpr;
                var moduleSymbol = this.resolveModuleReference(importDecl, dottedNameAST.left, enclosingDecl, context, declPath);
                if (moduleSymbol) {
                    var identifierResolution = this.resolveIdentifierOfInternalModuleReference(importDecl, dottedNameAST.right, moduleSymbol, enclosingDecl, context);
                    if (identifierResolution) {
                        importDeclSymbol.setAssignedValueSymbol(identifierResolution.valueSymbol);
                        importDeclSymbol.setAssignedTypeSymbol(identifierResolution.typeSymbol);
                        importDeclSymbol.setAssignedContainerSymbol(identifierResolution.containerSymbol);
                        this.semanticInfoChain.setAliasSymbolForAST(moduleReference, identifierResolution.aliasSymbol);
                        return null;
                    }
                }
            }

            if (!aliasedType) {
                importDeclSymbol.setAssignedTypeSymbol(this.getNewErrorTypeSymbol());
            }

            return aliasedType;
        };

        PullTypeResolver.prototype.resolveImportDeclaration = function (importStatementAST, context) {
            var importDecl = this.semanticInfoChain.getDeclForAST(importStatementAST);
            var enclosingDecl = this.getEnclosingDecl(importDecl);
            var importDeclSymbol = importDecl.getSymbol();

            var aliasedType = null;

            if (importDeclSymbol.isResolved) {
                return importDeclSymbol;
            }

            importDeclSymbol.startResolving();

            if (importStatementAST.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                var modPath = importStatementAST.moduleReference.stringLiteral.valueText();
                var declPath = enclosingDecl.getParentPath();

                aliasedType = this.resolveExternalModuleReference(modPath, importDecl.fileName());

                if (!aliasedType) {
                    var path = importStatementAST.moduleReference.stringLiteral.text();
                    this.semanticInfoChain.addDiagnosticFromAST(importStatementAST, TypeScript.DiagnosticCode.Unable_to_resolve_external_module_0, [path]);
                    aliasedType = this.getNewErrorTypeSymbol();
                }
            } else {
                aliasedType = this.resolveInternalModuleReference(importStatementAST, context);
            }

            if (aliasedType) {
                if (!aliasedType.isContainer()) {
                    this.semanticInfoChain.addDiagnosticFromAST(importStatementAST, TypeScript.DiagnosticCode.Module_cannot_be_aliased_to_a_non_module_type);
                    if (!aliasedType.isError()) {
                        aliasedType = this.getNewErrorTypeSymbol();
                    }
                }

                if (aliasedType.isContainer()) {
                    importDeclSymbol.setAssignedContainerSymbol(aliasedType);
                }
                importDeclSymbol.setAssignedTypeSymbol(aliasedType);

                this.setSymbolForAST(importStatementAST.moduleReference, aliasedType, null);
            }

            importDeclSymbol.setResolved();

            this.resolveDeclaredSymbol(importDeclSymbol.assignedValue(), context);
            this.resolveDeclaredSymbol(importDeclSymbol.assignedType(), context);
            this.resolveDeclaredSymbol(importDeclSymbol.assignedContainer(), context);

            if (aliasedType && importDeclSymbol.anyDeclHasFlag(1 /* Exported */)) {
                importDeclSymbol.setIsUsedInExportedAlias();

                if (aliasedType.isContainer() && aliasedType.getExportAssignedValueSymbol()) {
                    importDeclSymbol.setIsUsedAsValue();
                }
            }

            if (this.canTypeCheckAST(importStatementAST, context)) {
                this.typeCheckImportDeclaration(importStatementAST, context);
            }

            return importDeclSymbol;
        };

        PullTypeResolver.prototype.typeCheckImportDeclaration = function (importStatementAST, context) {
            var _this = this;
            this.setTypeChecked(importStatementAST, context);

            var importDecl = this.semanticInfoChain.getDeclForAST(importStatementAST);
            var enclosingDecl = this.getEnclosingDecl(importDecl);
            var importDeclSymbol = importDecl.getSymbol();

            if (importStatementAST.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                if (this.compilationSettings.noResolve()) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(importStatementAST, TypeScript.DiagnosticCode.Import_declaration_cannot_refer_to_external_module_reference_when_noResolve_option_is_set, null));
                }

                var modPath = importStatementAST.moduleReference.stringLiteral.valueText();
                if (enclosingDecl.kind === 32 /* DynamicModule */) {
                    var ast = TypeScript.ASTHelpers.getEnclosingModuleDeclaration(this.getASTForDecl(enclosingDecl));
                    if (ast && ast.kind() === 130 /* ModuleDeclaration */) {
                        if (TypeScript.isRelative(modPath)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(importStatementAST, TypeScript.DiagnosticCode.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name));
                        }
                    }
                }
            }

            var checkPrivacy;
            if (importStatementAST.moduleReference.kind() === 245 /* ExternalModuleReference */) {
                var containerSymbol = importDeclSymbol.getExportAssignedContainerSymbol();
                var container = containerSymbol ? containerSymbol.getContainer() : null;
                if (container && container.kind === 32 /* DynamicModule */) {
                    checkPrivacy = true;
                }
            } else {
                checkPrivacy = true;
            }

            if (checkPrivacy) {
                var typeSymbol = importDeclSymbol.getExportAssignedTypeSymbol();
                var containerSymbol = importDeclSymbol.getExportAssignedContainerSymbol();
                var valueSymbol = importDeclSymbol.getExportAssignedValueSymbol();

                this.checkSymbolPrivacy(importDeclSymbol, containerSymbol, function (symbol) {
                    var messageCode = TypeScript.DiagnosticCode.Exported_import_declaration_0_is_assigned_container_that_is_or_is_using_inaccessible_module_1;
                    var messageArguments = [importDeclSymbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null), symbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null, false, false, true)];
                    context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(importStatementAST, messageCode, messageArguments));
                });

                if (typeSymbol !== containerSymbol) {
                    this.checkSymbolPrivacy(importDeclSymbol, typeSymbol, function (symbol) {
                        var messageCode = symbol.isContainer() && !symbol.isEnum() ? TypeScript.DiagnosticCode.Exported_import_declaration_0_is_assigned_type_that_is_using_inaccessible_module_1 : TypeScript.DiagnosticCode.Exported_import_declaration_0_is_assigned_type_that_has_or_is_using_private_type_1;

                        var messageArguments = [importDeclSymbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null), symbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null, false, false, true)];
                        context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(importStatementAST, messageCode, messageArguments));
                    });
                }

                if (valueSymbol) {
                    this.checkSymbolPrivacy(importDeclSymbol, valueSymbol.type, function (symbol) {
                        var messageCode = symbol.isContainer() && !symbol.isEnum() ? TypeScript.DiagnosticCode.Exported_import_declaration_0_is_assigned_value_with_type_that_is_using_inaccessible_module_1 : TypeScript.DiagnosticCode.Exported_import_declaration_0_is_assigned_value_with_type_that_has_or_is_using_private_type_1;
                        var messageArguments = [importDeclSymbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null), symbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null, false, false, true)];
                        context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(importStatementAST, messageCode, messageArguments));
                    });
                }
            }

            this.checkNameForCompilerGeneratedDeclarationCollision(importStatementAST, true, importStatementAST.identifier, context);
        };

        PullTypeResolver.prototype.postTypeCheckImportDeclaration = function (importStatementAST, context) {
            var importDecl = this.semanticInfoChain.getDeclForAST(importStatementAST);
            var importSymbol = importDecl.getSymbol();

            var isUsedAsValue = importSymbol.isUsedAsValue();
            var hasAssignedValue = importStatementAST.moduleReference.kind() !== 245 /* ExternalModuleReference */ && importSymbol.getExportAssignedValueSymbol() !== null;

            if (isUsedAsValue || hasAssignedValue) {
                this.checkThisCaptureVariableCollides(importStatementAST, true, context);
            }
        };

        PullTypeResolver.prototype.resolveExportAssignmentStatement = function (exportAssignmentAST, context) {
            var id = exportAssignmentAST.identifier.valueText();
            if (id.length === 0) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var valueSymbol = null;
            var typeSymbol = null;
            var containerSymbol = null;

            var enclosingDecl = this.getEnclosingDeclForAST(exportAssignmentAST);
            var parentSymbol = enclosingDecl.getSymbol();

            if (!parentSymbol.isType() && parentSymbol.isContainer()) {
                this.semanticInfoChain.addDiagnosticFromAST(exportAssignmentAST, TypeScript.DiagnosticCode.Export_assignments_may_only_be_used_at_the_top_level_of_external_modules);
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var declPath = enclosingDecl !== null ? [enclosingDecl] : [];

            containerSymbol = this.getSymbolFromDeclPath(id, declPath, 164 /* SomeContainer */);

            var acceptableAlias = true;

            if (containerSymbol) {
                acceptableAlias = (containerSymbol.kind & 59753052 /* AcceptableAlias */) !== 0;
            }

            if (!acceptableAlias && containerSymbol && containerSymbol.kind === 128 /* TypeAlias */) {
                this.resolveDeclaredSymbol(containerSymbol, context);

                var aliasSymbol = containerSymbol;
                var aliasedAssignedValue = aliasSymbol.getExportAssignedValueSymbol();
                var aliasedAssignedType = aliasSymbol.getExportAssignedTypeSymbol();
                var aliasedAssignedContainer = aliasSymbol.getExportAssignedContainerSymbol();

                if (aliasedAssignedValue || aliasedAssignedType || aliasedAssignedContainer) {
                    valueSymbol = aliasedAssignedValue;
                    typeSymbol = aliasedAssignedType;
                    containerSymbol = aliasedAssignedContainer;
                    aliasSymbol.setTypeUsedExternally();
                    if (valueSymbol) {
                        aliasSymbol.setIsUsedAsValue();
                    }
                    acceptableAlias = true;
                }
            }

            if (!acceptableAlias) {
                this.semanticInfoChain.addDiagnosticFromAST(exportAssignmentAST, TypeScript.DiagnosticCode.Export_assignments_may_only_be_made_with_variables_functions_classes_interfaces_enums_and_internal_modules);
                return this.semanticInfoChain.voidTypeSymbol;
            }

            if (!valueSymbol) {
                valueSymbol = this.getSymbolFromDeclPath(id, declPath, 68147712 /* SomeValue */);
            }
            if (!typeSymbol) {
                typeSymbol = this.getSymbolFromDeclPath(id, declPath, 58728795 /* SomeType */);
            }

            if (!valueSymbol && !typeSymbol && !containerSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(exportAssignmentAST, TypeScript.DiagnosticCode.Could_not_find_symbol_0, [id]));
                return this.semanticInfoChain.voidTypeSymbol;
            }

            if (valueSymbol) {
                parentSymbol.setExportAssignedValueSymbol(valueSymbol);
            }
            if (typeSymbol) {
                parentSymbol.setExportAssignedTypeSymbol(typeSymbol);
            }
            if (containerSymbol) {
                parentSymbol.setExportAssignedContainerSymbol(containerSymbol);
            }

            this.resolveDeclaredSymbol(valueSymbol, context);
            this.resolveDeclaredSymbol(typeSymbol, context);
            this.resolveDeclaredSymbol(containerSymbol, context);

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveAnyFunctionTypeSignature = function (funcDeclAST, typeParameters, parameterList, returnTypeAnnotation, context) {
            var functionDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            TypeScript.Debug.assert(functionDecl);

            var funcDeclSymbol = functionDecl.getSymbol();

            var signature = funcDeclSymbol.kind === 33554432 /* ConstructorType */ ? funcDeclSymbol.getConstructSignatures()[0] : funcDeclSymbol.getCallSignatures()[0];

            if (returnTypeAnnotation) {
                signature.returnType = this.resolveTypeReference(returnTypeAnnotation, context);
            }

            if (typeParameters) {
                for (var i = 0; i < typeParameters.typeParameters.nonSeparatorCount(); i++) {
                    this.resolveTypeParameterDeclaration(typeParameters.typeParameters.nonSeparatorAt(i), context);
                }
            }

            if (parameterList) {
                for (var i = 0; i < parameterList.parameters.nonSeparatorCount(); i++) {
                    this.resolveFunctionTypeSignatureParameter(parameterList.parameters.nonSeparatorAt(i), signature, functionDecl, context);
                }
            }

            funcDeclSymbol.setResolved();

            if (this.canTypeCheckAST(funcDeclAST, context)) {
                this.setTypeChecked(funcDeclAST, context);
                this.typeCheckFunctionOverloads(funcDeclAST, context);
            }

            return funcDeclSymbol;
        };

        PullTypeResolver.prototype.resolveFunctionTypeSignatureParameter = function (argDeclAST, signature, enclosingDecl, context) {
            var paramDecl = this.semanticInfoChain.getDeclForAST(argDeclAST);
            var paramSymbol = paramDecl.getSymbol();

            if (argDeclAST.typeAnnotation) {
                var typeRef = this.resolveTypeReference(TypeScript.ASTHelpers.getType(argDeclAST), context);

                if (paramSymbol.isVarArg && !typeRef.isArrayNamedTypeReference()) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Rest_parameters_must_be_array_types));
                    typeRef = this.getNewErrorTypeSymbol();
                }

                context.setTypeInContext(paramSymbol, typeRef);
            } else {
                if (paramSymbol.isVarArg) {
                    if (this.cachedArrayInterfaceType()) {
                        context.setTypeInContext(paramSymbol, this.createInstantiatedType(this.cachedArrayInterfaceType(), [this.semanticInfoChain.anyTypeSymbol]));
                    } else {
                        context.setTypeInContext(paramSymbol, this.semanticInfoChain.anyTypeSymbol);
                    }
                } else {
                    context.setTypeInContext(paramSymbol, this.semanticInfoChain.anyTypeSymbol);
                }

                if (this.compilationSettings.noImplicitAny()) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Parameter_0_of_function_type_implicitly_has_an_any_type, [argDeclAST.identifier.text()]));
                }
            }

            if (TypeScript.hasFlag(paramDecl.flags, 128 /* Optional */) && argDeclAST.equalsValueClause && isTypesOnlyLocation(argDeclAST)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Default_arguments_are_only_allowed_in_implementation));
            }

            paramSymbol.setResolved();
        };

        PullTypeResolver.prototype.resolveFunctionExpressionParameter = function (argDeclAST, id, typeExpr, equalsValueClause, contextParam, enclosingDecl, context) {
            var paramDecl = this.semanticInfoChain.getDeclForAST(argDeclAST);
            var paramSymbol = paramDecl.getSymbol();
            var contextualType = contextParam && contextParam.type;
            var isImplicitAny = false;

            if (typeExpr) {
                var typeRef = this.resolveTypeReference(typeExpr, context);

                if (paramSymbol.isVarArg && !typeRef.isArrayNamedTypeReference()) {
                    var diagnostic = context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Rest_parameters_must_be_array_types));
                    typeRef = this.getNewErrorTypeSymbol();
                }

                contextualType = typeRef || contextualType;
            }
            if (contextualType) {
                if (context.isInferentiallyTyping()) {
                    contextualType = context.fixAllTypeParametersReferencedByType(contextualType, this);
                }
                context.setTypeInContext(paramSymbol, contextualType);
            } else if (paramSymbol.isVarArg) {
                if (this.cachedArrayInterfaceType()) {
                    context.setTypeInContext(paramSymbol, this.createInstantiatedType(this.cachedArrayInterfaceType(), [this.semanticInfoChain.anyTypeSymbol]));
                } else {
                    context.setTypeInContext(paramSymbol, this.semanticInfoChain.anyTypeSymbol);
                }
                isImplicitAny = true;
            }

            var canTypeCheckAST = this.canTypeCheckAST(argDeclAST, context);
            if (equalsValueClause && (canTypeCheckAST || !contextualType)) {
                if (contextualType) {
                    context.propagateContextualType(contextualType);
                }

                var initExprSymbol = this.resolveAST(equalsValueClause, contextualType !== null, context);

                if (contextualType) {
                    context.popAnyContextualType();
                }

                if (!initExprSymbol || !initExprSymbol.type) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Unable_to_resolve_type_of_0, [id.text()]));

                    if (!contextualType) {
                        context.setTypeInContext(paramSymbol, this.getNewErrorTypeSymbol(paramSymbol.name));
                    }
                } else {
                    var initTypeSymbol = this.getInstanceTypeForAssignment(argDeclAST, initExprSymbol.type, context);
                    if (!contextualType) {
                        context.setTypeInContext(paramSymbol, initTypeSymbol.widenedType(this, equalsValueClause, context));
                        isImplicitAny = initTypeSymbol !== paramSymbol.type;
                    } else {
                        var comparisonInfo = new TypeComparisonInfo();

                        var isAssignable = this.sourceIsAssignableToTarget(initTypeSymbol, contextualType, argDeclAST, context, comparisonInfo);

                        if (!isAssignable) {
                            var enclosingSymbol = this.getEnclosingSymbolForAST(argDeclAST);
                            if (comparisonInfo.message) {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Cannot_convert_0_to_1_NL_2, [initTypeSymbol.toString(enclosingSymbol), contextualType.toString(enclosingSymbol), comparisonInfo.message]));
                            } else {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Cannot_convert_0_to_1, [initTypeSymbol.toString(enclosingSymbol), contextualType.toString(enclosingSymbol)]));
                            }
                        }
                    }
                }
            }

            if (!contextualType && !paramSymbol.isVarArg && !initTypeSymbol) {
                context.setTypeInContext(paramSymbol, this.semanticInfoChain.anyTypeSymbol);
                isImplicitAny = true;
            }

            if (isImplicitAny && this.compilationSettings.noImplicitAny()) {
                var functionExpressionName = paramDecl.getParentDecl().getFunctionExpressionName();
                if (functionExpressionName) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Parameter_0_of_1_implicitly_has_an_any_type, [id.text(), functionExpressionName]));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(argDeclAST, TypeScript.DiagnosticCode.Parameter_0_of_lambda_function_implicitly_has_an_any_type, [id.text()]));
                }
            }

            if (canTypeCheckAST) {
                this.checkNameForCompilerGeneratedDeclarationCollision(argDeclAST, true, id, context);
            }

            paramSymbol.setResolved();
        };

        PullTypeResolver.prototype.checkNameForCompilerGeneratedDeclarationCollision = function (astWithName, isDeclaration, name, context) {
            var compilerReservedName = getCompilerReservedName(name);
            switch (compilerReservedName) {
                case 1 /* _this */:
                    this.postTypeCheckWorkitems.push(astWithName);
                    return;

                case 2 /* _super */:
                    this.checkSuperCaptureVariableCollides(astWithName, isDeclaration, context);
                    return;

                case 3 /* arguments */:
                    this.checkArgumentsCollides(astWithName, context);
                    return;

                case 4 /* _i */:
                    this.checkIndexOfRestArgumentInitializationCollides(astWithName, isDeclaration, context);
                    return;

                case 5 /* require */:
                case 6 /* exports */:
                    if (isDeclaration) {
                        this.checkExternalModuleRequireExportsCollides(astWithName, name, context);
                    }
                    return;
            }
        };

        PullTypeResolver.prototype.hasRestParameterCodeGen = function (someFunctionDecl) {
            var enclosingAST = this.getASTForDecl(someFunctionDecl);
            var nodeType = enclosingAST.kind();

            if (nodeType === 129 /* FunctionDeclaration */) {
                var functionDeclaration = enclosingAST;
                return !TypeScript.hasFlag(someFunctionDecl.kind === 65536 /* Method */ ? someFunctionDecl.getParentDecl().flags : someFunctionDecl.flags, 8 /* Ambient */) && functionDeclaration.block && TypeScript.lastParameterIsRest(functionDeclaration.callSignature.parameterList);
            } else if (nodeType === 135 /* MemberFunctionDeclaration */) {
                var memberFunction = enclosingAST;
                return !TypeScript.hasFlag(someFunctionDecl.kind === 65536 /* Method */ ? someFunctionDecl.getParentDecl().flags : someFunctionDecl.flags, 8 /* Ambient */) && memberFunction.block && TypeScript.lastParameterIsRest(memberFunction.callSignature.parameterList);
            } else if (nodeType === 137 /* ConstructorDeclaration */) {
                var constructorDeclaration = enclosingAST;
                return !TypeScript.hasFlag(someFunctionDecl.getParentDecl().flags, 8 /* Ambient */) && constructorDeclaration.block && TypeScript.lastParameterIsRest(constructorDeclaration.callSignature.parameterList);
            } else if (nodeType === 218 /* ParenthesizedArrowFunctionExpression */) {
                var arrowFunctionExpression = enclosingAST;
                return TypeScript.lastParameterIsRest(arrowFunctionExpression.callSignature.parameterList);
            } else if (nodeType === 222 /* FunctionExpression */) {
                var functionExpression = enclosingAST;
                return TypeScript.lastParameterIsRest(functionExpression.callSignature.parameterList);
            }

            return false;
        };

        PullTypeResolver.prototype.checkArgumentsCollides = function (ast, context) {
            if (ast.kind() === 242 /* Parameter */) {
                var enclosingDecl = this.getEnclosingDeclForAST(ast);
                if (TypeScript.hasFlag(enclosingDecl.kind, 1032192 /* SomeFunction */)) {
                    if (this.hasRestParameterCodeGen(enclosingDecl)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters));
                    }
                }
            }
        };

        PullTypeResolver.prototype.checkIndexOfRestArgumentInitializationCollides = function (ast, isDeclaration, context) {
            if (!isDeclaration || ast.kind() === 242 /* Parameter */) {
                var enclosingDecl = this.getEnclosingDeclForAST(ast);
                var declPath = isDeclaration ? [enclosingDecl] : (enclosingDecl ? enclosingDecl.getParentPath() : []);
                var resolvedSymbol = null;
                var resolvedSymbolContainer;
                for (var i = declPath.length - 1; i >= 0; i--) {
                    var decl = declPath[i];
                    if (!isDeclaration) {
                        if (!resolvedSymbol) {
                            resolvedSymbol = this.resolveNameExpression(ast, context);
                            if (resolvedSymbol.isError()) {
                                return;
                            }

                            resolvedSymbolContainer = resolvedSymbol.getContainer();
                        }

                        if (resolvedSymbolContainer && TypeScript.ArrayUtilities.contains(resolvedSymbolContainer.getDeclarations(), decl)) {
                            break;
                        }
                    }

                    if (TypeScript.hasFlag(decl.kind, 1032192 /* SomeFunction */)) {
                        if (this.hasRestParameterCodeGen(decl)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, isDeclaration ? TypeScript.DiagnosticCode.Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter : TypeScript.DiagnosticCode.Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter));
                        }
                    }
                }
            }
        };

        PullTypeResolver.prototype.checkExternalModuleRequireExportsCollides = function (ast, name, context) {
            var enclosingDecl = this.getEnclosingDeclForAST(ast);

            var enclosingModule = TypeScript.ASTHelpers.getModuleDeclarationFromNameAST(name);
            if (enclosingModule) {
                enclosingDecl = this.getEnclosingDeclForAST(enclosingModule);
            }

            if (enclosingDecl && enclosingDecl.kind === 32 /* DynamicModule */) {
                var decl = this.semanticInfoChain.getDeclForAST(ast);

                if (!TypeScript.hasFlag(decl.flags, 8 /* Ambient */)) {
                    var nameText = name.valueText();
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module, [nameText, nameText]));
                }
            }
        };

        PullTypeResolver.prototype.resolveObjectTypeTypeReference = function (objectType, context) {
            var interfaceDecl = this.semanticInfoChain.getDeclForAST(objectType);
            TypeScript.Debug.assert(interfaceDecl);

            var interfaceSymbol = interfaceDecl.getSymbol();
            TypeScript.Debug.assert(interfaceSymbol);

            if (objectType.typeMembers) {
                var memberDecl = null;
                var memberSymbol = null;
                var memberType = null;
                var typeMembers = objectType.typeMembers;

                for (var i = 0; i < typeMembers.nonSeparatorCount(); i++) {
                    memberDecl = this.semanticInfoChain.getDeclForAST(typeMembers.nonSeparatorAt(i));
                    memberSymbol = (memberDecl.kind & 7340032 /* SomeSignature */) ? memberDecl.getSignatureSymbol() : memberDecl.getSymbol();

                    this.resolveAST(typeMembers.nonSeparatorAt(i), false, context);

                    memberType = memberSymbol.type;

                    if ((memberType && memberType.isGeneric()) || (memberSymbol.isSignature() && memberSymbol.isGeneric())) {
                        interfaceSymbol.setHasGenericMember();
                    }
                }
            }

            interfaceSymbol.setResolved();

            if (this.canTypeCheckAST(objectType, context)) {
                this.typeCheckObjectTypeTypeReference(objectType, context);
            }

            return interfaceSymbol;
        };

        PullTypeResolver.prototype.typeCheckObjectTypeTypeReference = function (objectType, context) {
            this.setTypeChecked(objectType, context);
            var objectTypeDecl = this.semanticInfoChain.getDeclForAST(objectType);
            var objectTypeSymbol = objectTypeDecl.getSymbol();

            this.typeCheckMembersAgainstIndexer(objectTypeSymbol, objectTypeDecl, context);
            this.checkTypeForDuplicateIndexSignatures(objectTypeSymbol);
        };

        PullTypeResolver.prototype.resolveTypeAnnotation = function (typeAnnotation, context) {
            return this.resolveTypeReference(typeAnnotation.type, context);
        };

        PullTypeResolver.prototype.resolveTypeReference = function (typeRef, context) {
            if (typeRef === null) {
                return null;
            }

            TypeScript.Debug.assert(typeRef.kind() !== 244 /* TypeAnnotation */);

            var aliasType = null;
            var type = this.computeTypeReferenceSymbol(typeRef, context);

            if (type.kind === 4 /* Container */) {
                var container = type;
                var instanceSymbol = container.getInstanceSymbol();

                if (instanceSymbol && (instanceSymbol.anyDeclHasFlag(16384 /* ClassConstructorVariable */) || instanceSymbol.kind === 32768 /* ConstructorMethod */)) {
                    type = instanceSymbol.type.getAssociatedContainerType();
                }
            }

            if (type && type.isAlias()) {
                aliasType = type;
                type = aliasType.getExportAssignedTypeSymbol();
            }

            if (type && !type.isGeneric()) {
                if (aliasType) {
                    this.semanticInfoChain.setAliasSymbolForAST(typeRef, aliasType);
                }
            }

            if (type && !type.isError()) {
                if ((type.kind & 58728795 /* SomeType */) === 0) {
                    if (type.kind & 164 /* SomeContainer */) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(typeRef, TypeScript.DiagnosticCode.Type_reference_cannot_refer_to_container_0, [aliasType ? aliasType.toString() : type.toString()]));
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(typeRef, TypeScript.DiagnosticCode.Type_reference_must_refer_to_type));
                    }
                }
            }

            if (this.canTypeCheckAST(typeRef, context)) {
                this.setTypeChecked(typeRef, context);
            }

            return type;
        };

        PullTypeResolver.prototype.getArrayType = function (elementType) {
            var arraySymbol = elementType.getArrayType();

            if (!arraySymbol) {
                arraySymbol = this.createInstantiatedType(this.cachedArrayInterfaceType(), [elementType]);

                if (!arraySymbol) {
                    arraySymbol = this.semanticInfoChain.anyTypeSymbol;
                }

                elementType.setArrayType(arraySymbol);
            }

            return arraySymbol;
        };

        PullTypeResolver.prototype.computeTypeReferenceSymbol = function (term, context) {
            switch (term.kind()) {
                case 60 /* AnyKeyword */:
                    return this.semanticInfoChain.anyTypeSymbol;
                case 61 /* BooleanKeyword */:
                    return this.semanticInfoChain.booleanTypeSymbol;
                case 67 /* NumberKeyword */:
                    return this.semanticInfoChain.numberTypeSymbol;
                case 69 /* StringKeyword */:
                    return this.semanticInfoChain.stringTypeSymbol;
                case 41 /* VoidKeyword */:
                    return this.semanticInfoChain.voidTypeSymbol;
            }

            var typeDeclSymbol = null;

            if (term.kind() === 11 /* IdentifierName */) {
                typeDeclSymbol = this.resolveTypeNameExpression(term, context);
            } else if (term.kind() === 123 /* FunctionType */) {
                var functionType = term;
                typeDeclSymbol = this.resolveAnyFunctionTypeSignature(functionType, functionType.typeParameterList, functionType.parameterList, functionType.type, context);
            } else if (term.kind() === 125 /* ConstructorType */) {
                var constructorType = term;
                typeDeclSymbol = this.resolveAnyFunctionTypeSignature(constructorType, constructorType.typeParameterList, constructorType.parameterList, constructorType.type, context);
            } else if (term.kind() === 122 /* ObjectType */) {
                typeDeclSymbol = this.resolveObjectTypeTypeReference(term, context);
            } else if (term.kind() === 126 /* GenericType */) {
                typeDeclSymbol = this.resolveGenericTypeReference(term, context);
            } else if (term.kind() === 121 /* QualifiedName */) {
                typeDeclSymbol = this.resolveQualifiedName(term, context);
            } else if (term.kind() === 14 /* StringLiteral */) {
                var stringConstantAST = term;
                var enclosingDecl = this.getEnclosingDeclForAST(term);
                typeDeclSymbol = new TypeScript.PullStringConstantTypeSymbol(stringConstantAST.text());
                var decl = new TypeScript.PullSynthesizedDecl(stringConstantAST.text(), stringConstantAST.text(), typeDeclSymbol.kind, null, enclosingDecl, enclosingDecl.semanticInfoChain);
                typeDeclSymbol.addDeclaration(decl);
            } else if (term.kind() === 127 /* TypeQuery */) {
                var typeQuery = term;

                var typeQueryTerm = typeQuery.name;

                var valueSymbol = this.resolveAST(typeQueryTerm, false, context);

                if (valueSymbol && valueSymbol.isAlias()) {
                    if (valueSymbol.assignedValue()) {
                        valueSymbol = valueSymbol.assignedValue();
                    } else {
                        var containerSymbol = valueSymbol.getExportAssignedContainerSymbol();
                        valueSymbol = (containerSymbol && containerSymbol.isContainer() && !containerSymbol.isEnum()) ? containerSymbol.getInstanceSymbol() : null;
                    }
                }

                if (valueSymbol) {
                    typeDeclSymbol = valueSymbol.type.widenedType(this, typeQueryTerm, context);
                } else {
                    typeDeclSymbol = this.getNewErrorTypeSymbol();
                }
            } else if (term.kind() === 124 /* ArrayType */) {
                var arrayType = term;
                var underlying = this.resolveTypeReference(arrayType.type, context);
                typeDeclSymbol = this.getArrayType(underlying);
            } else {
                throw TypeScript.Errors.invalidOperation("unknown type");
            }

            if (!typeDeclSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(term, TypeScript.DiagnosticCode.Unable_to_resolve_type));
                return this.getNewErrorTypeSymbol();
            }

            if (typeDeclSymbol.isError()) {
                return typeDeclSymbol;
            }

            if (this.genericTypeIsUsedWithoutRequiredTypeArguments(typeDeclSymbol, term, context)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(term, TypeScript.DiagnosticCode.Generic_type_references_must_include_all_type_arguments));
                typeDeclSymbol = this.instantiateTypeToAny(typeDeclSymbol, context);
            }

            return typeDeclSymbol;
        };

        PullTypeResolver.prototype.genericTypeIsUsedWithoutRequiredTypeArguments = function (typeSymbol, term, context) {
            if (!typeSymbol) {
                return false;
            }

            if (typeSymbol.isAlias()) {
                return this.genericTypeIsUsedWithoutRequiredTypeArguments(typeSymbol.getExportAssignedTypeSymbol(), term, context);
            }

            return typeSymbol.isNamedTypeSymbol() && typeSymbol.isGeneric() && !typeSymbol.isTypeParameter() && (typeSymbol.isResolved || typeSymbol.inResolution) && !typeSymbol.getIsSpecialized() && typeSymbol.getTypeParameters().length && typeSymbol.getTypeArguments() === null && this.isTypeRefWithoutTypeArgs(term);
        };

        PullTypeResolver.prototype.resolveMemberVariableDeclaration = function (varDecl, context) {
            return this.resolveVariableDeclaratorOrParameterOrEnumElement(varDecl, varDecl.modifiers, varDecl.variableDeclarator.propertyName, TypeScript.ASTHelpers.getType(varDecl.variableDeclarator), varDecl.variableDeclarator.equalsValueClause, context);
        };

        PullTypeResolver.prototype.resolvePropertySignature = function (varDecl, context) {
            return this.resolveVariableDeclaratorOrParameterOrEnumElement(varDecl, TypeScript.sentinelEmptyArray, varDecl.propertyName, TypeScript.ASTHelpers.getType(varDecl), null, context);
        };

        PullTypeResolver.prototype.resolveVariableDeclarator = function (varDecl, context) {
            return this.resolveVariableDeclaratorOrParameterOrEnumElement(varDecl, TypeScript.ASTHelpers.getVariableDeclaratorModifiers(varDecl), varDecl.propertyName, TypeScript.ASTHelpers.getType(varDecl), varDecl.equalsValueClause, context);
        };

        PullTypeResolver.prototype.resolveParameterList = function (list, context) {
            return this.resolveSeparatedList(list.parameters, context);
        };

        PullTypeResolver.prototype.resolveParameter = function (parameter, context) {
            return this.resolveVariableDeclaratorOrParameterOrEnumElement(parameter, parameter.modifiers, parameter.identifier, TypeScript.ASTHelpers.getType(parameter), parameter.equalsValueClause, context);
        };

        PullTypeResolver.prototype.getEnumTypeSymbol = function (enumElement, context) {
            var enumDeclaration = enumElement.parent.parent;
            var decl = this.semanticInfoChain.getDeclForAST(enumDeclaration);
            var symbol = decl.getSymbol();
            this.resolveDeclaredSymbol(symbol, context);

            return symbol;
        };

        PullTypeResolver.prototype.resolveEnumElement = function (enumElement, context) {
            return this.resolveVariableDeclaratorOrParameterOrEnumElement(enumElement, TypeScript.sentinelEmptyArray, enumElement.propertyName, null, enumElement.equalsValueClause, context);
        };

        PullTypeResolver.prototype.typeCheckEnumElement = function (enumElement, context) {
            this.typeCheckVariableDeclaratorOrParameterOrEnumElement(enumElement, TypeScript.sentinelEmptyArray, enumElement.propertyName, null, enumElement.equalsValueClause, context);
        };

        PullTypeResolver.prototype.resolveEqualsValueClause = function (clause, isContextuallyTyped, context) {
            if (this.canTypeCheckAST(clause, context)) {
                this.setTypeChecked(clause, context);
            }

            return this.resolveAST(clause.value, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.resolveVariableDeclaratorOrParameterOrEnumElement = function (varDeclOrParameter, modifiers, name, typeExpr, init, context) {
            var hasTypeExpr = typeExpr !== null || varDeclOrParameter.kind() === 243 /* EnumElement */;
            var enclosingDecl = this.getEnclosingDeclForAST(varDeclOrParameter);
            var decl = this.semanticInfoChain.getDeclForAST(varDeclOrParameter);

            if (enclosingDecl && decl.kind === 2048 /* Parameter */) {
                enclosingDecl.ensureSymbolIsBound();
            }

            var declSymbol = decl.getSymbol();
            var declParameterSymbol = decl.getValueDecl() ? decl.getValueDecl().getSymbol() : null;

            if (declSymbol.isResolved) {
                var declType = declSymbol.type;
                var valDecl = decl.getValueDecl();

                if (valDecl) {
                    var valSymbol = valDecl.getSymbol();

                    if (valSymbol && !valSymbol.isResolved) {
                        valSymbol.type = declType;
                        valSymbol.setResolved();
                    }
                }
            } else {
                if (declSymbol.inResolution) {
                    declSymbol.type = this.semanticInfoChain.anyTypeSymbol;
                    declSymbol.setResolved();
                    return declSymbol;
                }

                if (!declSymbol.type || !declSymbol.type.isError()) {
                    declSymbol.startResolving();

                    var typeExprSymbol = this.resolveAndTypeCheckVariableDeclarationTypeExpr(varDeclOrParameter, name, typeExpr, context);

                    if (!hasTypeExpr) {
                        this.resolveAndTypeCheckVariableDeclaratorOrParameterInitExpr(varDeclOrParameter, name, typeExpr, init, context, typeExprSymbol);
                    }

                    if (!(hasTypeExpr || init)) {
                        var defaultType = this.semanticInfoChain.anyTypeSymbol;

                        if (declSymbol.isVarArg && this.cachedArrayInterfaceType()) {
                            defaultType = this.createInstantiatedType(this.cachedArrayInterfaceType(), [defaultType]);
                        }

                        context.setTypeInContext(declSymbol, defaultType);

                        if (declParameterSymbol) {
                            declParameterSymbol.type = defaultType;
                        }
                    }
                    declSymbol.setResolved();

                    if (declParameterSymbol) {
                        declParameterSymbol.setResolved();
                    }
                }
            }

            if (this.canTypeCheckAST(varDeclOrParameter, context)) {
                this.typeCheckVariableDeclaratorOrParameterOrEnumElement(varDeclOrParameter, modifiers, name, typeExpr, init, context);
            }

            return declSymbol;
        };

        PullTypeResolver.prototype.resolveAndTypeCheckVariableDeclarationTypeExpr = function (varDeclOrParameter, name, typeExpr, context) {
            var enclosingDecl = this.getEnclosingDeclForAST(varDeclOrParameter);
            var decl = this.semanticInfoChain.getDeclForAST(varDeclOrParameter);
            var declSymbol = decl.getSymbol();
            var declParameterSymbol = decl.getValueDecl() ? decl.getValueDecl().getSymbol() : null;

            if (varDeclOrParameter.kind() === 243 /* EnumElement */) {
                var result = this.getEnumTypeSymbol(varDeclOrParameter, context);
                declSymbol.type = result;
                return result;
            }

            if (!typeExpr) {
                return null;
            }

            var wrapperDecl = this.getEnclosingDecl(decl);
            wrapperDecl = wrapperDecl || enclosingDecl;

            var typeExprSymbol = this.resolveTypeReference(typeExpr, context);

            if (!typeExprSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Unable_to_resolve_type_of_0, [name.text()]));
                declSymbol.type = this.getNewErrorTypeSymbol();

                if (declParameterSymbol) {
                    context.setTypeInContext(declParameterSymbol, this.semanticInfoChain.anyTypeSymbol);
                }
            } else if (typeExprSymbol.isError()) {
                context.setTypeInContext(declSymbol, typeExprSymbol);
                if (declParameterSymbol) {
                    context.setTypeInContext(declParameterSymbol, typeExprSymbol);
                }
            } else {
                if (typeExprSymbol === this.semanticInfoChain.anyTypeSymbol) {
                    decl.setFlag(16777216 /* IsAnnotatedWithAny */);
                }

                if (typeExprSymbol.isContainer()) {
                    var exportedTypeSymbol = typeExprSymbol.getExportAssignedTypeSymbol();

                    if (exportedTypeSymbol) {
                        typeExprSymbol = exportedTypeSymbol;
                    } else {
                        typeExprSymbol = typeExprSymbol.type;

                        if (typeExprSymbol.isAlias()) {
                            typeExprSymbol = typeExprSymbol.getExportAssignedTypeSymbol();
                        }

                        if (typeExprSymbol && typeExprSymbol.isContainer() && !typeExprSymbol.isEnum()) {
                            var instanceSymbol = typeExprSymbol.getInstanceSymbol();

                            if (!instanceSymbol || !TypeScript.PullHelpers.symbolIsEnum(instanceSymbol)) {
                                typeExprSymbol = this.getNewErrorTypeSymbol();
                            } else {
                                typeExprSymbol = instanceSymbol.type;
                            }
                        }
                    }
                } else if (declSymbol.isVarArg && !(typeExprSymbol.isArrayNamedTypeReference() || typeExprSymbol === this.cachedArrayInterfaceType())) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Rest_parameters_must_be_array_types));
                    typeExprSymbol = this.getNewErrorTypeSymbol();
                }

                context.setTypeInContext(declSymbol, typeExprSymbol);

                if (declParameterSymbol) {
                    declParameterSymbol.type = typeExprSymbol;
                }

                if (typeExprSymbol.kind === 16777216 /* FunctionType */ && !typeExprSymbol.getFunctionSymbol()) {
                    typeExprSymbol.setFunctionSymbol(declSymbol);
                }
            }

            return typeExprSymbol;
        };

        PullTypeResolver.prototype.resolveAndTypeCheckVariableDeclaratorOrParameterInitExpr = function (varDeclOrParameter, name, typeExpr, init, context, typeExprSymbol) {
            if (!init) {
                return null;
            }

            var hasTypeExpr = typeExpr !== null || varDeclOrParameter.kind() === 243 /* EnumElement */;
            if (typeExprSymbol) {
                context.pushNewContextualType(typeExprSymbol);
            }

            var enclosingDecl = this.getEnclosingDeclForAST(varDeclOrParameter);
            var decl = this.semanticInfoChain.getDeclForAST(varDeclOrParameter);
            var declSymbol = decl.getSymbol();
            var declParameterSymbol = decl.getValueDecl() ? decl.getValueDecl().getSymbol() : null;

            var wrapperDecl = this.getEnclosingDecl(decl);
            wrapperDecl = wrapperDecl || enclosingDecl;

            var initExprSymbol = this.resolveAST(init, typeExprSymbol !== null, context);

            if (typeExprSymbol) {
                context.popAnyContextualType();
            }

            if (!initExprSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Unable_to_resolve_type_of_0, [name.text()]));

                if (!hasTypeExpr) {
                    context.setTypeInContext(declSymbol, this.getNewErrorTypeSymbol());

                    if (declParameterSymbol) {
                        context.setTypeInContext(declParameterSymbol, this.semanticInfoChain.anyTypeSymbol);
                    }
                }
            } else {
                var initTypeSymbol = initExprSymbol.type;

                if (!hasTypeExpr) {
                    var widenedInitTypeSymbol = initTypeSymbol.widenedType(this, init.value, context);
                    context.setTypeInContext(declSymbol, widenedInitTypeSymbol);

                    if (declParameterSymbol) {
                        context.setTypeInContext(declParameterSymbol, widenedInitTypeSymbol);
                    }

                    if (this.compilationSettings.noImplicitAny()) {
                        if ((widenedInitTypeSymbol !== initTypeSymbol) && (widenedInitTypeSymbol === this.semanticInfoChain.anyTypeSymbol)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Variable_0_implicitly_has_an_any_type, [name.text()]));
                        }
                    }

                    return widenedInitTypeSymbol;
                }
            }

            return initTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckPropertySignature = function (varDecl, context) {
            this.typeCheckVariableDeclaratorOrParameterOrEnumElement(varDecl, TypeScript.sentinelEmptyArray, varDecl.propertyName, TypeScript.ASTHelpers.getType(varDecl), null, context);
        };

        PullTypeResolver.prototype.typeCheckMemberVariableDeclaration = function (varDecl, context) {
            this.typeCheckVariableDeclaratorOrParameterOrEnumElement(varDecl, varDecl.modifiers, varDecl.variableDeclarator.propertyName, TypeScript.ASTHelpers.getType(varDecl), varDecl.variableDeclarator.equalsValueClause, context);
        };

        PullTypeResolver.prototype.typeCheckVariableDeclarator = function (varDecl, context) {
            this.typeCheckVariableDeclaratorOrParameterOrEnumElement(varDecl, TypeScript.ASTHelpers.getVariableDeclaratorModifiers(varDecl), varDecl.propertyName, TypeScript.ASTHelpers.getType(varDecl), varDecl.equalsValueClause, context);
        };

        PullTypeResolver.prototype.typeCheckParameter = function (parameter, context) {
            this.typeCheckVariableDeclaratorOrParameterOrEnumElement(parameter, parameter.modifiers, parameter.identifier, TypeScript.ASTHelpers.getType(parameter), parameter.equalsValueClause, context);
        };

        PullTypeResolver.prototype.typeCheckVariableDeclaratorOrParameterOrEnumElement = function (varDeclOrParameter, modifiers, name, typeExpr, init, context) {
            var _this = this;
            this.setTypeChecked(varDeclOrParameter, context);

            var hasTypeExpr = typeExpr !== null || varDeclOrParameter.kind() === 243 /* EnumElement */;
            var enclosingDecl = this.getEnclosingDeclForAST(varDeclOrParameter);
            var decl = this.semanticInfoChain.getDeclForAST(varDeclOrParameter);
            var declSymbol = decl.getSymbol();

            var typeExprSymbol = this.resolveAndTypeCheckVariableDeclarationTypeExpr(varDeclOrParameter, name, typeExpr, context);

            var initTypeSymbol = this.resolveAndTypeCheckVariableDeclaratorOrParameterInitExpr(varDeclOrParameter, name, typeExpr, init, context, typeExprSymbol);

            if (hasTypeExpr || init) {
                if (typeExprSymbol && typeExprSymbol.isAlias()) {
                    typeExprSymbol = typeExprSymbol.getExportAssignedTypeSymbol();
                }

                if (typeExprSymbol && typeExprSymbol.kind === 32 /* DynamicModule */) {
                    var exportedTypeSymbol = typeExprSymbol.getExportAssignedTypeSymbol();

                    if (exportedTypeSymbol) {
                        typeExprSymbol = exportedTypeSymbol;
                    } else {
                        var instanceTypeSymbol = typeExprSymbol.getInstanceType();

                        if (!instanceTypeSymbol) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Tried_to_set_variable_type_to_uninitialized_module_type_0, [typeExprSymbol.toString()]));
                            typeExprSymbol = null;
                        } else {
                            typeExprSymbol = instanceTypeSymbol;
                        }
                    }
                }

                initTypeSymbol = this.getInstanceTypeForAssignment(varDeclOrParameter, initTypeSymbol, context);

                if (initTypeSymbol && typeExprSymbol) {
                    var comparisonInfo = new TypeComparisonInfo();

                    var isAssignable = this.sourceIsAssignableToTarget(initTypeSymbol, typeExprSymbol, varDeclOrParameter, context, comparisonInfo);

                    if (!isAssignable) {
                        var enclosingSymbol = this.getEnclosingSymbolForAST(varDeclOrParameter);
                        if (comparisonInfo.message) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Cannot_convert_0_to_1_NL_2, [initTypeSymbol.toString(enclosingSymbol), typeExprSymbol.toString(enclosingSymbol), comparisonInfo.message]));
                        } else {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Cannot_convert_0_to_1, [initTypeSymbol.toString(enclosingSymbol), typeExprSymbol.toString(enclosingSymbol)]));
                        }
                    }
                }
            } else if (varDeclOrParameter.kind() !== 243 /* EnumElement */ && this.compilationSettings.noImplicitAny() && !this.isForInVariableDeclarator(varDeclOrParameter)) {
                var wrapperDecl = this.getEnclosingDecl(decl);
                wrapperDecl = wrapperDecl || enclosingDecl;

                var needReportError = function (containerDecl, selfDecl) {
                    if (!TypeScript.hasFlag(containerDecl.flags, 8 /* Ambient */)) {
                        return true;
                    }

                    return selfDecl && !TypeScript.hasFlag(selfDecl.flags, 2 /* Private */);
                };

                if ((wrapperDecl.kind === 16384 /* Function */ || wrapperDecl.kind === 32768 /* ConstructorMethod */ || wrapperDecl.kind === 2097152 /* ConstructSignature */)) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Parameter_0_of_1_implicitly_has_an_any_type, [name.text(), enclosingDecl.name]));
                } else if (wrapperDecl.kind === 65536 /* Method */) {
                    var parentDecl = wrapperDecl.getParentDecl();

                    if (needReportError(parentDecl, wrapperDecl)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Parameter_0_of_1_implicitly_has_an_any_type, [name.text(), enclosingDecl.name]));
                    }
                } else if (decl.kind === 4096 /* Property */ && !declSymbol.getContainer().isNamedTypeSymbol()) {
                    if (needReportError(wrapperDecl, decl)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Member_0_of_object_type_implicitly_has_an_any_type, [name.text()]));
                    }
                } else if (wrapperDecl.kind !== 268435456 /* CatchBlock */) {
                    if (needReportError(wrapperDecl) || !TypeScript.hasModifier(modifiers, 2 /* Private */)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Variable_0_implicitly_has_an_any_type, [name.text()]));
                    }
                }
            }

            if (init && varDeclOrParameter.kind() === 242 /* Parameter */) {
                var containerSignature = enclosingDecl.getSignatureSymbol();
                if (containerSignature && !containerSignature.isDefinition()) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(varDeclOrParameter, TypeScript.DiagnosticCode.Default_arguments_are_only_allowed_in_implementation));
                }
            }
            if (declSymbol.kind !== 2048 /* Parameter */ && (declSymbol.kind !== 4096 /* Property */ || declSymbol.getContainer().isNamedTypeSymbol())) {
                this.checkSymbolPrivacy(declSymbol, declSymbol.type, function (symbol) {
                    return _this.variablePrivacyErrorReporter(varDeclOrParameter, declSymbol, symbol, context);
                });
            }

            if ((declSymbol.kind !== 4096 /* Property */ && declSymbol.kind !== 67108864 /* EnumMember */) || declSymbol.anyDeclHasFlag(8388608 /* PropertyParameter */)) {
                this.checkNameForCompilerGeneratedDeclarationCollision(varDeclOrParameter, true, name, context);
            }
        };

        PullTypeResolver.prototype.isForInVariableDeclarator = function (ast) {
            return ast.kind() === 225 /* VariableDeclarator */ && ast.parent && ast.parent.parent && ast.parent.parent.parent && ast.parent.kind() === 2 /* SeparatedList */ && ast.parent.parent.kind() === 224 /* VariableDeclaration */ && ast.parent.parent.parent.kind() === 155 /* ForInStatement */ && ast.parent.parent.parent.variableDeclaration === ast.parent.parent;
        };

        PullTypeResolver.prototype.checkSuperCaptureVariableCollides = function (superAST, isDeclaration, context) {
            var enclosingDecl = this.getEnclosingDeclForAST(superAST);

            var classSymbol = this.getContextualClassSymbolForEnclosingDecl(superAST, enclosingDecl);

            if (classSymbol && !classSymbol.anyDeclHasFlag(8 /* Ambient */)) {
                if (superAST.kind() === 242 /* Parameter */) {
                    var enclosingAST = this.getASTForDecl(enclosingDecl);
                    if (enclosingAST.kind() !== 218 /* ParenthesizedArrowFunctionExpression */ && enclosingAST.kind() !== 219 /* SimpleArrowFunctionExpression */) {
                        var block = enclosingDecl.kind === 65536 /* Method */ ? enclosingAST.block : enclosingAST.block;
                        if (!block) {
                            return;
                        }
                    }
                }

                this.resolveDeclaredSymbol(classSymbol, context);

                var parents = classSymbol.getExtendedTypes();
                if (parents.length) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(superAST, isDeclaration ? TypeScript.DiagnosticCode.Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference : TypeScript.DiagnosticCode.Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference));
                }
            }
        };

        PullTypeResolver.prototype.checkThisCaptureVariableCollides = function (_thisAST, isDeclaration, context) {
            if (isDeclaration) {
                var decl = this.semanticInfoChain.getDeclForAST(_thisAST);
                if (TypeScript.hasFlag(decl.flags, 8 /* Ambient */)) {
                    return;
                }
            }

            var enclosingDecl = this.getEnclosingDeclForAST(_thisAST);

            var enclosingModule = TypeScript.ASTHelpers.getModuleDeclarationFromNameAST(_thisAST);
            if (enclosingModule) {
                enclosingDecl = this.getEnclosingDeclForAST(enclosingModule);
            }

            var declPath = enclosingDecl.getParentPath();

            for (var i = declPath.length - 1; i >= 0; i--) {
                var decl = declPath[i];
                var declKind = decl.kind;
                if (declKind === 131072 /* FunctionExpression */ && TypeScript.hasFlag(decl.flags, 8192 /* ArrowFunction */)) {
                    continue;
                }

                if (declKind === 16384 /* Function */ || declKind === 65536 /* Method */ || declKind === 32768 /* ConstructorMethod */ || declKind === 262144 /* GetAccessor */ || declKind === 524288 /* SetAccessor */ || declKind === 131072 /* FunctionExpression */ || declKind === 8 /* Class */ || declKind === 4 /* Container */ || declKind === 32 /* DynamicModule */ || declKind === 1 /* Script */) {
                    if (TypeScript.hasFlag(decl.flags, 262144 /* MustCaptureThis */)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(_thisAST, isDeclaration ? TypeScript.DiagnosticCode.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference : TypeScript.DiagnosticCode.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference));
                    }
                    break;
                }
            }
        };

        PullTypeResolver.prototype.postTypeCheckVariableDeclaratorOrParameter = function (varDeclOrParameter, context) {
            this.checkThisCaptureVariableCollides(varDeclOrParameter, true, context);
        };

        PullTypeResolver.prototype.resolveTypeParameterDeclaration = function (typeParameterAST, context) {
            var typeParameterDecl = this.semanticInfoChain.getDeclForAST(typeParameterAST);
            var typeParameterSymbol = typeParameterDecl.getSymbol();

            this.resolveFirstTypeParameterDeclaration(typeParameterSymbol, context);

            if (typeParameterSymbol.isResolved && this.canTypeCheckAST(typeParameterAST, context)) {
                this.typeCheckTypeParameterDeclaration(typeParameterAST, context);
            }

            return typeParameterSymbol;
        };

        PullTypeResolver.prototype.resolveFirstTypeParameterDeclaration = function (typeParameterSymbol, context) {
            var typeParameterDecl = typeParameterSymbol.getDeclarations()[0];
            var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameterDecl);

            if (typeParameterSymbol.isResolved || typeParameterSymbol.inResolution) {
                return;
            }

            typeParameterSymbol.startResolving();

            if (typeParameterAST.constraint) {
                var constraintTypeSymbol = this.resolveTypeReference(typeParameterAST.constraint.type, context);

                if (constraintTypeSymbol) {
                    typeParameterSymbol.setConstraint(constraintTypeSymbol);
                }
            }

            typeParameterSymbol.setResolved();
        };

        PullTypeResolver.prototype.typeCheckTypeParameterDeclaration = function (typeParameterAST, context) {
            this.setTypeChecked(typeParameterAST, context);

            var constraint = this.resolveAST(typeParameterAST.constraint, false, context);

            if (constraint) {
                var typeParametersAST = typeParameterAST.parent;
                var typeParameters = [];
                for (var i = 0; i < typeParametersAST.nonSeparatorCount(); i++) {
                    var currentTypeParameterAST = typeParametersAST.nonSeparatorAt(i);
                    var currentTypeParameterDecl = this.semanticInfoChain.getDeclForAST(currentTypeParameterAST);
                    var currentTypeParameter = this.semanticInfoChain.getSymbolForDecl(currentTypeParameterDecl);
                    typeParameters[currentTypeParameter.pullSymbolID] = currentTypeParameter;
                }

                if (constraint.wrapsSomeTypeParameter(typeParameters)) {
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Constraint_of_a_type_parameter_cannot_reference_any_type_parameter_from_the_same_type_parameter_list);
                }
            }
        };

        PullTypeResolver.prototype.resolveConstraint = function (constraint, context) {
            if (this.canTypeCheckAST(constraint, context)) {
                this.setTypeChecked(constraint, context);
            }

            return this.resolveTypeReference(constraint.type, context);
        };

        PullTypeResolver.prototype.resolveFunctionBodyReturnTypes = function (funcDeclAST, block, bodyExpression, signature, useContextualType, enclosingDecl, context) {
            var _this = this;
            var returnStatementsExpressions = [];

            var enclosingDeclStack = [enclosingDecl];

            var preFindReturnExpressionTypes = function (ast, walker) {
                var go = true;

                switch (ast.kind()) {
                    case 129 /* FunctionDeclaration */:
                    case 219 /* SimpleArrowFunctionExpression */:
                    case 218 /* ParenthesizedArrowFunctionExpression */:
                    case 222 /* FunctionExpression */:
                    case 215 /* ObjectLiteralExpression */:
                        go = false;
                        break;

                    case 150 /* ReturnStatement */:
                        var returnStatement = ast;
                        enclosingDecl.setFlag(4194304 /* HasReturnStatement */);
                        returnStatementsExpressions.push({ expression: returnStatement.expression, enclosingDecl: enclosingDeclStack[enclosingDeclStack.length - 1] });
                        go = false;
                        break;

                    case 236 /* CatchClause */:
                    case 163 /* WithStatement */:
                        enclosingDeclStack[enclosingDeclStack.length] = _this.semanticInfoChain.getDeclForAST(ast);
                        break;

                    default:
                        break;
                }

                walker.options.goChildren = go;

                return ast;
            };

            var postFindReturnExpressionEnclosingDecls = function (ast, walker) {
                switch (ast.kind()) {
                    case 236 /* CatchClause */:
                    case 163 /* WithStatement */:
                        enclosingDeclStack.length--;
                        break;
                    default:
                        break;
                }

                walker.options.goChildren = true;

                return ast;
            };

            if (block) {
                TypeScript.getAstWalkerFactory().walk(block, preFindReturnExpressionTypes, postFindReturnExpressionEnclosingDecls);
            } else {
                returnStatementsExpressions.push({ expression: bodyExpression, enclosingDecl: enclosingDecl });
                enclosingDecl.setFlag(4194304 /* HasReturnStatement */);
            }

            if (!returnStatementsExpressions.length) {
                signature.returnType = this.semanticInfoChain.voidTypeSymbol;
            } else {
                var returnExpressionSymbols = [];
                var returnExpressions = [];

                for (var i = 0; i < returnStatementsExpressions.length; i++) {
                    var returnExpression = returnStatementsExpressions[i].expression;
                    if (returnExpression) {
                        var returnType = this.resolveAST(returnExpression, useContextualType, context).type;

                        if (returnType.isError()) {
                            signature.returnType = returnType;
                            return;
                        } else {
                            if (returnExpression.parent.kind() === 150 /* ReturnStatement */) {
                                this.setSymbolForAST(returnExpression.parent, returnType, context);
                            }
                        }

                        returnExpressionSymbols.push(returnType);
                        returnExpressions.push(returnExpression);
                    }
                }

                if (!returnExpressionSymbols.length) {
                    signature.returnType = this.semanticInfoChain.voidTypeSymbol;
                } else {
                    var collection = {
                        getLength: function () {
                            return returnExpressionSymbols.length;
                        },
                        getTypeAtIndex: function (index) {
                            return returnExpressionSymbols[index].type;
                        }
                    };

                    var bestCommonReturnType = this.findBestCommonType(collection, context, new TypeComparisonInfo());
                    var returnType = bestCommonReturnType;
                    var returnExpression = returnExpressions[returnExpressionSymbols.indexOf(returnType)];

                    var functionDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
                    var functionSymbol = functionDecl.getSymbol();

                    if (returnType) {
                        var previousReturnType = returnType;
                        var newReturnType = returnType.widenedType(this, returnExpression, context);
                        signature.returnType = newReturnType;

                        if (!TypeScript.ArrayUtilities.contains(returnExpressionSymbols, bestCommonReturnType)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Could_not_find_the_best_common_type_of_types_of_all_return_statement_expressions));
                        }

                        if (this.compilationSettings.noImplicitAny()) {
                            if (previousReturnType !== newReturnType && newReturnType === this.semanticInfoChain.anyTypeSymbol) {
                                var functionName = enclosingDecl.name;
                                if (functionName === "") {
                                    functionName = enclosingDecl.getFunctionExpressionName();
                                }

                                if (functionName != "") {
                                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode._0_which_lacks_return_type_annotation_implicitly_has_an_any_return_type, [functionName]));
                                } else {
                                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_any_return_type));
                                }
                            }
                        }
                    }

                    if (!functionSymbol.type && functionSymbol.isAccessor()) {
                        functionSymbol.type = signature.returnType;
                    }
                }
            }
        };

        PullTypeResolver.prototype.typeCheckConstructorDeclaration = function (funcDeclAST, context) {
            var _this = this;
            this.setTypeChecked(funcDeclAST, context);

            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            for (var i = 0; i < funcDeclAST.callSignature.parameterList.parameters.nonSeparatorCount(); i++) {
                this.resolveAST(funcDeclAST.callSignature.parameterList.parameters.nonSeparatorAt(i), false, context);
            }

            this.resolveAST(funcDeclAST.block, false, context);

            if (funcDecl.getSignatureSymbol() && funcDecl.getSignatureSymbol().isDefinition() && this.enclosingClassIsDerived(funcDecl.getParentDecl())) {
                if (!this.constructorHasSuperCall(funcDeclAST)) {
                    context.postDiagnostic(new TypeScript.Diagnostic(funcDeclAST.fileName(), this.semanticInfoChain.lineMap(funcDeclAST.fileName()), funcDeclAST.start(), "constructor".length, TypeScript.DiagnosticCode.Constructors_for_derived_classes_must_contain_a_super_call));
                } else if (this.superCallMustBeFirstStatementInConstructor(funcDecl)) {
                    var firstStatement = this.getFirstStatementOfBlockOrNull(funcDeclAST.block);
                    if (!firstStatement || !this.isSuperInvocationExpressionStatement(firstStatement)) {
                        context.postDiagnostic(new TypeScript.Diagnostic(funcDeclAST.fileName(), this.semanticInfoChain.lineMap(funcDeclAST.fileName()), funcDeclAST.start(), "constructor".length, TypeScript.DiagnosticCode.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties));
                    }
                }
            }

            this.validateVariableDeclarationGroups(funcDecl, context);

            this.checkFunctionTypePrivacy(funcDeclAST, false, null, TypeScript.ASTHelpers.parametersFromParameterList(funcDeclAST.callSignature.parameterList), null, funcDeclAST.block, context);

            this.typeCheckCallBacks.push(function (context) {
                _this.typeCheckFunctionOverloads(funcDeclAST, context);
            });
        };

        PullTypeResolver.prototype.constructorHasSuperCall = function (constructorDecl) {
            var _this = this;
            if (constructorDecl.block) {
                var foundSuperCall = false;
                var pre = function (ast, walker) {
                    switch (ast.kind()) {
                        case 129 /* FunctionDeclaration */:
                        case 219 /* SimpleArrowFunctionExpression */:
                        case 218 /* ParenthesizedArrowFunctionExpression */:
                        case 222 /* FunctionExpression */:
                        case 215 /* ObjectLiteralExpression */:
                            walker.options.goChildren = false;
                        default:
                            if (_this.isSuperInvocationExpression(ast)) {
                                foundSuperCall = true;
                                walker.options.stopWalking = true;
                            }
                    }
                };

                TypeScript.getAstWalkerFactory().walk(constructorDecl.block, pre);
                return foundSuperCall;
            }

            return false;
        };

        PullTypeResolver.prototype.typeCheckFunctionExpression = function (funcDecl, isContextuallyTyped, context) {
            this.typeCheckAnyFunctionExpression(funcDecl, funcDecl.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList), funcDecl.callSignature.typeAnnotation, funcDecl.block, null, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.typeCheckCallSignature = function (funcDecl, context) {
            this.typeCheckAnyFunctionDeclaration(funcDecl, false, null, funcDecl.typeParameterList, funcDecl.parameterList, TypeScript.ASTHelpers.getType(funcDecl), null, context);
        };

        PullTypeResolver.prototype.typeCheckConstructSignature = function (funcDecl, context) {
            this.typeCheckAnyFunctionDeclaration(funcDecl, false, null, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), null, context);
        };

        PullTypeResolver.prototype.typeCheckMethodSignature = function (funcDecl, context) {
            this.typeCheckAnyFunctionDeclaration(funcDecl, false, funcDecl.propertyName, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), null, context);
        };

        PullTypeResolver.prototype.typeCheckMemberFunctionDeclaration = function (funcDecl, context) {
            this.typeCheckAnyFunctionDeclaration(funcDecl, TypeScript.hasModifier(funcDecl.modifiers, 16 /* Static */), funcDecl.propertyName, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), funcDecl.block, context);
        };

        PullTypeResolver.prototype.containsSingleThrowStatement = function (block) {
            return block !== null && block.statements.childCount() === 1 && block.statements.childAt(0).kind() === 157 /* ThrowStatement */;
        };

        PullTypeResolver.prototype.typeCheckAnyFunctionDeclaration = function (funcDeclAST, isStatic, name, typeParameters, parameters, returnTypeAnnotation, block, context) {
            var _this = this;
            this.setTypeChecked(funcDeclAST, context);

            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            if (typeParameters) {
                for (var i = 0; i < typeParameters.typeParameters.nonSeparatorCount(); i++) {
                    this.resolveTypeParameterDeclaration(typeParameters.typeParameters.nonSeparatorAt(i), context);
                }
            }

            this.resolveAST(parameters, false, context);

            this.resolveAST(block, false, context);
            var enclosingDecl = this.getEnclosingDecl(funcDecl);

            this.resolveReturnTypeAnnotationOfFunctionDeclaration(funcDeclAST, returnTypeAnnotation, context);
            this.validateVariableDeclarationGroups(funcDecl, context);

            this.checkFunctionTypePrivacy(funcDeclAST, isStatic, typeParameters, TypeScript.ASTHelpers.parametersFromParameterList(parameters), returnTypeAnnotation, block, context);

            this.checkThatNonVoidFunctionHasReturnExpressionOrThrowStatement(funcDecl, returnTypeAnnotation, funcDecl.getSignatureSymbol().returnType, block, context);

            if (funcDecl.kind === 16384 /* Function */) {
                this.checkNameForCompilerGeneratedDeclarationCollision(funcDeclAST, true, name, context);
            }

            this.typeCheckCallBacks.push(function (context) {
                _this.typeCheckFunctionOverloads(funcDeclAST, context);
            });
        };

        PullTypeResolver.prototype.checkThatNonVoidFunctionHasReturnExpressionOrThrowStatement = function (functionDecl, returnTypeAnnotation, returnTypeSymbol, block, context) {
            var hasReturn = TypeScript.hasFlag(functionDecl.flags, 4194304 /* HasReturnStatement */);

            if (block !== null && returnTypeAnnotation !== null && !hasReturn) {
                var isVoidOrAny = this.isAnyOrEquivalent(returnTypeSymbol) || returnTypeSymbol === this.semanticInfoChain.voidTypeSymbol;

                if (!isVoidOrAny && !this.containsSingleThrowStatement(block)) {
                    var funcName = functionDecl.getDisplayName() || TypeScript.getLocalizedText(TypeScript.DiagnosticCode.expression, null);

                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(returnTypeAnnotation, TypeScript.DiagnosticCode.Function_declared_a_non_void_return_type_but_has_no_return_expression));
                }
            }
        };

        PullTypeResolver.prototype.typeCheckIndexSignature = function (funcDeclAST, context) {
            var _this = this;
            this.setTypeChecked(funcDeclAST, context);

            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            this.resolveAST(funcDeclAST.parameter, false, context);

            var enclosingDecl = this.getEnclosingDecl(funcDecl);

            this.resolveReturnTypeAnnotationOfFunctionDeclaration(funcDeclAST, TypeScript.ASTHelpers.getType(funcDeclAST), context);
            this.validateVariableDeclarationGroups(funcDecl, context);

            this.checkFunctionTypePrivacy(funcDeclAST, false, null, TypeScript.ASTHelpers.parametersFromParameter(funcDeclAST.parameter), TypeScript.ASTHelpers.getType(funcDeclAST), null, context);

            var signature = funcDecl.getSignatureSymbol();

            this.typeCheckCallBacks.push(function (context) {
                var parentSymbol = funcDecl.getSignatureSymbol().getContainer();
                var allIndexSignatures = _this.getBothKindsOfIndexSignaturesExcludingAugmentedType(parentSymbol, context);
                var stringIndexSignature = allIndexSignatures.stringSignature;
                var numberIndexSignature = allIndexSignatures.numericSignature;
                var isNumericIndexer = numberIndexSignature === signature;

                if (numberIndexSignature && stringIndexSignature && (isNumericIndexer || stringIndexSignature.getDeclarations()[0].getParentDecl() !== numberIndexSignature.getDeclarations()[0].getParentDecl())) {
                    var comparisonInfo = new TypeComparisonInfo();

                    if (!_this.sourceIsAssignableToTarget(numberIndexSignature.returnType, stringIndexSignature.returnType, funcDeclAST, context, comparisonInfo)) {
                        var enclosingSymbol = _this.getEnclosingSymbolForAST(funcDeclAST);
                        if (comparisonInfo.message) {
                            context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Numeric_indexer_type_0_must_be_assignable_to_string_indexer_type_1_NL_2, [numberIndexSignature.returnType.toString(enclosingSymbol), stringIndexSignature.returnType.toString(enclosingSymbol), comparisonInfo.message]));
                        } else {
                            context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Numeric_indexer_type_0_must_be_assignable_to_string_indexer_type_1, [numberIndexSignature.returnType.toString(enclosingSymbol), stringIndexSignature.returnType.toString(enclosingSymbol)]));
                        }
                    }
                }

                var allMembers = parentSymbol.type.getAllMembers(536869887 /* All */, 0 /* all */);
                for (var i = 0; i < allMembers.length; i++) {
                    var member = allMembers[i];
                    var name = member.name;
                    if (name || (member.kind === 4096 /* Property */ && name === "")) {
                        if (!allMembers[i].isResolved) {
                            _this.resolveDeclaredSymbol(allMembers[i], context);
                        }

                        if (parentSymbol !== allMembers[i].getContainer()) {
                            var isMemberNumeric = TypeScript.PullHelpers.isNameNumeric(name);
                            var indexerKindMatchesMemberNameKind = isNumericIndexer === isMemberNumeric;
                            var onlyStringIndexerIsPresent = !numberIndexSignature;

                            if (indexerKindMatchesMemberNameKind || onlyStringIndexerIsPresent) {
                                var comparisonInfo = new TypeComparisonInfo();
                                if (!_this.sourceIsAssignableToTarget(allMembers[i].type, signature.returnType, funcDeclAST, context, comparisonInfo, false)) {
                                    _this.reportErrorThatMemberIsNotSubtypeOfIndexer(allMembers[i], signature, funcDeclAST, context, comparisonInfo);
                                }
                            }
                        }
                    }
                }
            });
        };

        PullTypeResolver.prototype.postTypeCheckFunctionDeclaration = function (funcDeclAST, context) {
            this.checkThisCaptureVariableCollides(funcDeclAST, true, context);
        };

        PullTypeResolver.prototype.resolveReturnTypeAnnotationOfFunctionDeclaration = function (funcDeclAST, returnTypeAnnotation, context) {
            var returnTypeSymbol = null;

            if (returnTypeAnnotation) {
                var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

                returnTypeSymbol = this.resolveTypeReference(returnTypeAnnotation, context);

                if (!returnTypeSymbol) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(returnTypeAnnotation, TypeScript.DiagnosticCode.Cannot_resolve_return_type_reference));
                } else {
                    var isConstructor = funcDeclAST.kind() === 137 /* ConstructorDeclaration */ || funcDeclAST.kind() === 143 /* ConstructSignature */;
                    if (isConstructor && returnTypeSymbol === this.semanticInfoChain.voidTypeSymbol) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Constructors_cannot_have_a_return_type_of_void));
                    }
                }
            }

            return returnTypeSymbol;
        };

        PullTypeResolver.prototype.resolveMemberFunctionDeclaration = function (funcDecl, context) {
            return this.resolveFunctionDeclaration(funcDecl, TypeScript.hasModifier(funcDecl.modifiers, 16 /* Static */), funcDecl.propertyName, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), funcDecl.block, context);
        };

        PullTypeResolver.prototype.resolveCallSignature = function (funcDecl, context) {
            return this.resolveFunctionDeclaration(funcDecl, false, null, funcDecl.typeParameterList, funcDecl.parameterList, TypeScript.ASTHelpers.getType(funcDecl), null, context);
        };

        PullTypeResolver.prototype.resolveConstructSignature = function (funcDecl, context) {
            return this.resolveFunctionDeclaration(funcDecl, false, null, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), null, context);
        };

        PullTypeResolver.prototype.resolveMethodSignature = function (funcDecl, context) {
            return this.resolveFunctionDeclaration(funcDecl, false, funcDecl.propertyName, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), null, context);
        };

        PullTypeResolver.prototype.resolveAnyFunctionDeclaration = function (funcDecl, context) {
            return this.resolveFunctionDeclaration(funcDecl, TypeScript.hasModifier(funcDecl.modifiers, 16 /* Static */), funcDecl.identifier, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), funcDecl.block, context);
        };

        PullTypeResolver.prototype.resolveFunctionExpression = function (funcDecl, isContextuallyTyped, context) {
            return this.resolveAnyFunctionExpression(funcDecl, funcDecl.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList), TypeScript.ASTHelpers.getType(funcDecl), funcDecl.block, null, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.resolveSimpleArrowFunctionExpression = function (funcDecl, isContextuallyTyped, context) {
            return this.resolveAnyFunctionExpression(funcDecl, null, TypeScript.ASTHelpers.parametersFromIdentifier(funcDecl.identifier), null, funcDecl.block, funcDecl.expression, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.resolveParenthesizedArrowFunctionExpression = function (funcDecl, isContextuallyTyped, context) {
            return this.resolveAnyFunctionExpression(funcDecl, funcDecl.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList), TypeScript.ASTHelpers.getType(funcDecl), funcDecl.block, funcDecl.expression, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.getEnclosingClassDeclaration = function (ast) {
            while (ast) {
                if (ast.kind() === 131 /* ClassDeclaration */) {
                    return ast;
                }

                ast = ast.parent;
            }

            return null;
        };

        PullTypeResolver.prototype.resolveConstructorDeclaration = function (funcDeclAST, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            var funcSymbol = funcDecl.getSymbol();

            var signature = funcDecl.getSignatureSymbol();

            var hadError = false;

            if (signature) {
                if (signature.isResolved) {
                    if (this.canTypeCheckAST(funcDeclAST, context)) {
                        this.typeCheckConstructorDeclaration(funcDeclAST, context);
                    }
                    return funcSymbol;
                }

                if (!signature.inResolution) {
                    var classAST = this.getEnclosingClassDeclaration(funcDeclAST);

                    if (classAST) {
                        var classDecl = this.semanticInfoChain.getDeclForAST(classAST);
                        var classSymbol = classDecl.getSymbol();

                        if (!classSymbol.isResolved && !classSymbol.inResolution) {
                            this.resolveDeclaredSymbol(classSymbol, context);
                        }
                    }
                }

                var functionTypeSymbol = funcSymbol && funcSymbol.type;

                if (signature.inResolution) {
                    signature.returnType = this.semanticInfoChain.anyTypeSymbol;

                    if (funcSymbol) {
                        funcSymbol.setUnresolved();
                        if (funcSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                            funcSymbol.type = functionTypeSymbol;
                        }
                    }
                    signature.setResolved();
                    return funcSymbol;
                }

                if (funcSymbol) {
                    funcSymbol.startResolving();
                }
                signature.startResolving();

                var prevInTypeCheck = context.inTypeCheck;

                context.inTypeCheck = false;

                for (var i = 0; i < funcDeclAST.callSignature.parameterList.parameters.nonSeparatorCount(); i++) {
                    this.resolveParameter(funcDeclAST.callSignature.parameterList.parameters.nonSeparatorAt(i), context);
                }

                context.inTypeCheck = prevInTypeCheck;

                if (signature.isGeneric()) {
                    if (funcSymbol) {
                        funcSymbol.type.setHasGenericSignature();
                    }
                }

                if (!hadError) {
                    if (funcSymbol) {
                        funcSymbol.setUnresolved();
                        if (funcSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                            funcSymbol.type = functionTypeSymbol;
                        }
                    }
                    signature.setResolved();
                }
            }

            if (funcSymbol) {
                this.resolveOtherDeclarations(funcDeclAST, context);
            }

            if (this.canTypeCheckAST(funcDeclAST, context)) {
                this.typeCheckConstructorDeclaration(funcDeclAST, context);
            }

            return funcSymbol;
        };

        PullTypeResolver.prototype.resolveIndexMemberDeclaration = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);
            }

            return this.resolveIndexSignature(ast.indexSignature, context);
        };

        PullTypeResolver.prototype.resolveIndexSignature = function (funcDeclAST, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            var funcSymbol = funcDecl.getSymbol();

            var signature = funcDecl.getSignatureSymbol();

            var hadError = false;

            if (signature) {
                if (signature.isResolved) {
                    if (this.canTypeCheckAST(funcDeclAST, context)) {
                        this.typeCheckIndexSignature(funcDeclAST, context);
                    }
                    return funcSymbol;
                }

                var functionTypeSymbol = funcSymbol && funcSymbol.type;

                if (signature.inResolution) {
                    if (funcDeclAST.typeAnnotation) {
                        var returnTypeSymbol = this.resolveTypeReference(TypeScript.ASTHelpers.getType(funcDeclAST), context);
                        if (!returnTypeSymbol) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(TypeScript.ASTHelpers.getType(funcDeclAST), TypeScript.DiagnosticCode.Cannot_resolve_return_type_reference));
                            signature.returnType = this.getNewErrorTypeSymbol();
                            hadError = true;
                        } else {
                            signature.returnType = returnTypeSymbol;
                        }
                    } else {
                        signature.returnType = this.semanticInfoChain.anyTypeSymbol;
                    }

                    if (funcSymbol) {
                        funcSymbol.setUnresolved();
                        if (funcSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                            funcSymbol.type = functionTypeSymbol;
                        }
                    }
                    signature.setResolved();
                    return funcSymbol;
                }

                if (funcSymbol) {
                    funcSymbol.startResolving();
                }
                signature.startResolving();

                if (funcDeclAST.parameter) {
                    var prevInTypeCheck = context.inTypeCheck;

                    context.inTypeCheck = false;
                    this.resolveParameter(funcDeclAST.parameter, context);
                    context.inTypeCheck = prevInTypeCheck;
                }

                if (funcDeclAST.typeAnnotation) {
                    returnTypeSymbol = this.resolveReturnTypeAnnotationOfFunctionDeclaration(funcDeclAST, TypeScript.ASTHelpers.getType(funcDeclAST), context);

                    if (!returnTypeSymbol) {
                        signature.returnType = this.getNewErrorTypeSymbol();
                        hadError = true;
                    } else {
                        signature.returnType = returnTypeSymbol;
                    }
                } else {
                    signature.returnType = this.semanticInfoChain.anyTypeSymbol;
                }

                if (!hadError) {
                    if (funcSymbol) {
                        funcSymbol.setUnresolved();
                        if (funcSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                            funcSymbol.type = functionTypeSymbol;
                        }
                    }
                    signature.setResolved();
                }
            }

            if (funcSymbol) {
                this.resolveOtherDeclarations(funcDeclAST, context);
            }

            if (this.canTypeCheckAST(funcDeclAST, context)) {
                this.typeCheckIndexSignature(funcDeclAST, context);
            }

            return funcSymbol;
        };

        PullTypeResolver.prototype.resolveFunctionDeclaration = function (funcDeclAST, isStatic, name, typeParameters, parameterList, returnTypeAnnotation, block, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            var funcSymbol = funcDecl.getSymbol();

            var signature = funcDecl.getSignatureSymbol();

            var hadError = false;

            var isConstructor = funcDeclAST.kind() === 143 /* ConstructSignature */;

            if (signature) {
                if (signature.isResolved) {
                    if (this.canTypeCheckAST(funcDeclAST, context)) {
                        this.typeCheckAnyFunctionDeclaration(funcDeclAST, isStatic, name, typeParameters, parameterList, returnTypeAnnotation, block, context);
                    }
                    return funcSymbol;
                }

                if (isConstructor && !signature.inResolution) {
                    var classAST = this.getEnclosingClassDeclaration(funcDeclAST);

                    if (classAST) {
                        var classDecl = this.semanticInfoChain.getDeclForAST(classAST);
                        var classSymbol = classDecl.getSymbol();

                        if (!classSymbol.isResolved && !classSymbol.inResolution) {
                            this.resolveDeclaredSymbol(classSymbol, context);
                        }
                    }
                }

                var functionTypeSymbol = funcSymbol && funcSymbol.type;

                if (signature.inResolution) {
                    if (returnTypeAnnotation) {
                        var returnTypeSymbol = this.resolveTypeReference(returnTypeAnnotation, context);
                        if (!returnTypeSymbol) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(returnTypeAnnotation, TypeScript.DiagnosticCode.Cannot_resolve_return_type_reference));
                            signature.returnType = this.getNewErrorTypeSymbol();
                            hadError = true;
                        } else {
                            signature.returnType = returnTypeSymbol;

                            if (isConstructor && returnTypeSymbol === this.semanticInfoChain.voidTypeSymbol) {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Constructors_cannot_have_a_return_type_of_void));
                            }
                        }
                    } else {
                        signature.returnType = this.semanticInfoChain.anyTypeSymbol;
                    }

                    if (funcSymbol) {
                        funcSymbol.setUnresolved();
                        if (funcSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                            funcSymbol.type = functionTypeSymbol;
                        }
                    }
                    signature.setResolved();
                    return funcSymbol;
                }

                if (funcSymbol) {
                    funcSymbol.startResolving();
                }
                signature.startResolving();

                if (typeParameters) {
                    for (var i = 0; i < typeParameters.typeParameters.nonSeparatorCount(); i++) {
                        this.resolveTypeParameterDeclaration(typeParameters.typeParameters.nonSeparatorAt(i), context);
                    }
                }

                if (parameterList) {
                    var prevInTypeCheck = context.inTypeCheck;

                    context.inTypeCheck = false;

                    for (var i = 0; i < parameterList.parameters.nonSeparatorCount(); i++) {
                        this.resolveParameter(parameterList.parameters.nonSeparatorAt(i), context);
                    }

                    context.inTypeCheck = prevInTypeCheck;
                }

                if (returnTypeAnnotation) {
                    returnTypeSymbol = this.resolveReturnTypeAnnotationOfFunctionDeclaration(funcDeclAST, returnTypeAnnotation, context);

                    if (!returnTypeSymbol) {
                        signature.returnType = this.getNewErrorTypeSymbol();
                        hadError = true;
                    } else {
                        signature.returnType = returnTypeSymbol;
                    }
                } else if (funcDecl.kind !== 2097152 /* ConstructSignature */) {
                    if (TypeScript.hasFlag(funcDecl.flags, 2048 /* Signature */)) {
                        signature.returnType = this.semanticInfoChain.anyTypeSymbol;
                        var parentDeclFlags = 0 /* None */;
                        if (TypeScript.hasFlag(funcDecl.kind, 65536 /* Method */) || TypeScript.hasFlag(funcDecl.kind, 32768 /* ConstructorMethod */)) {
                            var parentDecl = funcDecl.getParentDecl();
                            parentDeclFlags = parentDecl.flags;
                        }

                        if (this.compilationSettings.noImplicitAny() && (!TypeScript.hasFlag(parentDeclFlags, 8 /* Ambient */) || (TypeScript.hasFlag(parentDeclFlags, 8 /* Ambient */) && !TypeScript.hasFlag(funcDecl.flags, 2 /* Private */)))) {
                            var funcDeclASTName = name;
                            if (funcDeclASTName) {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode._0_which_lacks_return_type_annotation_implicitly_has_an_any_return_type, [funcDeclASTName.text()]));
                            } else {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Lambda_Function_which_lacks_return_type_annotation_implicitly_has_an_any_return_type));
                            }
                        }
                    } else {
                        this.resolveFunctionBodyReturnTypes(funcDeclAST, block, null, signature, false, funcDecl, context);
                    }
                } else if (funcDecl.kind === 2097152 /* ConstructSignature */) {
                    signature.returnType = this.semanticInfoChain.anyTypeSymbol;

                    if (this.compilationSettings.noImplicitAny()) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Constructor_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type));
                    }
                }

                if (!hadError) {
                    if (funcSymbol) {
                        funcSymbol.setUnresolved();
                        if (funcSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                            funcSymbol.type = functionTypeSymbol;
                        }
                    }
                    signature.setResolved();
                }
            }

            if (funcSymbol) {
                this.resolveOtherDeclarations(funcDeclAST, context);
            }

            if (this.canTypeCheckAST(funcDeclAST, context)) {
                this.typeCheckAnyFunctionDeclaration(funcDeclAST, isStatic, name, typeParameters, parameterList, returnTypeAnnotation, block, context);
            }

            return funcSymbol;
        };

        PullTypeResolver.prototype.resolveGetterReturnTypeAnnotation = function (getterFunctionDeclarationAst, enclosingDecl, context) {
            if (getterFunctionDeclarationAst && getterFunctionDeclarationAst.typeAnnotation) {
                return this.resolveTypeReference(TypeScript.ASTHelpers.getType(getterFunctionDeclarationAst), context);
            }

            return null;
        };

        PullTypeResolver.prototype.resolveSetterArgumentTypeAnnotation = function (setterFunctionDeclarationAst, enclosingDecl, context) {
            if (setterFunctionDeclarationAst && setterFunctionDeclarationAst.parameterList && setterFunctionDeclarationAst.parameterList.parameters.nonSeparatorCount() > 0) {
                var parameter = setterFunctionDeclarationAst.parameterList.parameters.nonSeparatorAt(0);
                return this.resolveTypeReference(TypeScript.ASTHelpers.getType(parameter), context);
            }

            return null;
        };

        PullTypeResolver.prototype.resolveAccessorDeclaration = function (funcDeclAst, context) {
            var functionDeclaration = this.semanticInfoChain.getDeclForAST(funcDeclAst);
            var accessorSymbol = functionDeclaration.getSymbol();

            if (accessorSymbol.inResolution) {
                accessorSymbol.type = this.semanticInfoChain.anyTypeSymbol;
                accessorSymbol.setResolved();

                return accessorSymbol;
            }

            if (accessorSymbol.isResolved) {
                if (!accessorSymbol.type) {
                    accessorSymbol.type = this.semanticInfoChain.anyTypeSymbol;
                }
            } else {
                var getterSymbol = accessorSymbol.getGetter();
                var getterFunctionDeclarationAst = getterSymbol ? getterSymbol.getDeclarations()[0].ast() : null;
                var hasGetter = getterSymbol !== null;

                var setterSymbol = accessorSymbol.getSetter();
                var setterFunctionDeclarationAst = setterSymbol ? setterSymbol.getDeclarations()[0].ast() : null;
                var hasSetter = setterSymbol !== null;

                var getterAnnotatedType = this.resolveGetterReturnTypeAnnotation(getterFunctionDeclarationAst, functionDeclaration, context);
                var getterHasTypeAnnotation = getterAnnotatedType !== null;

                var setterAnnotatedType = this.resolveSetterArgumentTypeAnnotation(setterFunctionDeclarationAst, functionDeclaration, context);
                var setterHasTypeAnnotation = setterAnnotatedType !== null;

                accessorSymbol.startResolving();

                if (hasGetter) {
                    getterSymbol = this.resolveGetAccessorDeclaration(getterFunctionDeclarationAst, getterFunctionDeclarationAst.parameterList, TypeScript.ASTHelpers.getType(getterFunctionDeclarationAst), getterFunctionDeclarationAst.block, setterAnnotatedType, context);
                }

                if (hasSetter) {
                    setterSymbol = this.resolveSetAccessorDeclaration(setterFunctionDeclarationAst, setterFunctionDeclarationAst.parameterList, context);
                }

                if (hasGetter && hasSetter) {
                    var setterSig = setterSymbol.type.getCallSignatures()[0];
                    var setterParameters = setterSig.parameters;
                    var setterHasParameters = setterParameters.length > 0;
                    var getterSig = getterSymbol.type.getCallSignatures()[0];

                    var setterSuppliedTypeSymbol = setterHasParameters ? setterParameters[0].type : null;
                    var getterSuppliedTypeSymbol = getterSig.returnType;

                    if (setterHasTypeAnnotation && !getterHasTypeAnnotation) {
                        getterSuppliedTypeSymbol = setterSuppliedTypeSymbol;
                        getterSig.returnType = setterSuppliedTypeSymbol;
                    } else if ((getterHasTypeAnnotation && !setterHasTypeAnnotation) || (!getterHasTypeAnnotation && !setterHasTypeAnnotation)) {
                        setterSuppliedTypeSymbol = getterSuppliedTypeSymbol;

                        if (setterHasParameters) {
                            setterParameters[0].type = getterSuppliedTypeSymbol;
                        }
                    }

                    if (!this.typesAreIdentical(setterSuppliedTypeSymbol, getterSuppliedTypeSymbol, context)) {
                        accessorSymbol.type = this.getNewErrorTypeSymbol();
                    } else {
                        accessorSymbol.type = getterSuppliedTypeSymbol;
                    }
                } else if (hasSetter) {
                    var setterSig = setterSymbol.type.getCallSignatures()[0];
                    var setterParameters = setterSig.parameters;
                    var setterHasParameters = setterParameters.length > 0;

                    accessorSymbol.type = setterHasParameters ? setterParameters[0].type : this.semanticInfoChain.anyTypeSymbol;
                } else {
                    var getterSig = getterSymbol.type.getCallSignatures()[0];
                    accessorSymbol.type = getterSig.returnType;
                }

                accessorSymbol.setResolved();
            }

            if (this.canTypeCheckAST(funcDeclAst, context)) {
                this.typeCheckAccessorDeclaration(funcDeclAst, context);
            }

            return accessorSymbol;
        };

        PullTypeResolver.prototype.typeCheckAccessorDeclaration = function (funcDeclAst, context) {
            this.setTypeChecked(funcDeclAst, context);
            var functionDeclaration = this.semanticInfoChain.getDeclForAST(funcDeclAst);
            var accessorSymbol = functionDeclaration.getSymbol();
            var getterSymbol = accessorSymbol.getGetter();
            var setterSymbol = accessorSymbol.getSetter();

            var isGetter = funcDeclAst.kind() === 139 /* GetAccessor */;
            if (isGetter) {
                var getterFunctionDeclarationAst = funcDeclAst;
                context.pushNewContextualType(getterSymbol.type);
                this.typeCheckGetAccessorDeclaration(getterFunctionDeclarationAst, context);
                context.popAnyContextualType();
            } else {
                var setterFunctionDeclarationAst = funcDeclAst;
                this.typeCheckSetAccessorDeclaration(setterFunctionDeclarationAst, context);
            }
        };

        PullTypeResolver.prototype.resolveGetAccessorDeclaration = function (funcDeclAST, parameters, returnTypeAnnotation, block, setterAnnotatedType, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            var accessorSymbol = funcDecl.getSymbol();

            var getterSymbol = accessorSymbol.getGetter();
            var getterTypeSymbol = getterSymbol.type;

            var signature = getterTypeSymbol.getCallSignatures()[0];

            var hadError = false;

            if (signature) {
                if (signature.isResolved) {
                    return getterSymbol;
                }

                if (signature.inResolution) {
                    signature.returnType = this.semanticInfoChain.anyTypeSymbol;
                    signature.setResolved();

                    return getterSymbol;
                }

                signature.startResolving();

                if (returnTypeAnnotation) {
                    var returnTypeSymbol = this.resolveReturnTypeAnnotationOfFunctionDeclaration(funcDeclAST, returnTypeAnnotation, context);

                    if (!returnTypeSymbol) {
                        signature.returnType = this.getNewErrorTypeSymbol();

                        hadError = true;
                    } else {
                        signature.returnType = returnTypeSymbol;
                    }
                } else {
                    if (!setterAnnotatedType) {
                        this.resolveFunctionBodyReturnTypes(funcDeclAST, block, null, signature, false, funcDecl, context);
                    } else {
                        signature.returnType = setterAnnotatedType;
                    }
                }

                if (!hadError) {
                    signature.setResolved();
                }
            }

            return getterSymbol;
        };

        PullTypeResolver.prototype.checkIfGetterAndSetterTypeMatch = function (funcDeclAST, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            var accessorSymbol = funcDecl.getSymbol();
            var getter = accessorSymbol.getGetter();
            var setter = accessorSymbol.getSetter();

            if (getter && setter) {
                var getterAST = getter.getDeclarations()[0].ast();
                var setterAST = setter.getDeclarations()[0].ast();

                if (getterAST.typeAnnotation && PullTypeResolver.hasSetAccessorParameterTypeAnnotation(setterAST)) {
                    var setterSig = setter.type.getCallSignatures()[0];
                    var setterParameters = setterSig.parameters;

                    var getter = accessorSymbol.getGetter();
                    var getterSig = getter.type.getCallSignatures()[0];

                    var setterSuppliedTypeSymbol = setterParameters[0].type;
                    var getterSuppliedTypeSymbol = getterSig.returnType;

                    if (!this.typesAreIdentical(setterSuppliedTypeSymbol, getterSuppliedTypeSymbol, context)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.get_and_set_accessor_must_have_the_same_type));
                    }
                }
            }
        };

        PullTypeResolver.prototype.typeCheckGetAccessorDeclaration = function (funcDeclAST, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            var accessorSymbol = funcDecl.getSymbol();

            this.resolveReturnTypeAnnotationOfFunctionDeclaration(funcDeclAST, TypeScript.ASTHelpers.getType(funcDeclAST), context);

            this.resolveAST(funcDeclAST.block, false, context);

            this.validateVariableDeclarationGroups(funcDecl, context);

            var enclosingDecl = this.getEnclosingDecl(funcDecl);

            var hasReturn = (funcDecl.flags & (2048 /* Signature */ | 4194304 /* HasReturnStatement */)) !== 0;
            var funcNameAST = funcDeclAST.propertyName;

            if (!hasReturn && !this.containsSingleThrowStatement(funcDeclAST.block)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcNameAST, TypeScript.DiagnosticCode.Getters_must_return_a_value));
            }

            var setter = accessorSymbol.getSetter();
            if (setter) {
                var setterDecl = setter.getDeclarations()[0];
                var setterIsPrivate = TypeScript.hasFlag(setterDecl.flags, 2 /* Private */);
                var getterIsPrivate = TypeScript.hasModifier(funcDeclAST.modifiers, 2 /* Private */);

                if (getterIsPrivate !== setterIsPrivate) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcNameAST, TypeScript.DiagnosticCode.Getter_and_setter_accessors_do_not_agree_in_visibility));
                }

                this.checkIfGetterAndSetterTypeMatch(funcDeclAST, context);
            }

            this.checkFunctionTypePrivacy(funcDeclAST, TypeScript.hasModifier(funcDeclAST.modifiers, 16 /* Static */), null, TypeScript.ASTHelpers.parametersFromParameterList(funcDeclAST.parameterList), TypeScript.ASTHelpers.getType(funcDeclAST), funcDeclAST.block, context);
        };

        PullTypeResolver.hasSetAccessorParameterTypeAnnotation = function (setAccessor) {
            return setAccessor.parameterList && setAccessor.parameterList.parameters.nonSeparatorCount() > 0 && setAccessor.parameterList.parameters.nonSeparatorAt(0).typeAnnotation !== null;
        };

        PullTypeResolver.prototype.resolveSetAccessorDeclaration = function (funcDeclAST, parameterList, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            var accessorSymbol = funcDecl.getSymbol();

            var setterSymbol = accessorSymbol.getSetter();
            var setterTypeSymbol = setterSymbol.type;

            var signature = funcDecl.getSignatureSymbol();

            var hadError = false;

            if (signature) {
                if (signature.isResolved) {
                    return setterSymbol;
                }

                if (signature.inResolution) {
                    signature.returnType = this.semanticInfoChain.voidTypeSymbol;
                    signature.setResolved();
                    return setterSymbol;
                }

                signature.startResolving();

                if (parameterList) {
                    for (var i = 0; i < parameterList.parameters.nonSeparatorCount(); i++) {
                        this.resolveParameter(parameterList.parameters.nonSeparatorAt(i), context);
                    }
                }

                signature.returnType = this.semanticInfoChain.voidTypeSymbol;

                if (!hadError) {
                    signature.setResolved();
                }
            }

            return setterSymbol;
        };

        PullTypeResolver.prototype.typeCheckSetAccessorDeclaration = function (funcDeclAST, context) {
            var funcDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            var accessorSymbol = funcDecl.getSymbol();

            if (funcDeclAST.parameterList) {
                for (var i = 0; i < funcDeclAST.parameterList.parameters.nonSeparatorCount(); i++) {
                    this.resolveParameter(funcDeclAST.parameterList.parameters.nonSeparatorAt(i), context);
                }
            }

            this.resolveAST(funcDeclAST.block, false, context);

            this.validateVariableDeclarationGroups(funcDecl, context);

            var hasReturn = (funcDecl.flags & (2048 /* Signature */ | 4194304 /* HasReturnStatement */)) !== 0;

            var getter = accessorSymbol.getGetter();

            var funcNameAST = funcDeclAST.propertyName;

            if (getter) {
                var getterDecl = getter.getDeclarations()[0];
                var getterIsPrivate = TypeScript.hasFlag(getterDecl.flags, 2 /* Private */);
                var setterIsPrivate = TypeScript.hasModifier(funcDeclAST.modifiers, 2 /* Private */);

                if (getterIsPrivate !== setterIsPrivate) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcNameAST, TypeScript.DiagnosticCode.Getter_and_setter_accessors_do_not_agree_in_visibility));
                }

                this.checkIfGetterAndSetterTypeMatch(funcDeclAST, context);
            } else {
                if (this.compilationSettings.noImplicitAny()) {
                    var setterFunctionDeclarationAst = funcDeclAST;
                    if (!PullTypeResolver.hasSetAccessorParameterTypeAnnotation(setterFunctionDeclarationAst) && accessorSymbol.type === this.semanticInfoChain.anyTypeSymbol) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode._0_which_lacks_get_accessor_and_parameter_type_annotation_on_set_accessor_implicitly_has_an_any_type, [setterFunctionDeclarationAst.propertyName.text()]));
                    }
                }
            }

            this.checkFunctionTypePrivacy(funcDeclAST, TypeScript.hasModifier(funcDeclAST.modifiers, 16 /* Static */), null, TypeScript.ASTHelpers.parametersFromParameterList(funcDeclAST.parameterList), null, funcDeclAST.block, context);
        };

        PullTypeResolver.prototype.resolveList = function (list, context) {
            if (this.canTypeCheckAST(list, context)) {
                this.setTypeChecked(list, context);

                for (var i = 0, n = list.childCount(); i < n; i++) {
                    this.resolveAST(list.childAt(i), false, context);
                }
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveSeparatedList = function (list, context) {
            if (this.canTypeCheckAST(list, context)) {
                this.setTypeChecked(list, context);

                for (var i = 0, n = list.nonSeparatorCount(); i < n; i++) {
                    this.resolveAST(list.nonSeparatorAt(i), false, context);
                }
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveVoidExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);

                this.resolveAST(ast.expression, false, context);
            }

            return this.semanticInfoChain.undefinedTypeSymbol;
        };

        PullTypeResolver.prototype.resolveLogicalOperation = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckLogicalOperation(ast, context);
            }

            return this.semanticInfoChain.booleanTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckLogicalOperation = function (binex, context) {
            this.setTypeChecked(binex, context);

            var leftType = this.resolveAST(binex.left, false, context).type;
            var rightType = this.resolveAST(binex.right, false, context).type;

            var comparisonInfo = new TypeComparisonInfo();
            if (!this.sourceIsAssignableToTarget(leftType, rightType, binex, context, comparisonInfo) && !this.sourceIsAssignableToTarget(rightType, leftType, binex, context, comparisonInfo)) {
                var enclosingSymbol = this.getEnclosingSymbolForAST(binex);
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binex, TypeScript.DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2, [
                    TypeScript.SyntaxFacts.getText(TypeScript.SyntaxFacts.getOperatorTokenFromBinaryExpression(binex.kind())),
                    leftType.toString(enclosingSymbol), rightType.toString(enclosingSymbol)]));
            }
        };

        PullTypeResolver.prototype.resolveLogicalNotExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);

                this.resolveAST(ast.operand, false, context);
            }

            return this.semanticInfoChain.booleanTypeSymbol;
        };

        PullTypeResolver.prototype.resolveUnaryArithmeticOperation = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckUnaryArithmeticOperation(ast, context);
            }

            return this.semanticInfoChain.numberTypeSymbol;
        };

        PullTypeResolver.prototype.resolvePostfixUnaryExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckPostfixUnaryExpression(ast, context);
            }

            return this.semanticInfoChain.numberTypeSymbol;
        };

        PullTypeResolver.prototype.isAnyOrNumberOrEnum = function (type) {
            return this.isAnyOrEquivalent(type) || type === this.semanticInfoChain.numberTypeSymbol || TypeScript.PullHelpers.symbolIsEnum(type);
        };

        PullTypeResolver.prototype.typeCheckUnaryArithmeticOperation = function (unaryExpression, context) {
            this.setTypeChecked(unaryExpression, context);

            var nodeType = unaryExpression.kind();
            var expression = this.resolveAST(unaryExpression.operand, false, context);

            if (nodeType === 164 /* PlusExpression */ || nodeType == 165 /* NegateExpression */ || nodeType == 166 /* BitwiseNotExpression */) {
                return;
            }

            TypeScript.Debug.assert(nodeType === 168 /* PreIncrementExpression */ || nodeType === 169 /* PreDecrementExpression */);

            var operandType = expression.type;
            if (!this.isAnyOrNumberOrEnum(operandType)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(unaryExpression.operand, TypeScript.DiagnosticCode.The_type_of_a_unary_arithmetic_operation_operand_must_be_of_type_any_number_or_an_enum_type));
            }

            if (!this.isReference(unaryExpression.operand, expression)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(unaryExpression.operand, TypeScript.DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer));
            }
        };

        PullTypeResolver.prototype.typeCheckPostfixUnaryExpression = function (unaryExpression, context) {
            this.setTypeChecked(unaryExpression, context);

            var nodeType = unaryExpression.kind();
            var expression = this.resolveAST(unaryExpression.operand, false, context);

            TypeScript.Debug.assert(nodeType === 210 /* PostIncrementExpression */ || nodeType === 211 /* PostDecrementExpression */);

            var operandType = expression.type;
            if (!this.isAnyOrNumberOrEnum(operandType)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(unaryExpression.operand, TypeScript.DiagnosticCode.The_type_of_a_unary_arithmetic_operation_operand_must_be_of_type_any_number_or_an_enum_type));
            }

            if (!this.isReference(unaryExpression.operand, expression)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(unaryExpression.operand, TypeScript.DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer));
            }
        };

        PullTypeResolver.prototype.resolveBinaryArithmeticExpression = function (binaryExpression, context) {
            if (this.canTypeCheckAST(binaryExpression, context)) {
                this.typeCheckBinaryArithmeticExpression(binaryExpression, context);
            }

            return this.semanticInfoChain.numberTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckBinaryArithmeticExpression = function (binaryExpression, context) {
            this.setTypeChecked(binaryExpression, context);

            var lhsSymbol = this.resolveAST(binaryExpression.left, false, context);

            var lhsType = lhsSymbol.type;
            var rhsType = this.resolveAST(binaryExpression.right, false, context).type;

            if (lhsType === this.semanticInfoChain.nullTypeSymbol || lhsType === this.semanticInfoChain.undefinedTypeSymbol) {
                lhsType = rhsType;
            }

            if (rhsType === this.semanticInfoChain.nullTypeSymbol || rhsType === this.semanticInfoChain.undefinedTypeSymbol) {
                rhsType = lhsType;
            }

            var lhsIsFit = this.isAnyOrNumberOrEnum(lhsType);
            var rhsIsFit = this.isAnyOrNumberOrEnum(rhsType);

            if (!rhsIsFit) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.right, TypeScript.DiagnosticCode.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type));
            }

            if (!lhsIsFit) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type));
            }

            if (lhsIsFit && rhsIsFit) {
                switch (binaryExpression.kind()) {
                    case 183 /* LeftShiftAssignmentExpression */:
                    case 184 /* SignedRightShiftAssignmentExpression */:
                    case 185 /* UnsignedRightShiftAssignmentExpression */:
                    case 176 /* SubtractAssignmentExpression */:
                    case 177 /* MultiplyAssignmentExpression */:
                    case 178 /* DivideAssignmentExpression */:
                    case 179 /* ModuloAssignmentExpression */:
                    case 182 /* OrAssignmentExpression */:
                    case 180 /* AndAssignmentExpression */:
                    case 181 /* ExclusiveOrAssignmentExpression */:
                        if (!this.isReference(binaryExpression.left, lhsSymbol)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.Invalid_left_hand_side_of_assignment_expression));
                        }

                        this.checkAssignability(binaryExpression.left, rhsType, lhsType, context);
                }
            }
        };

        PullTypeResolver.prototype.resolveTypeOfExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);

                this.resolveAST(ast.expression, false, context);
            }

            return this.semanticInfoChain.stringTypeSymbol;
        };

        PullTypeResolver.prototype.resolveThrowStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);

                this.resolveAST(ast.expression, false, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveDeleteExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);
                this.resolveAST(ast.expression, false, context);
            }

            return this.semanticInfoChain.booleanTypeSymbol;
        };

        PullTypeResolver.prototype.resolveInstanceOfExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckInstanceOfExpression(ast, context);
            }

            return this.semanticInfoChain.booleanTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckInstanceOfExpression = function (binaryExpression, context) {
            this.setTypeChecked(binaryExpression, context);

            var lhsType = this.resolveAST(binaryExpression.left, false, context).type;
            var rhsType = this.resolveAST(binaryExpression.right, false, context).type;

            var enclosingSymbol = this.getEnclosingSymbolForAST(binaryExpression);
            var isValidLHS = this.isAnyOrEquivalent(lhsType) || lhsType.isObject() || lhsType.isTypeParameter();
            var isValidRHS = this.isAnyOrEquivalent(rhsType) || this.typeIsAssignableToFunction(rhsType, binaryExpression, context);

            if (!isValidLHS) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter));
            }

            if (!isValidRHS) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.right, TypeScript.DiagnosticCode.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type));
            }
        };

        PullTypeResolver.prototype.resolveCommaExpression = function (commaExpression, context) {
            if (this.canTypeCheckAST(commaExpression, context)) {
                this.setTypeChecked(commaExpression, context);

                this.resolveAST(commaExpression.left, false, context);
            }

            return this.resolveAST(commaExpression.right, false, context).type;
        };

        PullTypeResolver.prototype.resolveInExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckInExpression(ast, context);
            }

            return this.semanticInfoChain.booleanTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckInExpression = function (binaryExpression, context) {
            this.setTypeChecked(binaryExpression, context);

            var lhsType = this.resolveAST(binaryExpression.left, false, context).type;
            var rhsType = this.resolveAST(binaryExpression.right, false, context).type;

            var isValidLHS = this.isAnyOrEquivalent(lhsType.type) || lhsType.type === this.semanticInfoChain.stringTypeSymbol || lhsType.type === this.semanticInfoChain.numberTypeSymbol;

            var isValidRHS = this.isAnyOrEquivalent(rhsType) || rhsType.isObject() || rhsType.isTypeParameter();

            if (!isValidLHS) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number));
            }

            if (!isValidRHS) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.right, TypeScript.DiagnosticCode.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter));
            }
        };

        PullTypeResolver.prototype.resolveForStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);

                this.resolveAST(ast.variableDeclaration, false, context);
                this.resolveAST(ast.initializer, false, context);
                this.resolveAST(ast.condition, false, context);
                this.resolveAST(ast.incrementor, false, context);
                this.resolveAST(ast.statement, false, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveForInStatement = function (forInStatement, context) {
            if (this.canTypeCheckAST(forInStatement, context)) {
                this.typeCheckForInStatement(forInStatement, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckForInStatement = function (forInStatement, context) {
            this.setTypeChecked(forInStatement, context);

            if (forInStatement.variableDeclaration) {
                var declaration = forInStatement.variableDeclaration;

                if (declaration.declarators.nonSeparatorCount() === 1) {
                    var varDecl = declaration.declarators.nonSeparatorAt(0);

                    if (varDecl.typeAnnotation) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(declaration, TypeScript.DiagnosticCode.Variable_declarations_of_a_for_statement_cannot_use_a_type_annotation));
                    }
                }
            } else {
                var varSym = this.resolveAST(forInStatement.left, false, context);
                var isStringOrNumber = varSym.type === this.semanticInfoChain.stringTypeSymbol || this.isAnyOrEquivalent(varSym.type);

                if (!isStringOrNumber) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(forInStatement.left, TypeScript.DiagnosticCode.Variable_declarations_of_a_for_statement_must_be_of_types_string_or_any));
                }
            }

            var rhsType = this.resolveAST(forInStatement.expression, false, context).type;
            var isValidRHS = rhsType && (this.isAnyOrEquivalent(rhsType) || rhsType.isObject() || rhsType.isTypeParameter());

            if (!isValidRHS) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(forInStatement.expression, TypeScript.DiagnosticCode.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter));
            }

            this.resolveAST(forInStatement.statement, false, context);
        };

        PullTypeResolver.prototype.resolveWhileStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckWhileStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckWhileStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            this.resolveAST(ast.condition, false, context);
            this.resolveAST(ast.statement, false, context);
        };

        PullTypeResolver.prototype.resolveDoStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckDoStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckDoStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            this.resolveAST(ast.condition, false, context);
            this.resolveAST(ast.statement, false, context);
        };

        PullTypeResolver.prototype.resolveIfStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckIfStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckIfStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            this.resolveAST(ast.condition, false, context);
            this.resolveAST(ast.statement, false, context);
            this.resolveAST(ast.elseClause, false, context);
        };

        PullTypeResolver.prototype.resolveElseClause = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckElseClause(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckElseClause = function (ast, context) {
            this.setTypeChecked(ast, context);

            this.resolveAST(ast.statement, false, context);
        };

        PullTypeResolver.prototype.resolveBlock = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);
                this.resolveAST(ast.statements, false, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveVariableStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);
                this.resolveAST(ast.declaration, false, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveVariableDeclarationList = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);
                this.resolveAST(ast.declarators, false, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveWithStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckWithStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckWithStatement = function (ast, context) {
            this.setTypeChecked(ast, context);
            var withStatement = ast;
            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(withStatement.condition, TypeScript.DiagnosticCode.All_symbols_within_a_with_block_will_be_resolved_to_any));
        };

        PullTypeResolver.prototype.resolveTryStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckTryStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckTryStatement = function (ast, context) {
            this.setTypeChecked(ast, context);
            var tryStatement = ast;

            this.resolveAST(tryStatement.block, false, context);
            this.resolveAST(tryStatement.catchClause, false, context);
            this.resolveAST(tryStatement.finallyClause, false, context);
        };

        PullTypeResolver.prototype.resolveCatchClause = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckCatchClause(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckCatchClause = function (ast, context) {
            this.setTypeChecked(ast, context);
            this.resolveAST(ast.block, false, context);

            var catchDecl = this.semanticInfoChain.getDeclForAST(ast);
            this.validateVariableDeclarationGroups(catchDecl, context);
        };

        PullTypeResolver.prototype.resolveFinallyClause = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckFinallyClause(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckFinallyClause = function (ast, context) {
            this.setTypeChecked(ast, context);
            this.resolveAST(ast.block, false, context);
        };

        PullTypeResolver.prototype.getEnclosingFunctionDeclaration = function (ast) {
            var enclosingDecl = this.getEnclosingDeclForAST(ast);

            while (enclosingDecl) {
                if (enclosingDecl.kind & 1032192 /* SomeFunction */) {
                    return enclosingDecl;
                }

                enclosingDecl = enclosingDecl.getParentDecl();
            }

            return null;
        };

        PullTypeResolver.prototype.resolveReturnExpression = function (expression, enclosingFunction, context) {
            if (enclosingFunction) {
                enclosingFunction.setFlag(4194304 /* HasReturnStatement */);
            }

            var isContextuallyTyped = false;

            if (enclosingFunction) {
                var enclosingDeclAST = this.getASTForDecl(enclosingFunction);
                var typeAnnotation = TypeScript.ASTHelpers.getType(enclosingDeclAST);
                if (typeAnnotation) {
                    var returnTypeAnnotationSymbol = this.resolveTypeReference(typeAnnotation, context);
                    if (returnTypeAnnotationSymbol) {
                        isContextuallyTyped = true;
                        context.pushNewContextualType(returnTypeAnnotationSymbol);
                    }
                } else {
                    var currentContextualType = context.getContextualType();
                    if (currentContextualType && currentContextualType.isFunction()) {
                        var contextualSignatures = currentContextualType.kind == 33554432 /* ConstructorType */ ? currentContextualType.getConstructSignatures() : currentContextualType.getCallSignatures();
                        var currentContextualTypeSignatureSymbol = contextualSignatures[0];

                        var currentContextualTypeReturnTypeSymbol = currentContextualTypeSignatureSymbol.returnType;
                        if (currentContextualTypeReturnTypeSymbol) {
                            isContextuallyTyped = true;
                            context.propagateContextualType(currentContextualTypeReturnTypeSymbol);
                        }
                    }
                }
            }

            var result = this.resolveAST(expression, isContextuallyTyped, context).type;
            if (isContextuallyTyped) {
                context.popAnyContextualType();
            }

            return result;
        };

        PullTypeResolver.prototype.typeCheckReturnExpression = function (expression, expressionType, enclosingFunction, context) {
            if (enclosingFunction && enclosingFunction.kind === 32768 /* ConstructorMethod */) {
                var classDecl = enclosingFunction.getParentDecl();
                if (classDecl) {
                    var classSymbol = classDecl.getSymbol();
                    this.resolveDeclaredSymbol(classSymbol, context);

                    var comparisonInfo = new TypeComparisonInfo();
                    var isAssignable = this.sourceIsAssignableToTarget(expressionType, classSymbol.type, expression, context, comparisonInfo);
                    if (!isAssignable) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(expression, TypeScript.DiagnosticCode.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class));
                    }
                }
            }

            if (enclosingFunction && enclosingFunction.kind === 524288 /* SetAccessor */) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(expression, TypeScript.DiagnosticCode.Setters_cannot_return_a_value));
            }

            if (enclosingFunction) {
                var enclosingDeclAST = this.getASTForDecl(enclosingFunction);
                var typeAnnotation = TypeScript.ASTHelpers.getType(enclosingDeclAST);
                if (typeAnnotation || enclosingFunction.kind === 262144 /* GetAccessor */) {
                    var signatureSymbol = enclosingFunction.getSignatureSymbol();
                    var sigReturnType = signatureSymbol.returnType;

                    if (expressionType && sigReturnType) {
                        var comparisonInfo = new TypeComparisonInfo();
                        var upperBound = null;

                        this.resolveDeclaredSymbol(expressionType, context);
                        this.resolveDeclaredSymbol(sigReturnType, context);

                        var isAssignable = this.sourceIsAssignableToTarget(expressionType, sigReturnType, expression, context, comparisonInfo);

                        if (!isAssignable) {
                            var enclosingSymbol = this.getEnclosingSymbolForAST(expression);
                            if (comparisonInfo.message) {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(expression, TypeScript.DiagnosticCode.Cannot_convert_0_to_1_NL_2, [expressionType.toString(enclosingSymbol), sigReturnType.toString(enclosingSymbol), comparisonInfo.message]));
                            } else {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(expression, TypeScript.DiagnosticCode.Cannot_convert_0_to_1, [expressionType.toString(enclosingSymbol), sigReturnType.toString(enclosingSymbol)]));
                            }
                        }
                    }
                }
            }
        };

        PullTypeResolver.prototype.resolveReturnStatement = function (returnAST, context) {
            var enclosingFunction = this.getEnclosingFunctionDeclaration(returnAST);
            if (enclosingFunction) {
                enclosingFunction.setFlag(4194304 /* HasReturnStatement */);
            }

            var returnType = this.getSymbolForAST(returnAST, context);
            var canTypeCheckAST = this.canTypeCheckAST(returnAST, context);
            if (!returnType || canTypeCheckAST) {
                var returnExpr = returnAST.expression;

                var resolvedReturnType = returnExpr === null ? this.semanticInfoChain.voidTypeSymbol : this.resolveReturnExpression(returnExpr, enclosingFunction, context);

                if (!returnType) {
                    returnType = resolvedReturnType;
                    this.setSymbolForAST(returnAST, resolvedReturnType, context);
                }

                if (returnExpr && canTypeCheckAST) {
                    this.setTypeChecked(returnExpr, context);
                    this.typeCheckReturnExpression(returnExpr, resolvedReturnType, enclosingFunction, context);
                }
            }

            return returnType;
        };

        PullTypeResolver.prototype.resolveSwitchStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckSwitchStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckSwitchStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            var expressionType = this.resolveAST(ast.expression, false, context).type;

            for (var i = 0, n = ast.switchClauses.childCount(); i < n; i++) {
                var switchClause = ast.switchClauses.childAt(i);
                if (switchClause.kind() === 233 /* CaseSwitchClause */) {
                    var caseSwitchClause = switchClause;

                    var caseClauseExpressionType = this.resolveAST(caseSwitchClause.expression, false, context).type;
                    this.resolveAST(caseSwitchClause.statements, false, context);

                    var comparisonInfo = new TypeComparisonInfo();
                    if (!this.sourceIsAssignableToTarget(expressionType, caseClauseExpressionType, caseSwitchClause.expression, context, comparisonInfo) && !this.sourceIsAssignableToTarget(caseClauseExpressionType, expressionType, caseSwitchClause.expression, context, comparisonInfo)) {
                        var enclosingSymbol = this.getEnclosingSymbolForAST(caseSwitchClause.expression);
                        if (comparisonInfo.message) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(caseSwitchClause.expression, TypeScript.DiagnosticCode.Cannot_convert_0_to_1_NL_2, [caseClauseExpressionType.toString(enclosingSymbol), expressionType.toString(enclosingSymbol), comparisonInfo.message]));
                        } else {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(caseSwitchClause.expression, TypeScript.DiagnosticCode.Cannot_convert_0_to_1, [caseClauseExpressionType.toString(enclosingSymbol), expressionType.toString(enclosingSymbol)]));
                        }
                    }
                } else {
                    var defaultSwitchClause = switchClause;
                    this.resolveAST(defaultSwitchClause.statements, false, context);
                }
            }
        };

        PullTypeResolver.prototype.resolveLabeledStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckLabeledStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckLabeledStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            var labelIdentifier = ast.identifier.valueText();

            var breakableLabels = this.getEnclosingLabels(ast, true, false);

            var matchingLabel = TypeScript.ArrayUtilities.firstOrDefault(breakableLabels, function (s) {
                return s.identifier.valueText() === labelIdentifier;
            });
            if (matchingLabel) {
                context.postDiagnostic(this.semanticInfoChain.duplicateIdentifierDiagnosticFromAST(ast.identifier, labelIdentifier, matchingLabel));
            }

            this.resolveAST(ast.statement, false, context);
        };

        PullTypeResolver.prototype.labelIsOnContinuableConstruct = function (statement) {
            switch (statement.kind()) {
                case 160 /* LabeledStatement */:
                    return this.labelIsOnContinuableConstruct(statement.statement);

                case 158 /* WhileStatement */:
                case 154 /* ForStatement */:
                case 155 /* ForInStatement */:
                case 161 /* DoStatement */:
                    return true;

                default:
                    return false;
            }
        };

        PullTypeResolver.prototype.resolveContinueStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckContinueStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.isIterationStatement = function (ast) {
            switch (ast.kind()) {
                case 154 /* ForStatement */:
                case 155 /* ForInStatement */:
                case 158 /* WhileStatement */:
                case 161 /* DoStatement */:
                    return true;
            }

            return false;
        };

        PullTypeResolver.prototype.isAnyFunctionExpressionOrDeclaration = function (ast) {
            switch (ast.kind()) {
                case 219 /* SimpleArrowFunctionExpression */:
                case 218 /* ParenthesizedArrowFunctionExpression */:
                case 222 /* FunctionExpression */:
                case 129 /* FunctionDeclaration */:
                case 135 /* MemberFunctionDeclaration */:
                case 241 /* FunctionPropertyAssignment */:
                case 137 /* ConstructorDeclaration */:
                case 139 /* GetAccessor */:
                case 140 /* SetAccessor */:
                    return true;
            }

            return false;
        };

        PullTypeResolver.prototype.inSwitchStatement = function (ast) {
            while (ast) {
                if (ast.kind() === 151 /* SwitchStatement */) {
                    return true;
                }

                if (this.isAnyFunctionExpressionOrDeclaration(ast)) {
                    return false;
                }

                ast = ast.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.inIterationStatement = function (ast, crossFunctions) {
            while (ast) {
                if (this.isIterationStatement(ast)) {
                    return true;
                }

                if (!crossFunctions && this.isAnyFunctionExpressionOrDeclaration(ast)) {
                    return false;
                }

                ast = ast.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.getEnclosingLabels = function (ast, breakable, crossFunctions) {
            var result = [];

            ast = ast.parent;
            while (ast) {
                if (ast.kind() === 160 /* LabeledStatement */) {
                    var labeledStatement = ast;
                    if (breakable) {
                        result.push(labeledStatement);
                    } else {
                        if (this.labelIsOnContinuableConstruct(labeledStatement.statement)) {
                            result.push(labeledStatement);
                        }
                    }
                }

                if (!crossFunctions && this.isAnyFunctionExpressionOrDeclaration(ast)) {
                    break;
                }

                ast = ast.parent;
            }

            return result;
        };

        PullTypeResolver.prototype.typeCheckContinueStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            if (!this.inIterationStatement(ast, false)) {
                if (this.inIterationStatement(ast, true)) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Jump_target_cannot_cross_function_boundary));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.continue_statement_can_only_be_used_within_an_enclosing_iteration_statement));
                }
            } else if (ast.identifier) {
                var continuableLabels = this.getEnclosingLabels(ast, false, false);

                if (!TypeScript.ArrayUtilities.any(continuableLabels, function (s) {
                    return s.identifier.valueText() === ast.identifier.valueText();
                })) {
                    var continuableLabels = this.getEnclosingLabels(ast, false, true);

                    if (TypeScript.ArrayUtilities.any(continuableLabels, function (s) {
                        return s.identifier.valueText() === ast.identifier.valueText();
                    })) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Jump_target_cannot_cross_function_boundary));
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Jump_target_not_found));
                    }
                }
            }
        };

        PullTypeResolver.prototype.resolveBreakStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckBreakStatement(ast, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.typeCheckBreakStatement = function (ast, context) {
            this.setTypeChecked(ast, context);

            if (ast.identifier) {
                var breakableLabels = this.getEnclosingLabels(ast, true, false);

                if (!TypeScript.ArrayUtilities.any(breakableLabels, function (s) {
                    return s.identifier.valueText() === ast.identifier.valueText();
                })) {
                    var breakableLabels = this.getEnclosingLabels(ast, true, true);
                    if (TypeScript.ArrayUtilities.any(breakableLabels, function (s) {
                        return s.identifier.valueText() === ast.identifier.valueText();
                    })) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Jump_target_cannot_cross_function_boundary));
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Jump_target_not_found));
                    }
                }
            } else if (!this.inIterationStatement(ast, false) && !this.inSwitchStatement(ast)) {
                if (this.inIterationStatement(ast, true)) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Jump_target_cannot_cross_function_boundary));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement));
                }
            }
        };

        PullTypeResolver.prototype.resolveAST = function (ast, isContextuallyTyped, context) {
            if (!ast) {
                return;
            }

            var symbol = this.getSymbolForAST(ast, context);
            if (symbol && symbol.isResolved) {
                this.typeCheckAST(ast, isContextuallyTyped, context);
                return symbol;
            }

            if (ast.isExpression() && !isTypesOnlyLocation(ast)) {
                return this.resolveExpressionAST(ast, isContextuallyTyped, context);
            }

            var nodeType = ast.kind();

            switch (nodeType) {
                case 124 /* ArrayType */:
                case 126 /* GenericType */:
                case 122 /* ObjectType */:
                case 127 /* TypeQuery */:
                case 125 /* ConstructorType */:
                case 123 /* FunctionType */:
                    return this.resolveTypeReference(ast, context);

                case 1 /* List */:
                    return this.resolveList(ast, context);

                case 2 /* SeparatedList */:
                    return this.resolveSeparatedList(ast, context);

                case 120 /* SourceUnit */:
                    return this.resolveSourceUnit(ast, context);

                case 132 /* EnumDeclaration */:
                    return this.resolveEnumDeclaration(ast, context);

                case 130 /* ModuleDeclaration */:
                    return this.resolveModuleDeclaration(ast, context);

                case 128 /* InterfaceDeclaration */:
                    return this.resolveInterfaceDeclaration(ast, context);

                case 131 /* ClassDeclaration */:
                    return this.resolveClassDeclaration(ast, context);

                case 224 /* VariableDeclaration */:
                    return this.resolveVariableDeclarationList(ast, context);

                case 136 /* MemberVariableDeclaration */:
                    return this.resolveMemberVariableDeclaration(ast, context);

                case 225 /* VariableDeclarator */:
                    return this.resolveVariableDeclarator(ast, context);

                case 141 /* PropertySignature */:
                    return this.resolvePropertySignature(ast, context);

                case 227 /* ParameterList */:
                    return this.resolveParameterList(ast, context);

                case 242 /* Parameter */:
                    return this.resolveParameter(ast, context);

                case 243 /* EnumElement */:
                    return this.resolveEnumElement(ast, context);

                case 232 /* EqualsValueClause */:
                    return this.resolveEqualsValueClause(ast, isContextuallyTyped, context);

                case 238 /* TypeParameter */:
                    return this.resolveTypeParameterDeclaration(ast, context);

                case 239 /* Constraint */:
                    return this.resolveConstraint(ast, context);

                case 133 /* ImportDeclaration */:
                    return this.resolveImportDeclaration(ast, context);

                case 240 /* SimplePropertyAssignment */:
                    return this.resolveSimplePropertyAssignment(ast, isContextuallyTyped, context);

                case 241 /* FunctionPropertyAssignment */:
                    return this.resolveFunctionPropertyAssignment(ast, isContextuallyTyped, context);

                case 11 /* IdentifierName */:
                    TypeScript.Debug.assert(isTypesOnlyLocation(ast));
                    return this.resolveTypeNameExpression(ast, context);

                case 121 /* QualifiedName */:
                    return this.resolveQualifiedName(ast, context);

                case 137 /* ConstructorDeclaration */:
                    return this.resolveConstructorDeclaration(ast, context);

                case 139 /* GetAccessor */:
                case 140 /* SetAccessor */:
                    return this.resolveAccessorDeclaration(ast, context);

                case 138 /* IndexMemberDeclaration */:
                    return this.resolveIndexMemberDeclaration(ast, context);

                case 144 /* IndexSignature */:
                    return this.resolveIndexSignature(ast, context);

                case 135 /* MemberFunctionDeclaration */:
                    return this.resolveMemberFunctionDeclaration(ast, context);

                case 142 /* CallSignature */:
                    return this.resolveCallSignature(ast, context);

                case 143 /* ConstructSignature */:
                    return this.resolveConstructSignature(ast, context);

                case 145 /* MethodSignature */:
                    return this.resolveMethodSignature(ast, context);

                case 129 /* FunctionDeclaration */:
                    return this.resolveAnyFunctionDeclaration(ast, context);

                case 244 /* TypeAnnotation */:
                    return this.resolveTypeAnnotation(ast, context);

                case 134 /* ExportAssignment */:
                    return this.resolveExportAssignmentStatement(ast, context);

                case 157 /* ThrowStatement */:
                    return this.resolveThrowStatement(ast, context);

                case 149 /* ExpressionStatement */:
                    return this.resolveExpressionStatement(ast, context);

                case 154 /* ForStatement */:
                    return this.resolveForStatement(ast, context);

                case 155 /* ForInStatement */:
                    return this.resolveForInStatement(ast, context);

                case 158 /* WhileStatement */:
                    return this.resolveWhileStatement(ast, context);

                case 161 /* DoStatement */:
                    return this.resolveDoStatement(ast, context);

                case 147 /* IfStatement */:
                    return this.resolveIfStatement(ast, context);

                case 235 /* ElseClause */:
                    return this.resolveElseClause(ast, context);

                case 146 /* Block */:
                    return this.resolveBlock(ast, context);

                case 148 /* VariableStatement */:
                    return this.resolveVariableStatement(ast, context);

                case 163 /* WithStatement */:
                    return this.resolveWithStatement(ast, context);

                case 159 /* TryStatement */:
                    return this.resolveTryStatement(ast, context);

                case 236 /* CatchClause */:
                    return this.resolveCatchClause(ast, context);

                case 237 /* FinallyClause */:
                    return this.resolveFinallyClause(ast, context);

                case 150 /* ReturnStatement */:
                    return this.resolveReturnStatement(ast, context);

                case 151 /* SwitchStatement */:
                    return this.resolveSwitchStatement(ast, context);

                case 153 /* ContinueStatement */:
                    return this.resolveContinueStatement(ast, context);

                case 152 /* BreakStatement */:
                    return this.resolveBreakStatement(ast, context);

                case 160 /* LabeledStatement */:
                    return this.resolveLabeledStatement(ast, context);
            }

            return this.semanticInfoChain.anyTypeSymbol;
        };

        PullTypeResolver.prototype.resolveExpressionAST = function (ast, isContextuallyOrInferentiallyTyped, context) {
            var expressionSymbol = this.resolveExpressionWorker(ast, isContextuallyOrInferentiallyTyped, context);

            if (isContextuallyOrInferentiallyTyped && context.isInferentiallyTyping()) {
                return this.alterPotentialGenericFunctionTypeToInstantiatedFunctionTypeForTypeArgumentInference(expressionSymbol, context);
            } else {
                return expressionSymbol;
            }
        };

        PullTypeResolver.prototype.resolveExpressionWorker = function (ast, isContextuallyTyped, context) {
            switch (ast.kind()) {
                case 215 /* ObjectLiteralExpression */:
                    return this.resolveObjectLiteralExpression(ast, isContextuallyTyped, context);

                case 11 /* IdentifierName */:
                    return this.resolveNameExpression(ast, context);

                case 212 /* MemberAccessExpression */:
                    return this.resolveMemberAccessExpression(ast, context);

                case 222 /* FunctionExpression */:
                    return this.resolveFunctionExpression(ast, isContextuallyTyped, context);

                case 219 /* SimpleArrowFunctionExpression */:
                    return this.resolveSimpleArrowFunctionExpression(ast, isContextuallyTyped, context);

                case 218 /* ParenthesizedArrowFunctionExpression */:
                    return this.resolveParenthesizedArrowFunctionExpression(ast, isContextuallyTyped, context);

                case 214 /* ArrayLiteralExpression */:
                    return this.resolveArrayLiteralExpression(ast, isContextuallyTyped, context);

                case 35 /* ThisKeyword */:
                    return this.resolveThisExpression(ast, context);

                case 50 /* SuperKeyword */:
                    return this.resolveSuperExpression(ast, context);

                case 213 /* InvocationExpression */:
                    return this.resolveInvocationExpression(ast, context);

                case 216 /* ObjectCreationExpression */:
                    return this.resolveObjectCreationExpression(ast, context);

                case 220 /* CastExpression */:
                    return this.resolveCastExpression(ast, context);

                case 13 /* NumericLiteral */:
                    return this.semanticInfoChain.numberTypeSymbol;

                case 14 /* StringLiteral */:
                    return this.semanticInfoChain.stringTypeSymbol;

                case 32 /* NullKeyword */:
                    return this.semanticInfoChain.nullTypeSymbol;

                case 37 /* TrueKeyword */:
                case 24 /* FalseKeyword */:
                    return this.semanticInfoChain.booleanTypeSymbol;

                case 172 /* VoidExpression */:
                    return this.resolveVoidExpression(ast, context);

                case 174 /* AssignmentExpression */:
                    return this.resolveAssignmentExpression(ast, context);

                case 167 /* LogicalNotExpression */:
                    return this.resolveLogicalNotExpression(ast, context);

                case 193 /* NotEqualsWithTypeConversionExpression */:
                case 192 /* EqualsWithTypeConversionExpression */:
                case 194 /* EqualsExpression */:
                case 195 /* NotEqualsExpression */:
                case 196 /* LessThanExpression */:
                case 198 /* LessThanOrEqualExpression */:
                case 199 /* GreaterThanOrEqualExpression */:
                case 197 /* GreaterThanExpression */:
                    return this.resolveLogicalOperation(ast, context);

                case 208 /* AddExpression */:
                case 175 /* AddAssignmentExpression */:
                    return this.resolveBinaryAdditionOperation(ast, context);

                case 164 /* PlusExpression */:
                case 165 /* NegateExpression */:
                case 166 /* BitwiseNotExpression */:
                case 168 /* PreIncrementExpression */:
                case 169 /* PreDecrementExpression */:
                    return this.resolveUnaryArithmeticOperation(ast, context);

                case 210 /* PostIncrementExpression */:
                case 211 /* PostDecrementExpression */:
                    return this.resolvePostfixUnaryExpression(ast, context);

                case 209 /* SubtractExpression */:
                case 205 /* MultiplyExpression */:
                case 206 /* DivideExpression */:
                case 207 /* ModuloExpression */:
                case 189 /* BitwiseOrExpression */:
                case 191 /* BitwiseAndExpression */:
                case 202 /* LeftShiftExpression */:
                case 203 /* SignedRightShiftExpression */:
                case 204 /* UnsignedRightShiftExpression */:
                case 190 /* BitwiseExclusiveOrExpression */:
                case 181 /* ExclusiveOrAssignmentExpression */:
                case 183 /* LeftShiftAssignmentExpression */:
                case 184 /* SignedRightShiftAssignmentExpression */:
                case 185 /* UnsignedRightShiftAssignmentExpression */:
                case 176 /* SubtractAssignmentExpression */:
                case 177 /* MultiplyAssignmentExpression */:
                case 178 /* DivideAssignmentExpression */:
                case 179 /* ModuloAssignmentExpression */:
                case 182 /* OrAssignmentExpression */:
                case 180 /* AndAssignmentExpression */:
                    return this.resolveBinaryArithmeticExpression(ast, context);

                case 221 /* ElementAccessExpression */:
                    return this.resolveElementAccessExpression(ast, context);

                case 187 /* LogicalOrExpression */:
                    return this.resolveLogicalOrExpression(ast, isContextuallyTyped, context);

                case 188 /* LogicalAndExpression */:
                    return this.resolveLogicalAndExpression(ast, context);

                case 171 /* TypeOfExpression */:
                    return this.resolveTypeOfExpression(ast, context);

                case 170 /* DeleteExpression */:
                    return this.resolveDeleteExpression(ast, context);

                case 186 /* ConditionalExpression */:
                    return this.resolveConditionalExpression(ast, isContextuallyTyped, context);

                case 12 /* RegularExpressionLiteral */:
                    return this.resolveRegularExpressionLiteral();

                case 217 /* ParenthesizedExpression */:
                    return this.resolveParenthesizedExpression(ast, context);

                case 200 /* InstanceOfExpression */:
                    return this.resolveInstanceOfExpression(ast, context);

                case 173 /* CommaExpression */:
                    return this.resolveCommaExpression(ast, context);

                case 201 /* InExpression */:
                    return this.resolveInExpression(ast, context);

                case 223 /* OmittedExpression */:
                    return this.semanticInfoChain.undefinedTypeSymbol;
            }

            TypeScript.Debug.fail("resolveExpressionASTWorker: Missing expression kind: " + TypeScript.SyntaxKind[ast.kind()]);
        };

        PullTypeResolver.prototype.typeCheckAST = function (ast, isContextuallyTyped, context) {
            if (!this.canTypeCheckAST(ast, context)) {
                return;
            }

            var nodeType = ast.kind();
            switch (nodeType) {
                case 120 /* SourceUnit */:
                    this.typeCheckSourceUnit(ast, context);
                    return;

                case 132 /* EnumDeclaration */:
                    this.typeCheckEnumDeclaration(ast, context);
                    return;

                case 130 /* ModuleDeclaration */:
                    this.typeCheckModuleDeclaration(ast, context);
                    return;

                case 128 /* InterfaceDeclaration */:
                    this.typeCheckInterfaceDeclaration(ast, context);
                    return;

                case 131 /* ClassDeclaration */:
                    this.typeCheckClassDeclaration(ast, context);
                    return;

                case 243 /* EnumElement */:
                    this.typeCheckEnumElement(ast, context);
                    return;

                case 136 /* MemberVariableDeclaration */:
                    this.typeCheckMemberVariableDeclaration(ast, context);
                    return;

                case 225 /* VariableDeclarator */:
                    this.typeCheckVariableDeclarator(ast, context);
                    return;

                case 141 /* PropertySignature */:
                    this.typeCheckPropertySignature(ast, context);
                    return;

                case 242 /* Parameter */:
                    this.typeCheckParameter(ast, context);
                    return;

                case 133 /* ImportDeclaration */:
                    this.typeCheckImportDeclaration(ast, context);
                    return;

                case 215 /* ObjectLiteralExpression */:
                    this.resolveObjectLiteralExpression(ast, isContextuallyTyped, context);
                    return;

                case 241 /* FunctionPropertyAssignment */:
                    this.typeCheckFunctionPropertyAssignment(ast, isContextuallyTyped, context);
                    return;

                case 11 /* IdentifierName */:
                    if (isTypesOnlyLocation(ast)) {
                        this.resolveTypeNameExpression(ast, context);
                    } else {
                        this.resolveNameExpression(ast, context);
                    }
                    return;

                case 212 /* MemberAccessExpression */:
                    this.resolveMemberAccessExpression(ast, context);
                    return;

                case 121 /* QualifiedName */:
                    this.resolveQualifiedName(ast, context);
                    return;

                case 222 /* FunctionExpression */:
                    this.typeCheckFunctionExpression(ast, isContextuallyTyped, context);
                    return;

                case 137 /* ConstructorDeclaration */:
                    this.typeCheckConstructorDeclaration(ast, context);
                    return;

                case 139 /* GetAccessor */:
                case 140 /* SetAccessor */:
                    this.typeCheckAccessorDeclaration(ast, context);
                    return;

                case 135 /* MemberFunctionDeclaration */:
                    this.typeCheckMemberFunctionDeclaration(ast, context);
                    return;

                case 145 /* MethodSignature */:
                    this.typeCheckMethodSignature(ast, context);
                    return;

                case 144 /* IndexSignature */:
                    this.typeCheckIndexSignature(ast, context);
                    break;

                case 142 /* CallSignature */:
                    this.typeCheckCallSignature(ast, context);
                    return;

                case 143 /* ConstructSignature */:
                    this.typeCheckConstructSignature(ast, context);
                    return;

                case 129 /* FunctionDeclaration */: {
                    var funcDecl = ast;
                    this.typeCheckAnyFunctionDeclaration(funcDecl, TypeScript.hasModifier(funcDecl.modifiers, 16 /* Static */), funcDecl.identifier, funcDecl.callSignature.typeParameterList, funcDecl.callSignature.parameterList, TypeScript.ASTHelpers.getType(funcDecl), funcDecl.block, context);
                    return;
                }

                case 219 /* SimpleArrowFunctionExpression */:
                    this.typeCheckSimpleArrowFunctionExpression(ast, isContextuallyTyped, context);
                    return;

                case 218 /* ParenthesizedArrowFunctionExpression */:
                    this.typeCheckParenthesizedArrowFunctionExpression(ast, isContextuallyTyped, context);
                    return;

                case 214 /* ArrayLiteralExpression */:
                    this.resolveArrayLiteralExpression(ast, isContextuallyTyped, context);
                    return;

                case 213 /* InvocationExpression */:
                    this.typeCheckInvocationExpression(ast, context);
                    return;

                case 216 /* ObjectCreationExpression */:
                    this.typeCheckObjectCreationExpression(ast, context);
                    return;

                case 150 /* ReturnStatement */:
                    this.resolveReturnStatement(ast, context);
                    return;

                default:
                    TypeScript.Debug.assert(false, "Failure nodeType: " + TypeScript.SyntaxKind[ast.kind()] + ". Implement typeCheck when symbol is set for the ast as part of resolution.");
            }
        };

        PullTypeResolver.prototype.processPostTypeCheckWorkItems = function (context) {
            while (this.postTypeCheckWorkitems.length) {
                var ast = this.postTypeCheckWorkitems.pop();
                this.postTypeCheck(ast, context);
            }
        };

        PullTypeResolver.prototype.postTypeCheck = function (ast, context) {
            var nodeType = ast.kind();

            switch (nodeType) {
                case 242 /* Parameter */:
                case 225 /* VariableDeclarator */:
                    this.postTypeCheckVariableDeclaratorOrParameter(ast, context);
                    return;

                case 131 /* ClassDeclaration */:
                    this.postTypeCheckClassDeclaration(ast, context);
                    return;

                case 129 /* FunctionDeclaration */:
                    this.postTypeCheckFunctionDeclaration(ast, context);
                    return;

                case 130 /* ModuleDeclaration */:
                    this.postTypeCheckModuleDeclaration(ast, context);
                    return;

                case 132 /* EnumDeclaration */:
                    this.postTypeCheckEnumDeclaration(ast, context);
                    return;

                case 133 /* ImportDeclaration */:
                    this.postTypeCheckImportDeclaration(ast, context);
                    return;

                case 11 /* IdentifierName */:
                    this.postTypeCheckNameExpression(ast, context);
                    return;

                default:
                    TypeScript.Debug.assert(false, "Implement postTypeCheck clause to handle the postTypeCheck work, nodeType: " + TypeScript.SyntaxKind[ast.kind()]);
            }
        };

        PullTypeResolver.prototype.resolveRegularExpressionLiteral = function () {
            if (this.cachedRegExpInterfaceType()) {
                return this.cachedRegExpInterfaceType();
            } else {
                return this.semanticInfoChain.anyTypeSymbol;
            }
        };

        PullTypeResolver.prototype.postTypeCheckNameExpression = function (nameAST, context) {
            this.checkThisCaptureVariableCollides(nameAST, false, context);
        };

        PullTypeResolver.prototype.typeCheckNameExpression = function (nameAST, context) {
            this.setTypeChecked(nameAST, context);
            this.checkNameForCompilerGeneratedDeclarationCollision(nameAST, false, nameAST, context);
        };

        PullTypeResolver.prototype.resolveNameExpression = function (nameAST, context) {
            var nameSymbol = this.getSymbolForAST(nameAST, context);
            var foundCached = nameSymbol !== null;

            if (!foundCached || this.canTypeCheckAST(nameAST, context)) {
                if (this.canTypeCheckAST(nameAST, context)) {
                    this.typeCheckNameExpression(nameAST, context);
                }
                nameSymbol = this.computeNameExpression(nameAST, context);
            }

            this.resolveDeclaredSymbol(nameSymbol, context);

            if (nameSymbol && (nameSymbol.type !== this.semanticInfoChain.anyTypeSymbol || nameSymbol.anyDeclHasFlag(16777216 /* IsAnnotatedWithAny */ | 1 /* Exported */))) {
                this.setSymbolForAST(nameAST, nameSymbol, context);
            }

            return nameSymbol;
        };

        PullTypeResolver.prototype.isInEnumDecl = function (decl) {
            if (decl.kind & 64 /* Enum */) {
                return true;
            }

            var declPath = decl.getParentPath();

            var disallowedKinds = 164 /* SomeContainer */ | 58728795 /* SomeType */;
            for (var i = declPath.length - 1; i >= 0; i--) {
                var decl = declPath[i];

                if (decl.kind & 64 /* Enum */) {
                    return true;
                }

                if (decl.kind & disallowedKinds) {
                    return false;
                }
            }
            return false;
        };

        PullTypeResolver.prototype.getSomeInnermostFunctionScopeDecl = function (declPath) {
            for (var i = declPath.length - 1; i >= 0; i--) {
                var decl = declPath[i];
                if (decl.kind & 1032192 /* SomeFunction */) {
                    return decl;
                }
            }

            return null;
        };

        PullTypeResolver.prototype.isFromFunctionScope = function (nameSymbol, functionScopeDecl) {
            var _this = this;
            return TypeScript.ArrayUtilities.any(nameSymbol.getDeclarations(), function (nameSymbolDecl) {
                return _this.getSomeInnermostFunctionScopeDecl(nameSymbolDecl.getParentPath()) === functionScopeDecl;
            });
        };

        PullTypeResolver.prototype.findConstructorDeclOfEnclosingType = function (decl) {
            var current = decl;
            while (current) {
                if (TypeScript.hasFlag(current.kind, 4096 /* Property */)) {
                    var parentDecl = current.getParentDecl();
                    if (TypeScript.hasFlag(parentDecl.kind, 8 /* Class */)) {
                        return TypeScript.ArrayUtilities.lastOrDefault(parentDecl.getChildDecls(), function (decl) {
                            return TypeScript.hasFlag(decl.kind, 32768 /* ConstructorMethod */);
                        });
                    }
                }

                if (TypeScript.hasFlag(current.kind, 164 /* SomeContainer */)) {
                    return null;
                }

                current = current.getParentDecl();
            }
            return null;
        };

        PullTypeResolver.prototype.checkNameAsPartOfInitializerExpressionForInstanceMemberVariable = function (nameAST, nameSymbol, context) {
            var id = nameAST.valueText();
            if (id.length === 0) {
                return false;
            }

            var memberVariableDeclarationAST = TypeScript.ASTHelpers.getEnclosingMemberVariableDeclaration(nameAST);
            if (memberVariableDeclarationAST) {
                var memberVariableDecl = this.semanticInfoChain.getDeclForAST(memberVariableDeclarationAST);
                if (!TypeScript.hasFlag(memberVariableDecl.flags, 16 /* Static */)) {
                    var constructorDecl = this.findConstructorDeclOfEnclosingType(memberVariableDecl);

                    if (constructorDecl) {
                        var childDecls = constructorDecl.searchChildDecls(id, 68147712 /* SomeValue */);
                        if (childDecls.length) {
                            if (TypeScript.PullHelpers.isSymbolDeclaredInScopeChain(nameSymbol, constructorDecl.getSymbol().getContainer())) {
                                var memberVariableSymbol = memberVariableDecl.getSymbol();

                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(nameAST, TypeScript.DiagnosticCode.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, [memberVariableSymbol.getScopedName(constructorDecl.getSymbol()), nameAST.text()]));
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        };

        PullTypeResolver.prototype.computeNameExpression = function (nameAST, context) {
            var id = nameAST.valueText();
            if (id.length === 0) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var nameSymbol = null;
            var enclosingDecl = this.getEnclosingDeclForAST(nameAST);

            if (TypeScript.hasFlag(enclosingDecl.flags, 8388608 /* PropertyParameter */)) {
                var valueDecl = enclosingDecl.getValueDecl();
                if (valueDecl && TypeScript.hasFlag(valueDecl.kind, 2048 /* Parameter */)) {
                    enclosingDecl = valueDecl;
                }
            }

            var isDeclarationASTOrDeclarationNameAST = TypeScript.ASTHelpers.isDeclarationASTOrDeclarationNameAST(nameAST);
            if (isDeclarationASTOrDeclarationNameAST) {
                nameSymbol = this.semanticInfoChain.getDeclForAST(nameAST.parent).getSymbol();
            }

            var declPath = enclosingDecl.getParentPath();

            if (!nameSymbol) {
                var searchKind = 68147712 /* SomeValue */;

                if (!this.isInEnumDecl(enclosingDecl)) {
                    searchKind = searchKind & ~(67108864 /* EnumMember */);
                }

                var nameSymbol = this.getSymbolFromDeclPath(id, declPath, searchKind);
            }

            if (id === "arguments") {
                var functionScopeDecl = this.getSomeInnermostFunctionScopeDecl(declPath);
                if (functionScopeDecl) {
                    if (!nameSymbol || !this.isFromFunctionScope(nameSymbol, functionScopeDecl)) {
                        nameSymbol = this.cachedFunctionArgumentsSymbol();
                        this.resolveDeclaredSymbol(this.cachedIArgumentsInterfaceType(), context);
                    }
                }
            }

            var aliasSymbol = null;
            if (nameSymbol && nameSymbol.isAlias() && !isDeclarationASTOrDeclarationNameAST) {
                aliasSymbol = nameSymbol;
                if (!this.inTypeQuery(nameAST)) {
                    aliasSymbol.setIsUsedAsValue();
                }

                this.resolveDeclaredSymbol(nameSymbol, context);

                this.resolveDeclaredSymbol(aliasSymbol.assignedValue(), context);
                this.resolveDeclaredSymbol(aliasSymbol.assignedContainer(), context);

                nameSymbol = aliasSymbol.getExportAssignedValueSymbol();
                if (!nameSymbol) {
                    aliasSymbol = null;
                }
            }

            if (!nameSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(nameAST, TypeScript.DiagnosticCode.Could_not_find_symbol_0, [nameAST.text()]));
                return this.getNewErrorTypeSymbol(id);
            } else if (this.checkNameAsPartOfInitializerExpressionForInstanceMemberVariable(nameAST, nameSymbol, context)) {
                return this.getNewErrorTypeSymbol(id);
            }

            var nameDeclaration = nameSymbol.getDeclarations()[0];
            var nameParentDecl = nameDeclaration.getParentDecl();
            if (nameParentDecl && (nameParentDecl.kind & 1032192 /* SomeFunction */) && (nameParentDecl.flags & 33554432 /* HasDefaultArgs */)) {
                var enclosingFunctionAST = this.semanticInfoChain.getASTForDecl(nameParentDecl);
                var currentParameterIndex = this.getCurrentParameterIndexForFunction(nameAST, enclosingFunctionAST);

                var parameterList = TypeScript.ASTHelpers.getParameterList(enclosingFunctionAST);

                if (currentParameterIndex >= 0) {
                    var matchingParameter;
                    if (parameterList) {
                        for (var i = 0; i <= currentParameterIndex; i++) {
                            var candidateParameter = parameterList.parameters.nonSeparatorAt(i);
                            if (candidateParameter && candidateParameter.identifier.valueText() === id) {
                                matchingParameter = candidateParameter;
                                break;
                            }
                        }
                    }

                    if (!matchingParameter) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(nameAST, TypeScript.DiagnosticCode.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, [parameterList.parameters.nonSeparatorAt(currentParameterIndex).identifier.text(), nameAST.text()]));
                        return this.getNewErrorTypeSymbol(id);
                    } else if (matchingParameter === TypeScript.ASTHelpers.getEnclosingParameterForInitializer(nameAST)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(nameAST, TypeScript.DiagnosticCode.Parameter_0_cannot_be_referenced_in_its_initializer, [parameterList.parameters.nonSeparatorAt(currentParameterIndex).identifier.text()]));
                        return this.getNewErrorTypeSymbol(id);
                    }
                }
            }

            if (aliasSymbol) {
                this.semanticInfoChain.setAliasSymbolForAST(nameAST, aliasSymbol);
            }

            return nameSymbol;
        };

        PullTypeResolver.prototype.getCurrentParameterIndexForFunction = function (parameter, funcDecl) {
            var parameterList = TypeScript.ASTHelpers.getParameterList(funcDecl);
            if (parameterList) {
                while (parameter && parameter.parent) {
                    if (parameter.parent.parent === parameterList) {
                        return parameterList.parameters.nonSeparatorIndexOf(parameter);
                    }

                    parameter = parameter.parent;
                }
            }

            return -1;
        };

        PullTypeResolver.prototype.resolveMemberAccessExpression = function (dottedNameAST, context) {
            return this.resolveDottedNameExpression(dottedNameAST, dottedNameAST.expression, dottedNameAST.name, context);
        };

        PullTypeResolver.prototype.resolveDottedNameExpression = function (dottedNameAST, expression, name, context) {
            var symbol = this.getSymbolForAST(dottedNameAST, context);
            var foundCached = symbol !== null;

            if (!foundCached || this.canTypeCheckAST(dottedNameAST, context)) {
                var canTypeCheckDottedNameAST = this.canTypeCheckAST(dottedNameAST, context);
                if (canTypeCheckDottedNameAST) {
                    this.setTypeChecked(dottedNameAST, context);
                }

                symbol = this.computeDottedNameExpression(expression, name, context, canTypeCheckDottedNameAST);
            }

            this.resolveDeclaredSymbol(symbol, context);

            if (symbol && (symbol.type !== this.semanticInfoChain.anyTypeSymbol || symbol.anyDeclHasFlag(16777216 /* IsAnnotatedWithAny */ | 1 /* Exported */))) {
                this.setSymbolForAST(dottedNameAST, symbol, context);
                this.setSymbolForAST(name, symbol, context);
            }

            return symbol;
        };

        PullTypeResolver.prototype.computeDottedNameExpression = function (expression, name, context, checkSuperPrivateAndStaticAccess) {
            var rhsName = name.valueText();
            if (rhsName.length === 0) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var lhs = this.resolveAST(expression, false, context);
            return this.computeDottedNameExpressionFromLHS(lhs, expression, name, context, checkSuperPrivateAndStaticAccess);
        };

        PullTypeResolver.prototype.computeDottedNameExpressionFromLHS = function (lhs, expression, name, context, checkSuperPrivateAndStaticAccess) {
            var rhsName = name.valueText();
            if (rhsName.length === 0) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var lhsType = lhs.type;

            if (lhs.isAlias()) {
                var lhsAlias = lhs;
                if (!this.inTypeQuery(expression)) {
                    lhsAlias.setIsUsedAsValue();
                }
                lhsType = lhsAlias.getExportAssignedTypeSymbol();
            }

            if (lhsType.isAlias()) {
                lhsType = lhsType.getExportAssignedTypeSymbol();
            }

            if (!lhsType) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(name, TypeScript.DiagnosticCode.Could_not_find_enclosing_symbol_for_dotted_name_0, [name.text()]));
                return this.getNewErrorTypeSymbol();
            }

            if (!lhsType.isResolved) {
                var potentiallySpecializedType = this.resolveDeclaredSymbol(lhsType, context);

                if (potentiallySpecializedType !== lhsType) {
                    if (!lhs.isType()) {
                        context.setTypeInContext(lhs, potentiallySpecializedType);
                    }

                    lhsType = potentiallySpecializedType;
                }
            }

            if (lhsType.isContainer() && !lhsType.isAlias() && !lhsType.isEnum()) {
                var instanceSymbol = lhsType.getInstanceSymbol();

                if (instanceSymbol) {
                    lhsType = instanceSymbol.type;
                }
            }

            var originalLhsTypeForErrorReporting = lhsType;

            lhsType = this.getApparentType(lhsType).widenedType(this, expression, context);

            if (this.isAnyOrEquivalent(lhsType)) {
                return lhsType;
            }

            var nameSymbol = this._getNamedPropertySymbolOfAugmentedType(rhsName, lhsType);

            if (!nameSymbol) {
                if (lhsType.kind === 32 /* DynamicModule */) {
                    var container = lhsType;
                    var associatedInstance = container.getInstanceSymbol();

                    if (associatedInstance) {
                        var instanceType = associatedInstance.type;

                        nameSymbol = this.getNamedPropertySymbol(rhsName, 68147712 /* SomeValue */, instanceType);
                    }
                } else {
                    var associatedType = lhsType.getAssociatedContainerType();

                    if (associatedType && !associatedType.isClass()) {
                        nameSymbol = this.getNamedPropertySymbol(rhsName, 68147712 /* SomeValue */, associatedType);
                    }
                }

                if (!nameSymbol) {
                    var enclosingDecl = this.getEnclosingDeclForAST(expression);
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(name, TypeScript.DiagnosticCode.The_property_0_does_not_exist_on_value_of_type_1, [name.text(), originalLhsTypeForErrorReporting.toString(enclosingDecl ? enclosingDecl.getSymbol() : null)]));
                    return this.getNewErrorTypeSymbol(rhsName);
                }
            }

            if (checkSuperPrivateAndStaticAccess) {
                this.checkForSuperMemberAccess(expression, name, nameSymbol, context) || this.checkForPrivateMemberAccess(name, lhsType, nameSymbol, context);
            }

            return nameSymbol;
        };

        PullTypeResolver.prototype.resolveTypeNameExpression = function (nameAST, context) {
            var typeNameSymbol = this.getSymbolForAST(nameAST, context);

            if (!typeNameSymbol || !typeNameSymbol.isType() || this.canTypeCheckAST(nameAST, context)) {
                if (this.canTypeCheckAST(nameAST, context)) {
                    this.setTypeChecked(nameAST, context);
                }
                typeNameSymbol = this.computeTypeNameExpression(nameAST, context);
                this.setSymbolForAST(nameAST, typeNameSymbol, context);
            }

            this.resolveDeclaredSymbol(typeNameSymbol, context);

            return typeNameSymbol;
        };

        PullTypeResolver.prototype.computeTypeNameExpression = function (nameAST, context) {
            var id = nameAST.valueText();
            if (id.length === 0) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var enclosingDecl = this.getEnclosingDeclForAST(nameAST);

            var declPath = enclosingDecl.getParentPath();

            var onLeftOfDot = this.isLeftSideOfQualifiedName(nameAST);

            var kindToCheckFirst = onLeftOfDot ? 164 /* SomeContainer */ : 58728795 /* SomeType */;
            var kindToCheckSecond = onLeftOfDot ? 58728795 /* SomeType */ : 164 /* SomeContainer */;

            var typeNameSymbol = this.getSymbolFromDeclPath(id, declPath, kindToCheckFirst);

            if (!typeNameSymbol) {
                typeNameSymbol = this.getSymbolFromDeclPath(id, declPath, kindToCheckSecond);
            }

            if (!typeNameSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(nameAST, TypeScript.DiagnosticCode.Could_not_find_symbol_0, [nameAST.text()]));
                return this.getNewErrorTypeSymbol(id);
            }

            var typeNameSymbolAlias = null;
            if (typeNameSymbol.isAlias()) {
                typeNameSymbolAlias = typeNameSymbol;
                this.resolveDeclaredSymbol(typeNameSymbol, context);

                var aliasedType = typeNameSymbolAlias.getExportAssignedTypeSymbol();

                this.resolveDeclaredSymbol(aliasedType, context);
            }

            if (typeNameSymbol.isTypeParameter()) {
                if (this.isInStaticMemberContext(enclosingDecl)) {
                    var parentDecl = typeNameSymbol.getDeclarations()[0].getParentDecl();

                    if (parentDecl.kind === 8 /* Class */) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(nameAST, TypeScript.DiagnosticCode.Static_members_cannot_reference_class_type_parameters));
                        return this.getNewErrorTypeSymbol();
                    }
                }
            }

            if (!typeNameSymbol.isGeneric() && (typeNameSymbol.isClass() || typeNameSymbol.isInterface())) {
                typeNameSymbol = TypeScript.PullTypeReferenceSymbol.createTypeReference(typeNameSymbol);
            }

            return typeNameSymbol;
        };

        PullTypeResolver.prototype.isInStaticMemberContext = function (decl) {
            while (decl) {
                if (TypeScript.hasFlag(decl.kind, 1032192 /* SomeFunction */ | 4096 /* Property */) && TypeScript.hasFlag(decl.flags, 16 /* Static */)) {
                    return true;
                }

                if (TypeScript.hasFlag(decl.kind, 164 /* SomeContainer */)) {
                    return false;
                }

                decl = decl.getParentDecl();
            }

            return false;
        };

        PullTypeResolver.prototype.isLeftSideOfQualifiedName = function (ast) {
            return ast && ast.parent && ast.parent.kind() === 121 /* QualifiedName */ && ast.parent.left === ast;
        };

        PullTypeResolver.prototype.resolveGenericTypeReference = function (genericTypeAST, context) {
            var _this = this;
            var genericTypeSymbol = this.resolveAST(genericTypeAST.name, false, context).type;

            if (genericTypeSymbol.isError()) {
                return genericTypeSymbol;
            }

            if (!genericTypeSymbol.inResolution && !genericTypeSymbol.isResolved) {
                this.resolveDeclaredSymbol(genericTypeSymbol, context);
            }

            if (genericTypeSymbol.isAlias()) {
                if (this.inClassExtendsHeritageClause(genericTypeAST) && !this.inTypeArgumentList(genericTypeAST)) {
                    genericTypeSymbol.setIsUsedAsValue();
                }
                genericTypeSymbol = genericTypeSymbol.getExportAssignedTypeSymbol();
            }

            var typeParameters = genericTypeSymbol.getTypeParameters();
            if (typeParameters.length === 0) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(genericTypeAST, TypeScript.DiagnosticCode.Type_0_does_not_have_type_parameters, [genericTypeSymbol.toString()]));
                return this.getNewErrorTypeSymbol();
            }

            var typeArgs = [];

            if (genericTypeAST.typeArgumentList && genericTypeAST.typeArgumentList.typeArguments.nonSeparatorCount()) {
                for (var i = 0; i < genericTypeAST.typeArgumentList.typeArguments.nonSeparatorCount(); i++) {
                    typeArgs[i] = this.resolveTypeReference(genericTypeAST.typeArgumentList.typeArguments.nonSeparatorAt(i), context);

                    if (typeArgs[i].isError()) {
                        typeArgs[i] = this.semanticInfoChain.anyTypeSymbol;
                    }
                }
            }

            if (typeArgs.length && typeArgs.length !== typeParameters.length) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(genericTypeAST, TypeScript.DiagnosticCode.Generic_type_0_requires_1_type_argument_s, [genericTypeSymbol.toString(), genericTypeSymbol.getTypeParameters().length]));
                return this.getNewErrorTypeSymbol();
            }

            if (!genericTypeSymbol.isResolved) {
                var typeDecls = genericTypeSymbol.getDeclarations();
                var childDecls = null;

                for (var i = 0; i < typeDecls.length; i++) {
                    childDecls = typeDecls[i].getChildDecls();

                    for (var j = 0; j < childDecls.length; j++) {
                        childDecls[j].ensureSymbolIsBound();
                    }
                }
            }

            var specializedSymbol = this.createInstantiatedType(genericTypeSymbol, typeArgs);

            var upperBound = null;

            typeParameters = specializedSymbol.getTypeParameters();

            var typeConstraintSubstitutionMap = [];

            var instantiatedSubstitutionMap = specializedSymbol.getTypeParameterArgumentMap();

            for (var i = 0; i < typeParameters.length; i++) {
                typeConstraintSubstitutionMap[typeParameters[i].pullSymbolID] = typeParameters[i];
            }

            for (var id in instantiatedSubstitutionMap) {
                typeConstraintSubstitutionMap[id] = instantiatedSubstitutionMap[id];
            }

            for (var iArg = 0; (iArg < typeArgs.length) && (iArg < typeParameters.length); iArg++) {
                var typeArg = typeArgs[iArg];
                var typeParameter = typeParameters[iArg];
                var typeConstraint = typeParameter.getConstraint();

                typeConstraintSubstitutionMap[typeParameter.pullSymbolID] = typeArg;

                if (typeConstraint) {
                    if (typeConstraint.isTypeParameter()) {
                        for (var j = 0; j < typeParameters.length && j < typeArgs.length; j++) {
                            if (typeParameters[j] === typeConstraint) {
                                typeConstraint = typeArgs[j];
                            }
                        }
                    } else if (typeConstraint.isGeneric()) {
                        typeConstraint = this.instantiateType(typeConstraint, typeConstraintSubstitutionMap);
                    }

                    if (typeArg.isTypeParameter()) {
                        upperBound = typeArg.getConstraint();

                        if (upperBound) {
                            typeArg = upperBound;
                        }
                    }

                    if (typeArg.inResolution || (typeArg.isTypeReference() && typeArg.referencedTypeSymbol.inResolution)) {
                        return specializedSymbol;
                    }

                    if (context.canTypeCheckAST(genericTypeAST)) {
                        this.typeCheckCallBacks.push(function (context) {
                            if (!_this.sourceIsAssignableToTarget(typeArg, typeConstraint, genericTypeAST, context)) {
                                var enclosingSymbol = _this.getEnclosingSymbolForAST(genericTypeAST);
                                context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(genericTypeAST, TypeScript.DiagnosticCode.Type_0_does_not_satisfy_the_constraint_1_for_type_parameter_2, [typeArg.toString(enclosingSymbol, true), typeConstraint.toString(enclosingSymbol, true), typeParameter.toString(enclosingSymbol, true)]));
                            }
                        });
                    }
                }
            }

            return specializedSymbol;
        };

        PullTypeResolver.prototype.resolveQualifiedName = function (dottedNameAST, context) {
            if (this.inTypeQuery(dottedNameAST)) {
                return this.resolveDottedNameExpression(dottedNameAST, dottedNameAST.left, dottedNameAST.right, context).type;
            }

            var symbol = this.getSymbolForAST(dottedNameAST, context);
            if (!symbol || this.canTypeCheckAST(dottedNameAST, context)) {
                var canTypeCheck = this.canTypeCheckAST(dottedNameAST, context);
                if (canTypeCheck) {
                    this.setTypeChecked(dottedNameAST, context);
                }

                symbol = this.computeQualifiedName(dottedNameAST, context);
                this.setSymbolForAST(dottedNameAST, symbol, context);
            }

            this.resolveDeclaredSymbol(symbol, context);

            return symbol;
        };

        PullTypeResolver.prototype.isLastNameOfModuleNameModuleReference = function (ast) {
            return ast.kind() === 11 /* IdentifierName */ && ast.parent && ast.parent.kind() === 121 /* QualifiedName */ && ast.parent.right === ast && ast.parent.parent && ast.parent.parent.kind() === 246 /* ModuleNameModuleReference */;
        };

        PullTypeResolver.prototype.computeQualifiedName = function (dottedNameAST, context) {
            var rhsName = dottedNameAST.right.valueText();
            if (rhsName.length === 0) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            var enclosingDecl = this.getEnclosingDeclForAST(dottedNameAST);
            var lhs = this.resolveAST(dottedNameAST.left, false, context);

            var lhsType = lhs.isAlias() ? lhs.getExportAssignedContainerSymbol() : lhs.type;

            if (this.inClassExtendsHeritageClause(dottedNameAST) && !this.inTypeArgumentList(dottedNameAST)) {
                if (lhs.isAlias()) {
                    lhs.setIsUsedAsValue();
                }
            }

            if (!lhsType) {
                return this.getNewErrorTypeSymbol();
            }

            if (this.isAnyOrEquivalent(lhsType)) {
                return lhsType;
            }

            var onLeftOfDot = this.isLeftSideOfQualifiedName(dottedNameAST);
            var isNameOfModule = dottedNameAST.parent.kind() === 130 /* ModuleDeclaration */ && dottedNameAST.parent.name === dottedNameAST;

            var memberKind = (onLeftOfDot || isNameOfModule) ? 164 /* SomeContainer */ : 58728795 /* SomeType */;

            var childTypeSymbol = this.getNamedPropertySymbol(rhsName, memberKind, lhsType);

            if (!childTypeSymbol && !isNameOfModule && this.isLastNameOfModuleNameModuleReference(dottedNameAST.right)) {
                childTypeSymbol = this.getNamedPropertySymbol(rhsName, 68147712 /* SomeValue */, lhsType);
            }

            if (!childTypeSymbol && lhsType.isContainer()) {
                var exportedContainer = lhsType.getExportAssignedContainerSymbol();

                if (exportedContainer) {
                    childTypeSymbol = this.getNamedPropertySymbol(rhsName, memberKind, exportedContainer);
                }
            }

            if (!childTypeSymbol && enclosingDecl) {
                var parentDecl = enclosingDecl;

                while (parentDecl) {
                    if (parentDecl.kind & 164 /* SomeContainer */) {
                        break;
                    }

                    parentDecl = parentDecl.getParentDecl();
                }

                if (parentDecl) {
                    var enclosingSymbolType = parentDecl.getSymbol().type;

                    if (enclosingSymbolType === lhsType) {
                        childTypeSymbol = this.getNamedPropertySymbol(rhsName, memberKind, lhsType);
                    }
                }
            }

            if (!childTypeSymbol) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(dottedNameAST.right, TypeScript.DiagnosticCode.The_property_0_does_not_exist_on_value_of_type_1, [dottedNameAST.right.text(), lhsType.toString(enclosingDecl ? enclosingDecl.getSymbol() : null)]));
                return this.getNewErrorTypeSymbol(rhsName);
            }

            return childTypeSymbol;
        };

        PullTypeResolver.prototype.shouldContextuallyTypeAnyFunctionExpression = function (functionExpressionAST, typeParameters, parameters, returnTypeAnnotation, context) {
            if (typeParameters && typeParameters.typeParameters.nonSeparatorCount() > 0) {
                return false;
            }

            if (returnTypeAnnotation) {
                return false;
            }

            if (parameters) {
                for (var i = 0, n = parameters.length; i < n; i++) {
                    if (parameters.typeAt(i)) {
                        return false;
                    }
                }
            }

            var contextualFunctionTypeSymbol = context.getContextualType();

            if (contextualFunctionTypeSymbol) {
                this.resolveDeclaredSymbol(contextualFunctionTypeSymbol, context);
                var callSignatures = contextualFunctionTypeSymbol.getCallSignatures();
                var exactlyOneCallSignature = callSignatures && callSignatures.length === 1;
                if (!exactlyOneCallSignature) {
                    return false;
                }

                var callSignatureIsGeneric = callSignatures[0].getTypeParameters().length > 0;
                return !callSignatureIsGeneric;
            }

            return false;
        };

        PullTypeResolver.prototype.resolveAnyFunctionExpression = function (funcDeclAST, typeParameters, parameters, returnTypeAnnotation, block, bodyExpression, isContextuallyTyped, context) {
            var funcDeclSymbol = null;
            var functionDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            TypeScript.Debug.assert(functionDecl);

            if (functionDecl && functionDecl.hasSymbol()) {
                funcDeclSymbol = functionDecl.getSymbol();
                if (funcDeclSymbol.isResolved || funcDeclSymbol.inResolution) {
                    return funcDeclSymbol;
                }
            }

            funcDeclSymbol = functionDecl.getSymbol();
            TypeScript.Debug.assert(funcDeclSymbol);

            var funcDeclType = funcDeclSymbol.type;
            var signature = funcDeclType.getCallSignatures()[0];
            funcDeclSymbol.startResolving();

            if (typeParameters) {
                for (var i = 0; i < typeParameters.typeParameters.nonSeparatorCount(); i++) {
                    this.resolveTypeParameterDeclaration(typeParameters.typeParameters.nonSeparatorAt(i), context);
                }
            }

            var assigningFunctionSignature = null;
            if (isContextuallyTyped && this.shouldContextuallyTypeAnyFunctionExpression(funcDeclAST, typeParameters, parameters, returnTypeAnnotation, context)) {
                assigningFunctionSignature = context.getContextualType().getCallSignatures()[0];
            }

            this.resolveAnyFunctionExpressionParameters(funcDeclAST, typeParameters, parameters, returnTypeAnnotation, isContextuallyTyped, context);

            if (returnTypeAnnotation) {
                signature.returnType = this.resolveTypeReference(returnTypeAnnotation, context);
            } else {
                if (assigningFunctionSignature) {
                    var returnType = assigningFunctionSignature.returnType;

                    if (returnType) {
                        context.propagateContextualType(returnType);
                        this.resolveFunctionBodyReturnTypes(funcDeclAST, block, bodyExpression, signature, true, functionDecl, context);
                        context.popAnyContextualType();
                    } else {
                        signature.returnType = this.semanticInfoChain.anyTypeSymbol;

                        if (this.compilationSettings.noImplicitAny()) {
                            var functionExpressionName = functionDecl.getFunctionExpressionName();

                            if (functionExpressionName != "") {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode._0_which_lacks_return_type_annotation_implicitly_has_an_any_return_type, [functionExpressionName]));
                            } else {
                                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_any_return_type));
                            }
                        }
                    }
                } else {
                    this.resolveFunctionBodyReturnTypes(funcDeclAST, block, bodyExpression, signature, false, functionDecl, context);
                }
            }

            context.setTypeInContext(funcDeclSymbol, funcDeclType);
            funcDeclSymbol.setResolved();

            if (this.canTypeCheckAST(funcDeclAST, context)) {
                this.typeCheckAnyFunctionExpression(funcDeclAST, typeParameters, parameters, returnTypeAnnotation, block, bodyExpression, isContextuallyTyped, context);
            }

            return funcDeclSymbol;
        };

        PullTypeResolver.prototype.resolveAnyFunctionExpressionParameters = function (funcDeclAST, typeParameters, parameters, returnTypeAnnotation, isContextuallyTyped, context) {
            if (!parameters) {
                return;
            }

            var functionDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            var contextParams = [];

            var assigningFunctionSignature = null;
            if (isContextuallyTyped && this.shouldContextuallyTypeAnyFunctionExpression(funcDeclAST, typeParameters, parameters, returnTypeAnnotation, context)) {
                assigningFunctionSignature = context.getContextualType().getCallSignatures()[0];
            }

            if (assigningFunctionSignature) {
                contextParams = assigningFunctionSignature.parameters;
            }

            var contextualParametersCount = contextParams.length;
            for (var i = 0, n = parameters.length; i < n; i++) {
                var actualParameterIsVarArgParameter = (i === (n - 1)) && parameters.lastParameterIsRest();
                var correspondingContextualParameter = null;
                var contextualParameterType = null;

                if (i < contextualParametersCount) {
                    correspondingContextualParameter = contextParams[i];
                } else if (contextualParametersCount && contextParams[contextualParametersCount - 1].isVarArg) {
                    correspondingContextualParameter = contextParams[contextualParametersCount - 1];
                }

                if (correspondingContextualParameter) {
                    if (correspondingContextualParameter.isVarArg === actualParameterIsVarArgParameter) {
                        contextualParameterType = correspondingContextualParameter.type;
                    } else if (correspondingContextualParameter.isVarArg) {
                        contextualParameterType = correspondingContextualParameter.type.getElementType();
                    }
                }

                this.resolveFunctionExpressionParameter(parameters.astAt(i), parameters.identifierAt(i), parameters.typeAt(i), parameters.initializerAt(i), contextualParameterType, functionDecl, context);
            }
        };

        PullTypeResolver.prototype.typeCheckSimpleArrowFunctionExpression = function (arrowFunction, isContextuallyTyped, context) {
            return this.typeCheckAnyFunctionExpression(arrowFunction, null, TypeScript.ASTHelpers.parametersFromIdentifier(arrowFunction.identifier), null, arrowFunction.block, arrowFunction.expression, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.typeCheckParenthesizedArrowFunctionExpression = function (arrowFunction, isContextuallyTyped, context) {
            return this.typeCheckAnyFunctionExpression(arrowFunction, arrowFunction.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(arrowFunction.callSignature.parameterList), TypeScript.ASTHelpers.getType(arrowFunction), arrowFunction.block, arrowFunction.expression, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.typeCheckAnyFunctionExpression = function (funcDeclAST, typeParameters, parameters, returnTypeAnnotation, block, bodyExpression, isContextuallyTyped, context) {
            var _this = this;
            this.setTypeChecked(funcDeclAST, context);

            var functionDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);

            var funcDeclSymbol = functionDecl.getSymbol();
            var funcDeclType = funcDeclSymbol.type;
            var signature = funcDeclType.getCallSignatures()[0];
            var returnTypeSymbol = signature.returnType;

            if (typeParameters) {
                for (var i = 0; i < typeParameters.typeParameters.nonSeparatorCount(); i++) {
                    this.resolveTypeParameterDeclaration(typeParameters.typeParameters.nonSeparatorAt(i), context);
                }
            }

            this.resolveAnyFunctionExpressionParameters(funcDeclAST, typeParameters, parameters, returnTypeAnnotation, isContextuallyTyped, context);

            context.pushNewContextualType(null);
            if (block) {
                this.resolveAST(block, false, context);
            } else {
                var bodyExpressionType = this.resolveReturnExpression(bodyExpression, functionDecl, context);
                this.typeCheckReturnExpression(bodyExpression, bodyExpressionType, functionDecl, context);
            }

            context.popAnyContextualType();

            this.checkThatNonVoidFunctionHasReturnExpressionOrThrowStatement(functionDecl, returnTypeAnnotation, returnTypeSymbol, block, context);

            this.validateVariableDeclarationGroups(functionDecl, context);

            this.typeCheckCallBacks.push(function (context) {
                _this.typeCheckFunctionOverloads(funcDeclAST, context);
            });
        };

        PullTypeResolver.prototype.resolveThisExpression = function (thisExpression, context) {
            var enclosingDecl = this.getEnclosingDeclForAST(thisExpression);
            var thisTypeSymbol = this.getContextualClassSymbolForEnclosingDecl(thisExpression, enclosingDecl) || this.semanticInfoChain.anyTypeSymbol;

            if (this.canTypeCheckAST(thisExpression, context)) {
                this.typeCheckThisExpression(thisExpression, context, enclosingDecl);
            }

            return thisTypeSymbol;
        };

        PullTypeResolver.prototype.inTypeArgumentList = function (ast) {
            var previous = null;
            var current = ast;

            while (current) {
                switch (current.kind()) {
                    case 126 /* GenericType */:
                        var genericType = current;
                        if (genericType.typeArgumentList === previous) {
                            return true;
                        }
                        break;

                    case 226 /* ArgumentList */:
                        var argumentList = current;
                        return argumentList.typeArgumentList === previous;
                }

                previous = current;
                current = current.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.inClassExtendsHeritageClause = function (ast) {
            while (ast) {
                switch (ast.kind()) {
                    case 230 /* ExtendsHeritageClause */:
                        var heritageClause = ast;

                        return heritageClause.parent.parent.kind() === 131 /* ClassDeclaration */;

                    case 137 /* ConstructorDeclaration */:
                    case 131 /* ClassDeclaration */:
                    case 130 /* ModuleDeclaration */:
                        return false;
                }

                ast = ast.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.inTypeQuery = function (ast) {
            while (ast) {
                switch (ast.kind()) {
                    case 127 /* TypeQuery */:
                        return true;
                    case 129 /* FunctionDeclaration */:
                    case 213 /* InvocationExpression */:
                    case 137 /* ConstructorDeclaration */:
                    case 131 /* ClassDeclaration */:
                    case 130 /* ModuleDeclaration */:
                        return false;
                }

                ast = ast.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.inArgumentListOfSuperInvocation = function (ast) {
            var previous = null;
            var current = ast;
            while (current) {
                switch (current.kind()) {
                    case 213 /* InvocationExpression */:
                        var invocationExpression = current;
                        if (previous === invocationExpression.argumentList && invocationExpression.expression.kind() === 50 /* SuperKeyword */) {
                            return true;
                        }
                        break;

                    case 137 /* ConstructorDeclaration */:
                    case 131 /* ClassDeclaration */:
                    case 130 /* ModuleDeclaration */:
                        return false;
                }

                previous = current;
                current = current.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.inConstructorParameterList = function (ast) {
            var previous = null;
            var current = ast;
            while (current) {
                switch (current.kind()) {
                    case 142 /* CallSignature */:
                        var callSignature = current;
                        if (previous === callSignature.parameterList && callSignature.parent.kind() === 137 /* ConstructorDeclaration */) {
                            return true;
                        }

                    case 131 /* ClassDeclaration */:
                    case 130 /* ModuleDeclaration */:
                        return false;
                }

                previous = current;
                current = current.parent;
            }

            return false;
        };
        PullTypeResolver.prototype.isFunctionAccessorOrNonArrowFunctionExpression = function (decl) {
            if (decl.kind === 262144 /* GetAccessor */ || decl.kind === 524288 /* SetAccessor */) {
                return true;
            }

            return this.isFunctionOrNonArrowFunctionExpression(decl);
        };

        PullTypeResolver.prototype.isFunctionOrNonArrowFunctionExpression = function (decl) {
            if (decl.kind === 16384 /* Function */) {
                return true;
            } else if (decl.kind === 131072 /* FunctionExpression */ && !TypeScript.hasFlag(decl.flags, 8192 /* ArrowFunction */)) {
                return true;
            }

            return false;
        };

        PullTypeResolver.prototype.typeCheckThisExpression = function (thisExpression, context, enclosingDecl) {
            this.checkForThisCaptureInArrowFunction(thisExpression);

            if (this.inConstructorParameterList(thisExpression)) {
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(thisExpression, TypeScript.DiagnosticCode.this_cannot_be_referenced_in_constructor_arguments));
                return;
            }

            for (var currentDecl = enclosingDecl; currentDecl !== null; currentDecl = currentDecl.getParentDecl()) {
                if (this.isFunctionAccessorOrNonArrowFunctionExpression(currentDecl)) {
                    return;
                } else if (currentDecl.kind === 4 /* Container */ || currentDecl.kind === 32 /* DynamicModule */) {
                    if (currentDecl.getParentDecl() === null) {
                        return;
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(thisExpression, TypeScript.DiagnosticCode.this_cannot_be_referenced_within_module_bodies));
                        return;
                    }
                } else if (currentDecl.kind === 64 /* Enum */) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(thisExpression, TypeScript.DiagnosticCode.this_cannot_be_referenced_in_current_location));
                    return;
                } else if (currentDecl.kind === 32768 /* ConstructorMethod */) {
                    if (this.inArgumentListOfSuperInvocation(thisExpression) && this.superCallMustBeFirstStatementInConstructor(currentDecl)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(thisExpression, TypeScript.DiagnosticCode.this_cannot_be_referenced_in_current_location));
                    }

                    return;
                } else if (currentDecl.kind === 8 /* Class */) {
                    if (this.inStaticMemberVariableDeclaration(thisExpression)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(thisExpression, TypeScript.DiagnosticCode.this_cannot_be_referenced_in_static_initializers_in_a_class_body));
                    }

                    return;
                }
            }
        };

        PullTypeResolver.prototype.getContextualClassSymbolForEnclosingDecl = function (ast, enclosingDecl) {
            var declPath = enclosingDecl.getParentPath();

            if (declPath.length) {
                var isStaticContext = false;

                for (var i = declPath.length - 1; i >= 0; i--) {
                    var decl = declPath[i];
                    var declKind = decl.kind;
                    var declFlags = decl.flags;

                    if (declFlags & 16 /* Static */) {
                        isStaticContext = true;
                    } else if (declKind === 131072 /* FunctionExpression */ && !TypeScript.hasFlag(declFlags, 8192 /* ArrowFunction */)) {
                        return null;
                    } else if (declKind === 16384 /* Function */) {
                        return null;
                    } else if (declKind === 8 /* Class */) {
                        if (this.inStaticMemberVariableDeclaration(ast)) {
                            return this.getNewErrorTypeSymbol();
                        } else {
                            var classSymbol = decl.getSymbol();
                            if (isStaticContext) {
                                var constructorSymbol = classSymbol.getConstructorMethod();
                                return constructorSymbol.type;
                            } else {
                                return classSymbol;
                            }
                        }
                    }
                }
            }

            return null;
        };

        PullTypeResolver.prototype.inStaticMemberVariableDeclaration = function (ast) {
            while (ast) {
                if (ast.kind() === 136 /* MemberVariableDeclaration */ && TypeScript.hasModifier(ast.modifiers, 16 /* Static */)) {
                    return true;
                }

                ast = ast.parent;
            }

            return false;
        };

        PullTypeResolver.prototype.resolveSuperExpression = function (ast, context) {
            var enclosingDecl = this.getEnclosingDeclForAST(ast);
            var superType = this.semanticInfoChain.anyTypeSymbol;

            var classSymbol = this.getContextualClassSymbolForEnclosingDecl(ast, enclosingDecl);

            if (classSymbol) {
                this.resolveDeclaredSymbol(classSymbol, context);

                var parents = classSymbol.getExtendedTypes();

                if (parents.length) {
                    superType = parents[0];
                }
            }

            if (this.canTypeCheckAST(ast, context)) {
                this.typeCheckSuperExpression(ast, context, enclosingDecl);
            }

            return superType;
        };

        PullTypeResolver.prototype.typeCheckSuperExpression = function (ast, context, enclosingDecl) {
            this.setTypeChecked(ast, context);

            this.checkForThisCaptureInArrowFunction(ast);

            var isSuperCall = ast.parent.kind() === 213 /* InvocationExpression */;
            var isSuperPropertyAccess = ast.parent.kind() === 212 /* MemberAccessExpression */;
            TypeScript.Debug.assert(isSuperCall || isSuperPropertyAccess);

            if (isSuperPropertyAccess) {
                for (var currentDecl = enclosingDecl; currentDecl !== null; currentDecl = currentDecl.getParentDecl()) {
                    if (this.isFunctionOrNonArrowFunctionExpression(currentDecl)) {
                        break;
                    } else if (currentDecl.kind === 8 /* Class */) {
                        if (!this.enclosingClassIsDerived(currentDecl)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.super_cannot_be_referenced_in_non_derived_classes));
                            return;
                        } else if (this.inConstructorParameterList(ast)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.super_cannot_be_referenced_in_constructor_arguments));
                            return;
                        } else if (this.inStaticMemberVariableDeclaration(ast)) {
                            break;
                        }

                        return;
                    }
                }
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class));
                return;
            } else {
                if (enclosingDecl.kind === 32768 /* ConstructorMethod */) {
                    var classDecl = enclosingDecl.getParentDecl();

                    if (!this.enclosingClassIsDerived(classDecl)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.super_cannot_be_referenced_in_non_derived_classes));
                        return;
                    } else if (this.inConstructorParameterList(ast)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.super_cannot_be_referenced_in_constructor_arguments));
                        return;
                    }
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors));
                }
            }
        };

        PullTypeResolver.prototype.resolveSimplePropertyAssignment = function (propertyAssignment, isContextuallyTyped, context) {
            return this.resolveAST(propertyAssignment.expression, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.resolveFunctionPropertyAssignment = function (funcProp, isContextuallyTyped, context) {
            return this.resolveAnyFunctionExpression(funcProp, funcProp.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(funcProp.callSignature.parameterList), TypeScript.ASTHelpers.getType(funcProp), funcProp.block, null, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.typeCheckFunctionPropertyAssignment = function (funcProp, isContextuallyTyped, context) {
            this.typeCheckAnyFunctionExpression(funcProp, funcProp.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(funcProp.callSignature.parameterList), TypeScript.ASTHelpers.getType(funcProp), funcProp.block, null, isContextuallyTyped, context);
        };

        PullTypeResolver.prototype.resolveObjectLiteralExpression = function (expressionAST, isContextuallyTyped, context, additionalResults) {
            var symbol = this.getSymbolForAST(expressionAST, context);
            var hasResolvedSymbol = symbol && symbol.isResolved;

            if (!hasResolvedSymbol || additionalResults || this.canTypeCheckAST(expressionAST, context)) {
                if (this.canTypeCheckAST(expressionAST, context)) {
                    this.setTypeChecked(expressionAST, context);
                }
                symbol = this.computeObjectLiteralExpression(expressionAST, isContextuallyTyped, context, additionalResults);
                this.setSymbolForAST(expressionAST, symbol, context);
            }

            return symbol;
        };

        PullTypeResolver.prototype.bindObjectLiteralMembers = function (objectLiteralDeclaration, objectLiteralTypeSymbol, objectLiteralMembers, isUsingExistingSymbol, pullTypeContext) {
            var boundMemberSymbols = [];
            var memberSymbol;
            for (var i = 0, len = objectLiteralMembers.nonSeparatorCount(); i < len; i++) {
                var propertyAssignment = objectLiteralMembers.nonSeparatorAt(i);

                var id = this.getPropertyAssignmentName(propertyAssignment);
                var assignmentText = getPropertyAssignmentNameTextFromIdentifier(id);

                var isAccessor = propertyAssignment.kind() === 139 /* GetAccessor */ || propertyAssignment.kind() === 140 /* SetAccessor */;
                var decl = this.semanticInfoChain.getDeclForAST(propertyAssignment);
                TypeScript.Debug.assert(decl);

                if (propertyAssignment.kind() === 240 /* SimplePropertyAssignment */) {
                    if (!isUsingExistingSymbol) {
                        memberSymbol = new TypeScript.PullSymbol(assignmentText.memberName, 4096 /* Property */);
                        memberSymbol.addDeclaration(decl);
                        decl.setSymbol(memberSymbol);
                    } else {
                        memberSymbol = decl.getSymbol();
                    }
                } else if (propertyAssignment.kind() === 241 /* FunctionPropertyAssignment */) {
                    memberSymbol = decl.getSymbol();
                } else {
                    TypeScript.Debug.assert(isAccessor);
                    memberSymbol = decl.getSymbol();
                }

                if (!isUsingExistingSymbol && !isAccessor) {
                    var existingMember = objectLiteralTypeSymbol.findMember(memberSymbol.name, true);
                    if (existingMember) {
                        pullTypeContext.postDiagnostic(this.semanticInfoChain.duplicateIdentifierDiagnosticFromAST(propertyAssignment, assignmentText.actualText, existingMember.getDeclarations()[0].ast()));
                    }

                    objectLiteralTypeSymbol.addMember(memberSymbol);
                }

                boundMemberSymbols.push(memberSymbol);
            }

            return boundMemberSymbols;
        };

        PullTypeResolver.prototype.resolveObjectLiteralMembers = function (objectLiteralDeclaration, objectLiteralTypeSymbol, objectLiteralContextualType, objectLiteralMembers, stringIndexerSignature, numericIndexerSignature, allMemberTypes, allNumericMemberTypes, boundMemberSymbols, isUsingExistingSymbol, pullTypeContext, additionalResults) {
            for (var i = 0, len = objectLiteralMembers.nonSeparatorCount(); i < len; i++) {
                var propertyAssignment = objectLiteralMembers.nonSeparatorAt(i);

                var acceptedContextualType = false;
                var assigningSymbol = null;

                var id = this.getPropertyAssignmentName(propertyAssignment);
                var memberSymbol = boundMemberSymbols[i];
                var contextualMemberType = null;

                if (objectLiteralContextualType) {
                    assigningSymbol = this.getNamedPropertySymbol(memberSymbol.name, 68147712 /* SomeValue */, objectLiteralContextualType);

                    if (!assigningSymbol) {
                        if (numericIndexerSignature && TypeScript.PullHelpers.isNameNumeric(memberSymbol.name)) {
                            assigningSymbol = numericIndexerSignature;
                        } else if (stringIndexerSignature) {
                            assigningSymbol = stringIndexerSignature;
                        }
                    }

                    if (assigningSymbol) {
                        this.resolveDeclaredSymbol(assigningSymbol, pullTypeContext);

                        contextualMemberType = assigningSymbol.kind === 4194304 /* IndexSignature */ ? assigningSymbol.returnType : assigningSymbol.type;
                        pullTypeContext.propagateContextualType(contextualMemberType);

                        acceptedContextualType = true;

                        if (additionalResults) {
                            additionalResults.membersContextTypeSymbols[i] = contextualMemberType;
                        }
                    }
                }

                var memberSymbolType = this.resolveAST(propertyAssignment, contextualMemberType !== null, pullTypeContext).type;

                if (memberSymbolType) {
                    if (memberSymbolType.isGeneric()) {
                        objectLiteralTypeSymbol.setHasGenericMember();
                    }

                    if (stringIndexerSignature) {
                        allMemberTypes.push(memberSymbolType);
                    }
                    if (numericIndexerSignature && TypeScript.PullHelpers.isNameNumeric(memberSymbol.name)) {
                        allNumericMemberTypes.push(memberSymbolType);
                    }
                }

                if (acceptedContextualType) {
                    pullTypeContext.popAnyContextualType();
                }

                var isAccessor = propertyAssignment.kind() === 140 /* SetAccessor */ || propertyAssignment.kind() === 139 /* GetAccessor */;
                if (!memberSymbol.isResolved) {
                    if (isAccessor) {
                        this.setSymbolForAST(id, memberSymbolType, pullTypeContext);
                    } else {
                        pullTypeContext.setTypeInContext(memberSymbol, memberSymbolType);
                        memberSymbol.setResolved();

                        this.setSymbolForAST(id, memberSymbol, pullTypeContext);
                    }
                }
            }
        };

        PullTypeResolver.prototype.computeObjectLiteralExpression = function (objectLitAST, isContextuallyTyped, context, additionalResults) {
            var objectLitDecl = this.semanticInfoChain.getDeclForAST(objectLitAST);
            TypeScript.Debug.assert(objectLitDecl);

            var typeSymbol = this.getSymbolForAST(objectLitAST, context);
            var isUsingExistingSymbol = !!typeSymbol;

            if (!typeSymbol) {
                typeSymbol = new TypeScript.PullTypeSymbol("", 256 /* ObjectLiteral */);
                typeSymbol.addDeclaration(objectLitDecl);
                this.setSymbolForAST(objectLitAST, typeSymbol, context);
                objectLitDecl.setSymbol(typeSymbol);
            }

            var propertyAssignments = objectLitAST.propertyAssignments;
            var contextualType = null;

            if (isContextuallyTyped) {
                contextualType = context.getContextualType();
                this.resolveDeclaredSymbol(contextualType, context);
            }

            var stringIndexerSignature = null;
            var numericIndexerSignature = null;
            var allMemberTypes = null;
            var allNumericMemberTypes = null;

            if (contextualType) {
                var indexSignatures = this.getBothKindsOfIndexSignaturesExcludingAugmentedType(contextualType, context);

                stringIndexerSignature = indexSignatures.stringSignature;
                numericIndexerSignature = indexSignatures.numericSignature;

                var inInferentialTyping = context.isInferentiallyTyping();
                if (stringIndexerSignature) {
                    allMemberTypes = inInferentialTyping ? [] : [stringIndexerSignature.returnType];
                }

                if (numericIndexerSignature) {
                    allNumericMemberTypes = inInferentialTyping ? [] : [numericIndexerSignature.returnType];
                }
            }

            if (propertyAssignments) {
                if (additionalResults) {
                    additionalResults.membersContextTypeSymbols = [];
                }

                var boundMemberSymbols = this.bindObjectLiteralMembers(objectLitDecl, typeSymbol, propertyAssignments, isUsingExistingSymbol, context);

                this.resolveObjectLiteralMembers(objectLitDecl, typeSymbol, contextualType, propertyAssignments, stringIndexerSignature, numericIndexerSignature, allMemberTypes, allNumericMemberTypes, boundMemberSymbols, isUsingExistingSymbol, context, additionalResults);

                if (!isUsingExistingSymbol) {
                    this.stampObjectLiteralWithIndexSignature(typeSymbol, allMemberTypes, stringIndexerSignature, context);
                    this.stampObjectLiteralWithIndexSignature(typeSymbol, allNumericMemberTypes, numericIndexerSignature, context);
                }
            }

            typeSymbol.setResolved();
            return typeSymbol;
        };

        PullTypeResolver.prototype.getPropertyAssignmentName = function (propertyAssignment) {
            if (propertyAssignment.kind() === 240 /* SimplePropertyAssignment */) {
                return propertyAssignment.propertyName;
            } else if (propertyAssignment.kind() === 241 /* FunctionPropertyAssignment */) {
                return propertyAssignment.propertyName;
            } else if (propertyAssignment.kind() === 139 /* GetAccessor */) {
                return propertyAssignment.propertyName;
            } else if (propertyAssignment.kind() === 140 /* SetAccessor */) {
                return propertyAssignment.propertyName;
            } else {
                TypeScript.Debug.assert(false);
            }
        };

        PullTypeResolver.prototype.stampObjectLiteralWithIndexSignature = function (objectLiteralSymbol, indexerTypeCandidates, contextualIndexSignature, context) {
            if (contextualIndexSignature) {
                var typeCollection = {
                    getLength: function () {
                        return indexerTypeCandidates.length;
                    },
                    getTypeAtIndex: function (index) {
                        return indexerTypeCandidates[index];
                    }
                };
                var decl = objectLiteralSymbol.getDeclarations()[0];
                var indexerReturnType = this.findBestCommonType(typeCollection, context).widenedType(this, null, context);
                if (indexerReturnType === contextualIndexSignature.returnType) {
                    objectLiteralSymbol.addIndexSignature(contextualIndexSignature);
                } else {
                    this.semanticInfoChain.addSyntheticIndexSignature(decl, objectLiteralSymbol, this.getASTForDecl(decl), contextualIndexSignature.parameters[0].name, contextualIndexSignature.parameters[0].type, indexerReturnType);
                }
            }
        };

        PullTypeResolver.prototype.resolveArrayLiteralExpression = function (arrayLit, isContextuallyTyped, context) {
            var symbol = this.getSymbolForAST(arrayLit, context);
            if (!symbol || this.canTypeCheckAST(arrayLit, context)) {
                if (this.canTypeCheckAST(arrayLit, context)) {
                    this.setTypeChecked(arrayLit, context);
                }
                symbol = this.computeArrayLiteralExpressionSymbol(arrayLit, isContextuallyTyped, context);
                this.setSymbolForAST(arrayLit, symbol, context);
            }

            return symbol;
        };

        PullTypeResolver.prototype.computeArrayLiteralExpressionSymbol = function (arrayLit, isContextuallyTyped, context) {
            var elements = arrayLit.expressions;
            var elementType = null;
            var elementTypes = [];
            var comparisonInfo = new TypeComparisonInfo();
            var contextualElementType = null;
            comparisonInfo.onlyCaptureFirstError = true;

            if (isContextuallyTyped) {
                var contextualType = context.getContextualType();

                this.resolveDeclaredSymbol(contextualType, context);

                if (contextualType) {
                    var indexSignatures = this.getBothKindsOfIndexSignaturesExcludingAugmentedType(contextualType, context);
                    if (indexSignatures.numericSignature) {
                        contextualElementType = indexSignatures.numericSignature.returnType;
                    }
                }
            }

            if (elements) {
                if (contextualElementType) {
                    context.propagateContextualType(contextualElementType);
                }

                for (var i = 0, n = elements.nonSeparatorCount(); i < n; i++) {
                    elementTypes.push(this.resolveAST(elements.nonSeparatorAt(i), contextualElementType !== null, context).type);
                }

                if (contextualElementType) {
                    context.popAnyContextualType();
                }
            }

            if (elementTypes.length) {
                elementType = elementTypes[0];
            }
            var collection;

            if (contextualElementType && !context.isInferentiallyTyping()) {
                if (!elementType) {
                    elementType = contextualElementType;
                }

                collection = {
                    getLength: function () {
                        return elements.nonSeparatorCount() + 1;
                    },
                    getTypeAtIndex: function (index) {
                        return index === 0 ? contextualElementType : elementTypes[index - 1];
                    }
                };
            } else {
                collection = {
                    getLength: function () {
                        return elements.nonSeparatorCount();
                    },
                    getTypeAtIndex: function (index) {
                        return elementTypes[index];
                    }
                };
            }

            elementType = elementType ? this.findBestCommonType(collection, context, comparisonInfo) : elementType;

            if (!elementType) {
                elementType = this.semanticInfoChain.undefinedTypeSymbol;
            }

            return this.getArrayType(elementType);
        };

        PullTypeResolver.prototype.resolveElementAccessExpression = function (callEx, context) {
            var symbolAndDiagnostic = this.computeElementAccessExpressionSymbolAndDiagnostic(callEx, context);

            if (this.canTypeCheckAST(callEx, context)) {
                this.typeCheckElementAccessExpression(callEx, context, symbolAndDiagnostic);
            }

            return symbolAndDiagnostic.symbol;
        };

        PullTypeResolver.prototype.typeCheckElementAccessExpression = function (callEx, context, symbolAndDiagnostic) {
            this.setTypeChecked(callEx, context);
            context.postDiagnostic(symbolAndDiagnostic.diagnostic);
        };

        PullTypeResolver.prototype.computeElementAccessExpressionSymbolAndDiagnostic = function (callEx, context) {
            var targetSymbol = this.resolveAST(callEx.expression, false, context);
            var indexType = this.resolveAST(callEx.argumentExpression, false, context).type;

            var targetTypeSymbol = targetSymbol.type;

            targetTypeSymbol = this.getApparentType(targetTypeSymbol);

            if (this.isAnyOrEquivalent(targetTypeSymbol)) {
                return { symbol: targetTypeSymbol };
            }

            var elementType = targetTypeSymbol.getElementType();

            var isNumberIndex = indexType === this.semanticInfoChain.numberTypeSymbol || TypeScript.PullHelpers.symbolIsEnum(indexType);

            if (elementType && isNumberIndex) {
                return { symbol: elementType };
            }

            if (callEx.argumentExpression.kind() === 14 /* StringLiteral */ || callEx.argumentExpression.kind() === 13 /* NumericLiteral */) {
                var memberName = callEx.argumentExpression.kind() === 14 /* StringLiteral */ ? TypeScript.stripStartAndEndQuotes(callEx.argumentExpression.text()) : callEx.argumentExpression.valueText();

                var member = this._getNamedPropertySymbolOfAugmentedType(memberName, targetTypeSymbol);

                if (member) {
                    this.resolveDeclaredSymbol(member, context);

                    return { symbol: member.type };
                }
            }

            var signatures = this.getBothKindsOfIndexSignaturesIncludingAugmentedType(targetTypeSymbol, context);

            var stringSignature = signatures.stringSignature;
            var numberSignature = signatures.numericSignature;

            if (numberSignature && (isNumberIndex || indexType === this.semanticInfoChain.anyTypeSymbol)) {
                return { symbol: numberSignature.returnType || this.semanticInfoChain.anyTypeSymbol };
            } else if (stringSignature && (isNumberIndex || indexType === this.semanticInfoChain.anyTypeSymbol || indexType === this.semanticInfoChain.stringTypeSymbol)) {
                return { symbol: stringSignature.returnType || this.semanticInfoChain.anyTypeSymbol };
            } else if (isNumberIndex || indexType === this.semanticInfoChain.anyTypeSymbol || indexType === this.semanticInfoChain.stringTypeSymbol) {
                if (this.compilationSettings.noImplicitAny()) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(callEx.argumentExpression, TypeScript.DiagnosticCode.Index_signature_of_object_type_implicitly_has_an_any_type));
                }
                return { symbol: this.semanticInfoChain.anyTypeSymbol };
            } else {
                return {
                    symbol: this.getNewErrorTypeSymbol(),
                    diagnostic: this.semanticInfoChain.diagnosticFromAST(callEx, TypeScript.DiagnosticCode.Value_of_type_0_is_not_indexable_by_type_1, [targetTypeSymbol.toString(), indexType.toString()])
                };
            }
        };

        PullTypeResolver.prototype.getBothKindsOfIndexSignaturesIncludingAugmentedType = function (enclosingType, context) {
            return this._getBothKindsOfIndexSignatures(enclosingType, context, true);
        };

        PullTypeResolver.prototype.getBothKindsOfIndexSignaturesExcludingAugmentedType = function (enclosingType, context) {
            return this._getBothKindsOfIndexSignatures(enclosingType, context, false);
        };

        PullTypeResolver.prototype._getBothKindsOfIndexSignatures = function (enclosingType, context, includeAugmentedType) {
            var signatures = includeAugmentedType ? enclosingType.getIndexSignaturesOfAugmentedType(this, this.cachedFunctionInterfaceType(), this.cachedObjectInterfaceType()) : enclosingType.getIndexSignatures();

            var stringSignature = null;
            var numberSignature = null;
            var signature = null;
            var paramSymbols;
            var paramType;

            for (var i = 0; i < signatures.length; i++) {
                if (stringSignature && numberSignature) {
                    break;
                }

                signature = signatures[i];
                if (!signature.isResolved) {
                    this.resolveDeclaredSymbol(signature, context);
                }

                paramSymbols = signature.parameters;

                if (paramSymbols.length) {
                    paramType = paramSymbols[0].type;

                    if (!stringSignature && paramType === this.semanticInfoChain.stringTypeSymbol) {
                        stringSignature = signature;
                        continue;
                    } else if (!numberSignature && paramType === this.semanticInfoChain.numberTypeSymbol) {
                        numberSignature = signature;
                        continue;
                    }
                }
            }

            return {
                numericSignature: numberSignature,
                stringSignature: stringSignature
            };
        };

        PullTypeResolver.prototype._addUnhiddenSignaturesFromBaseType = function (derivedTypeSignatures, baseTypeSignatures, signaturesBeingAggregated) {
            var _this = this;
            if (!derivedTypeSignatures) {
                signaturesBeingAggregated.push.apply(signaturesBeingAggregated, baseTypeSignatures);
                return;
            }

            var context = new TypeScript.PullTypeResolutionContext(this);
            for (var i = 0; i < baseTypeSignatures.length; i++) {
                var baseSignature = baseTypeSignatures[i];

                var signatureIsHidden = TypeScript.ArrayUtilities.any(derivedTypeSignatures, function (sig) {
                    return _this.signaturesAreIdenticalWithNewEnclosingTypes(baseSignature, sig, context, false);
                });

                if (!signatureIsHidden) {
                    signaturesBeingAggregated.push(baseSignature);
                }
            }
        };

        PullTypeResolver.prototype.resolveBinaryAdditionOperation = function (binaryExpression, context) {
            var lhsExpression = this.resolveAST(binaryExpression.left, false, context);
            var lhsType = lhsExpression.type;
            var rhsType = this.resolveAST(binaryExpression.right, false, context).type;

            if (TypeScript.PullHelpers.symbolIsEnum(lhsType)) {
                lhsType = this.semanticInfoChain.numberTypeSymbol;
            }

            if (TypeScript.PullHelpers.symbolIsEnum(rhsType)) {
                rhsType = this.semanticInfoChain.numberTypeSymbol;
            }

            var isLhsTypeNullOrUndefined = lhsType === this.semanticInfoChain.nullTypeSymbol || lhsType === this.semanticInfoChain.undefinedTypeSymbol;
            var isRhsTypeNullOrUndefined = rhsType === this.semanticInfoChain.nullTypeSymbol || rhsType === this.semanticInfoChain.undefinedTypeSymbol;

            if (isLhsTypeNullOrUndefined) {
                if (isRhsTypeNullOrUndefined) {
                    lhsType = rhsType = this.semanticInfoChain.anyTypeSymbol;
                } else {
                    lhsType = rhsType;
                }
            } else if (isRhsTypeNullOrUndefined) {
                rhsType = lhsType;
            }

            var exprType = null;

            if (lhsType === this.semanticInfoChain.stringTypeSymbol || rhsType === this.semanticInfoChain.stringTypeSymbol) {
                exprType = this.semanticInfoChain.stringTypeSymbol;
            } else if (this.isAnyOrEquivalent(lhsType) || this.isAnyOrEquivalent(rhsType)) {
                exprType = this.semanticInfoChain.anyTypeSymbol;
            } else if (rhsType === this.semanticInfoChain.numberTypeSymbol && lhsType === this.semanticInfoChain.numberTypeSymbol) {
                exprType = this.semanticInfoChain.numberTypeSymbol;
            }

            if (this.canTypeCheckAST(binaryExpression, context)) {
                this.setTypeChecked(binaryExpression, context);

                if (exprType) {
                    if (binaryExpression.kind() === 175 /* AddAssignmentExpression */) {
                        if (!this.isReference(binaryExpression.left, lhsExpression)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.Invalid_left_hand_side_of_assignment_expression));
                        }

                        this.checkAssignability(binaryExpression.left, exprType, lhsType, context);
                    }
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.Invalid_expression_types_not_known_to_support_the_addition_operator));
                }
            }

            if (!exprType) {
                exprType = this.semanticInfoChain.anyTypeSymbol;
            }

            return exprType;
        };

        PullTypeResolver.prototype.bestCommonTypeOfTwoTypes = function (type1, type2, context) {
            return this.findBestCommonType({
                getLength: function () {
                    return 2;
                },
                getTypeAtIndex: function (index) {
                    switch (index) {
                        case 0:
                            return type1;
                        case 1:
                            return type2;
                    }
                }
            }, context);
        };

        PullTypeResolver.prototype.bestCommonTypeOfThreeTypes = function (type1, type2, type3, context) {
            return this.findBestCommonType({
                getLength: function () {
                    return 3;
                },
                getTypeAtIndex: function (index) {
                    switch (index) {
                        case 0:
                            return type1;
                        case 1:
                            return type2;
                        case 2:
                            return type3;
                    }
                }
            }, context);
        };

        PullTypeResolver.prototype.resolveLogicalOrExpression = function (binex, isContextuallyTyped, context) {
            if (this.canTypeCheckAST(binex, context)) {
                this.setTypeChecked(binex, context);
            }

            if (isContextuallyTyped) {
                var contextualType = context.getContextualType();
                var leftType = this.resolveAST(binex.left, isContextuallyTyped, context).type;
                var rightType = this.resolveAST(binex.right, isContextuallyTyped, context).type;

                return context.isInferentiallyTyping() ? this.bestCommonTypeOfTwoTypes(leftType, rightType, context) : this.bestCommonTypeOfThreeTypes(contextualType, leftType, rightType, context);
            } else {
                var leftType = this.resolveAST(binex.left, false, context).type;

                context.pushNewContextualType(leftType);
                var rightType = this.resolveAST(binex.right, true, context).type;
                context.popAnyContextualType();

                return this.bestCommonTypeOfTwoTypes(leftType, rightType, context);
            }
        };

        PullTypeResolver.prototype.resolveLogicalAndExpression = function (binex, context) {
            if (this.canTypeCheckAST(binex, context)) {
                this.setTypeChecked(binex, context);

                this.resolveAST(binex.left, false, context);
            }

            return this.resolveAST(binex.right, false, context).type;
        };

        PullTypeResolver.prototype.computeTypeOfConditionalExpression = function (leftType, rightType, isContextuallyTyped, context) {
            if (isContextuallyTyped && !context.isInferentiallyTyping()) {
                var contextualType = context.getContextualType();
                return this.bestCommonTypeOfThreeTypes(contextualType, leftType, rightType, context);
            } else {
                return this.bestCommonTypeOfTwoTypes(leftType, rightType, context);
            }
        };

        PullTypeResolver.prototype.resolveConditionalExpression = function (trinex, isContextuallyTyped, context) {
            var leftType = this.resolveAST(trinex.whenTrue, isContextuallyTyped, context).type;
            var rightType = this.resolveAST(trinex.whenFalse, isContextuallyTyped, context).type;

            var expressionType = this.computeTypeOfConditionalExpression(leftType, rightType, isContextuallyTyped, context);

            var conditionalTypesAreValid = this.conditionExpressionTypesAreValid(leftType, rightType, expressionType, isContextuallyTyped, context);

            if (this.canTypeCheckAST(trinex, context)) {
                this.setTypeChecked(trinex, context);
                this.resolveAST(trinex.condition, false, context);

                if (!this.conditionExpressionTypesAreValid(leftType, rightType, expressionType, isContextuallyTyped, context)) {
                    if (isContextuallyTyped) {
                        var contextualType = context.getContextualType();
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(trinex, TypeScript.DiagnosticCode.Type_of_conditional_0_must_be_identical_to_1_2_or_3, [expressionType.toString(), leftType.toString(), rightType.toString(), contextualType.toString()]));
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(trinex, TypeScript.DiagnosticCode.Type_of_conditional_0_must_be_identical_to_1_or_2, [expressionType.toString(), leftType.toString(), rightType.toString()]));
                    }
                }
            }

            if (!conditionalTypesAreValid) {
                return this.getNewErrorTypeSymbol();
            }

            return expressionType;
        };

        PullTypeResolver.prototype.conditionExpressionTypesAreValid = function (leftType, rightType, expressionType, isContextuallyTyped, context) {
            if (isContextuallyTyped) {
                var contextualType = context.getContextualType();
                if (this.typesAreIdentical(expressionType, leftType, context) || this.typesAreIdentical(expressionType, rightType, context) || this.typesAreIdentical(expressionType, contextualType, context)) {
                    return true;
                }
            } else {
                if (this.typesAreIdentical(expressionType, leftType, context) || this.typesAreIdentical(expressionType, rightType, context)) {
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.resolveParenthesizedExpression = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);
            }

            return this.resolveAST(ast.expression, false, context);
        };

        PullTypeResolver.prototype.resolveExpressionStatement = function (ast, context) {
            if (this.canTypeCheckAST(ast, context)) {
                this.setTypeChecked(ast, context);

                this.resolveAST(ast.expression, false, context);
            }

            return this.semanticInfoChain.voidTypeSymbol;
        };

        PullTypeResolver.prototype.resolveInvocationExpression = function (callEx, context, additionalResults) {
            var symbol = this.getSymbolForAST(callEx, context);

            if (!symbol || !symbol.isResolved) {
                if (!additionalResults) {
                    additionalResults = new PullAdditionalCallResolutionData();
                }
                symbol = this.computeInvocationExpressionSymbol(callEx, context, additionalResults);
                if (this.canTypeCheckAST(callEx, context)) {
                    this.setTypeChecked(callEx, context);
                }
                if (symbol !== this.semanticInfoChain.anyTypeSymbol) {
                    this.setSymbolForAST(callEx, symbol, context);
                }
                this.semanticInfoChain.setCallResolutionDataForAST(callEx, additionalResults);
            } else {
                if (this.canTypeCheckAST(callEx, context)) {
                    this.typeCheckInvocationExpression(callEx, context);
                }

                var callResolutionData = this.semanticInfoChain.getCallResolutionDataForAST(callEx);
                if (additionalResults && (callResolutionData !== additionalResults)) {
                    additionalResults.actualParametersContextTypeSymbols = callResolutionData.actualParametersContextTypeSymbols;
                    additionalResults.candidateSignature = callResolutionData.candidateSignature;
                    additionalResults.resolvedSignatures = callResolutionData.resolvedSignatures;
                    additionalResults.targetSymbol = callResolutionData.targetSymbol;
                }
            }

            return symbol;
        };

        PullTypeResolver.prototype.typeCheckInvocationExpression = function (callEx, context) {
            this.setTypeChecked(callEx, context);
            var targetSymbol = this.resolveAST(callEx.expression, false, context);

            if (callEx.argumentList.arguments) {
                var callResolutionData = this.semanticInfoChain.getCallResolutionDataForAST(callEx);

                var len = callEx.argumentList.arguments.nonSeparatorCount();
                for (var i = 0; i < len; i++) {
                    var contextualType = callResolutionData.actualParametersContextTypeSymbols ? callResolutionData.actualParametersContextTypeSymbols[i] : null;
                    if (contextualType) {
                        context.pushNewContextualType(contextualType);
                    }

                    this.resolveAST(callEx.argumentList.arguments.nonSeparatorAt(i), contextualType !== null, context);

                    if (contextualType) {
                        context.popAnyContextualType();
                        contextualType = null;
                    }
                }
            }

            for (var i = 0; i < callResolutionData.diagnosticsFromOverloadResolution.length; i++) {
                context.postDiagnostic(callResolutionData.diagnosticsFromOverloadResolution[i]);
            }
        };

        PullTypeResolver.prototype.computeInvocationExpressionSymbol = function (callEx, context, additionalResults) {
            var targetSymbol = this.resolveAST(callEx.expression, false, context);
            var targetAST = this.getCallTargetErrorSpanAST(callEx);

            var targetTypeSymbol = targetSymbol.type;
            if (this.isAnyOrEquivalent(targetTypeSymbol)) {
                this.resolveAST(callEx.argumentList.arguments, false, context);

                if (callEx.argumentList.typeArgumentList && callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount()) {
                    if (targetTypeSymbol === this.semanticInfoChain.anyTypeSymbol) {
                        this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Untyped_function_calls_may_not_accept_type_arguments), additionalResults, context);
                        return this.getNewErrorTypeSymbol();
                    }
                }

                return this.semanticInfoChain.anyTypeSymbol;
            }

            var isSuperCall = false;

            if (callEx.expression.kind() === 50 /* SuperKeyword */) {
                isSuperCall = true;

                if (targetTypeSymbol.isClass()) {
                    targetSymbol = targetTypeSymbol.getConstructorMethod();
                    this.resolveDeclaredSymbol(targetSymbol, context);
                    targetTypeSymbol = targetSymbol.type;
                } else {
                    this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Calls_to_super_are_only_valid_inside_a_class), additionalResults, context);
                    this.resolveAST(callEx.argumentList.arguments, false, context);

                    return this.getNewErrorTypeSymbol();
                }
            }

            var signatures = isSuperCall ? targetTypeSymbol.getConstructSignatures() : targetTypeSymbol.getCallSignatures();

            if (!signatures.length && (targetTypeSymbol.kind === 33554432 /* ConstructorType */)) {
                this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, [targetTypeSymbol.toString()]), additionalResults, context);
            }

            var explicitTypeArgs = null;
            var couldNotFindGenericOverload = false;
            var couldNotAssignToConstraint;
            var constraintDiagnostic = null;
            var typeArgumentCountDiagnostic = null;
            var diagnostics = [];

            if (callEx.argumentList.typeArgumentList) {
                explicitTypeArgs = [];

                if (callEx.argumentList.typeArgumentList && callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount()) {
                    for (var i = 0; i < callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount(); i++) {
                        explicitTypeArgs[i] = this.resolveTypeReference(callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorAt(i), context);
                    }
                }
            }

            var triedToInferTypeArgs = false;

            var resolvedSignatures = [];
            var inferredOrExplicitTypeArgs;
            var specializedSignature;
            var typeParameters;
            var typeConstraint = null;
            var beforeResolutionSignatures = signatures;
            var targetTypeReplacementMap = targetTypeSymbol.getTypeParameterArgumentMap();

            for (var i = 0; i < signatures.length; i++) {
                typeParameters = signatures[i].getTypeParameters();
                couldNotAssignToConstraint = false;

                if (signatures[i].isGeneric() && typeParameters.length) {
                    if (isSuperCall && targetTypeSymbol.isGeneric() && !callEx.argumentList.typeArgumentList) {
                        explicitTypeArgs = signatures[i].returnType.getTypeArguments();
                    }

                    if (explicitTypeArgs) {
                        if (explicitTypeArgs.length === typeParameters.length) {
                            inferredOrExplicitTypeArgs = explicitTypeArgs;
                        } else {
                            typeArgumentCountDiagnostic = typeArgumentCountDiagnostic || this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Signature_expected_0_type_arguments_got_1_instead, [typeParameters.length, explicitTypeArgs.length]);
                            continue;
                        }
                    } else {
                        TypeScript.Debug.assert(callEx.argumentList);
                        var typeArgumentInferenceContext = new TypeScript.InvocationTypeArgumentInferenceContext(this, context, signatures[i], callEx.argumentList.arguments);
                        inferredOrExplicitTypeArgs = this.inferArgumentTypesForSignature(typeArgumentInferenceContext, new TypeComparisonInfo(), context);
                        triedToInferTypeArgs = true;
                    }

                    TypeScript.Debug.assert(inferredOrExplicitTypeArgs && inferredOrExplicitTypeArgs.length == typeParameters.length);

                    var mutableTypeReplacementMap = new TypeScript.PullInstantiationHelpers.MutableTypeArgumentMap(targetTypeReplacementMap ? targetTypeReplacementMap : []);
                    TypeScript.PullInstantiationHelpers.updateMutableTypeParameterArgumentMap(typeParameters, inferredOrExplicitTypeArgs, mutableTypeReplacementMap);
                    var typeReplacementMap = mutableTypeReplacementMap.typeParameterArgumentMap;

                    if (explicitTypeArgs) {
                        for (var j = 0; j < typeParameters.length; j++) {
                            typeConstraint = typeParameters[j].getConstraint();

                            if (typeConstraint) {
                                if (typeConstraint.isGeneric()) {
                                    typeConstraint = this.instantiateType(typeConstraint, typeReplacementMap);
                                }

                                if (!this.sourceIsAssignableToTarget(inferredOrExplicitTypeArgs[j], typeConstraint, targetAST, context, null, true)) {
                                    var enclosingSymbol = this.getEnclosingSymbolForAST(targetAST);
                                    constraintDiagnostic = this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Type_0_does_not_satisfy_the_constraint_1_for_type_parameter_2, [inferredOrExplicitTypeArgs[j].toString(enclosingSymbol, true), typeConstraint.toString(enclosingSymbol, true), typeParameters[j].toString(enclosingSymbol, true)]);
                                    couldNotAssignToConstraint = true;
                                }

                                if (couldNotAssignToConstraint) {
                                    break;
                                }
                            }
                        }
                    }

                    if (couldNotAssignToConstraint) {
                        continue;
                    }

                    specializedSignature = this.instantiateSignature(signatures[i], typeReplacementMap);

                    if (specializedSignature) {
                        resolvedSignatures[resolvedSignatures.length] = specializedSignature;
                    }
                } else {
                    if (!(callEx.argumentList.typeArgumentList && callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount())) {
                        resolvedSignatures[resolvedSignatures.length] = signatures[i];
                    }
                }
            }

            if (signatures.length && !resolvedSignatures.length) {
                couldNotFindGenericOverload = true;
            }

            signatures = resolvedSignatures;

            var errorCondition = null;
            if (!signatures.length) {
                additionalResults.targetSymbol = targetSymbol;
                additionalResults.resolvedSignatures = beforeResolutionSignatures;
                additionalResults.candidateSignature = beforeResolutionSignatures && beforeResolutionSignatures.length ? beforeResolutionSignatures[0] : null;

                additionalResults.actualParametersContextTypeSymbols = actualParametersContextTypeSymbols;

                this.resolveAST(callEx.argumentList.arguments, false, context);

                if (!couldNotFindGenericOverload) {
                    if (this.cachedFunctionInterfaceType() && this.sourceIsAssignableToTarget(targetTypeSymbol, this.cachedFunctionInterfaceType(), targetAST, context)) {
                        if (callEx.argumentList.typeArgumentList) {
                            this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Non_generic_functions_may_not_accept_type_arguments), additionalResults, context);
                        }
                        return this.semanticInfoChain.anyTypeSymbol;
                    }

                    this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(callEx, TypeScript.DiagnosticCode.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature), additionalResults, context);
                } else if (constraintDiagnostic) {
                    this.postOverloadResolutionDiagnostics(constraintDiagnostic, additionalResults, context);
                } else if (typeArgumentCountDiagnostic) {
                    this.postOverloadResolutionDiagnostics(typeArgumentCountDiagnostic, additionalResults, context);
                } else {
                    this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(callEx, TypeScript.DiagnosticCode.Could_not_select_overload_for_call_expression), additionalResults, context);
                }

                return this.getNewErrorTypeSymbol();
            }

            var signature = this.resolveOverloads(callEx, signatures, callEx.argumentList.typeArgumentList !== null, context, diagnostics);
            var useBeforeResolutionSignatures = signature == null;

            if (!signature) {
                for (var i = 0; i < diagnostics.length; i++) {
                    this.postOverloadResolutionDiagnostics(diagnostics[i], additionalResults, context);
                }

                this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Could_not_select_overload_for_call_expression), additionalResults, context);

                errorCondition = this.getNewErrorTypeSymbol();

                if (!signatures.length) {
                    return errorCondition;
                }

                signature = signatures[0];
            }

            var rootSignature = signature.getRootSymbol();
            if (!rootSignature.isGeneric() && callEx.argumentList.typeArgumentList) {
                this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Non_generic_functions_may_not_accept_type_arguments), additionalResults, context);
            } else if (rootSignature.isGeneric() && callEx.argumentList.typeArgumentList && rootSignature.getTypeParameters() && (callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount() !== rootSignature.getTypeParameters().length)) {
                this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Signature_expected_0_type_arguments_got_1_instead, [rootSignature.getTypeParameters().length, callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount()]), additionalResults, context);
            }

            var returnType = isSuperCall ? this.semanticInfoChain.voidTypeSymbol : signature.returnType;

            var actualParametersContextTypeSymbols = [];
            if (callEx.argumentList.arguments) {
                var len = callEx.argumentList.arguments.nonSeparatorCount();
                var params = signature.parameters;
                var contextualType = null;
                var signatureDecl = signature.getDeclarations()[0];

                for (var i = 0; i < len; i++) {
                    if (params.length) {
                        if (i < params.length - 1 || (i < params.length && !signature.hasVarArgs)) {
                            this.resolveDeclaredSymbol(params[i], context);
                            contextualType = params[i].type;
                        } else if (signature.hasVarArgs) {
                            contextualType = params[params.length - 1].type;
                            if (contextualType.isArrayNamedTypeReference()) {
                                contextualType = contextualType.getElementType();
                            }
                        }
                    }

                    if (contextualType) {
                        context.pushNewContextualType(contextualType);
                        actualParametersContextTypeSymbols[i] = contextualType;
                    }

                    this.resolveAST(callEx.argumentList.arguments.nonSeparatorAt(i), contextualType !== null, context);

                    if (contextualType) {
                        context.popAnyContextualType();
                        contextualType = null;
                    }
                }
            }

            additionalResults.targetSymbol = targetSymbol;
            if (useBeforeResolutionSignatures && beforeResolutionSignatures) {
                additionalResults.resolvedSignatures = beforeResolutionSignatures;
                additionalResults.candidateSignature = beforeResolutionSignatures[0];
            } else {
                additionalResults.resolvedSignatures = signatures;
                additionalResults.candidateSignature = signature;
            }
            additionalResults.actualParametersContextTypeSymbols = actualParametersContextTypeSymbols;

            if (errorCondition) {
                return errorCondition;
            }

            if (!returnType) {
                returnType = this.semanticInfoChain.anyTypeSymbol;
            }

            return returnType;
        };

        PullTypeResolver.prototype.resolveObjectCreationExpression = function (callEx, context, additionalResults) {
            var symbol = this.getSymbolForAST(callEx, context);

            if (!symbol || !symbol.isResolved) {
                if (!additionalResults) {
                    additionalResults = new PullAdditionalCallResolutionData();
                }
                symbol = this.computeObjectCreationExpressionSymbol(callEx, context, additionalResults);
                if (this.canTypeCheckAST(callEx, context)) {
                    this.setTypeChecked(callEx, context);
                }
                this.setSymbolForAST(callEx, symbol, context);
                this.semanticInfoChain.setCallResolutionDataForAST(callEx, additionalResults);
            } else {
                if (this.canTypeCheckAST(callEx, context)) {
                    this.typeCheckObjectCreationExpression(callEx, context);
                }

                var callResolutionData = this.semanticInfoChain.getCallResolutionDataForAST(callEx);
                if (additionalResults && (callResolutionData !== additionalResults)) {
                    additionalResults.actualParametersContextTypeSymbols = callResolutionData.actualParametersContextTypeSymbols;
                    additionalResults.candidateSignature = callResolutionData.candidateSignature;
                    additionalResults.resolvedSignatures = callResolutionData.resolvedSignatures;
                    additionalResults.targetSymbol = callResolutionData.targetSymbol;
                }
            }

            return symbol;
        };

        PullTypeResolver.prototype.typeCheckObjectCreationExpression = function (callEx, context) {
            this.setTypeChecked(callEx, context);
            this.resolveAST(callEx.expression, false, context);
            var callResolutionData = this.semanticInfoChain.getCallResolutionDataForAST(callEx);
            if (callEx.argumentList) {
                var callResolutionData = this.semanticInfoChain.getCallResolutionDataForAST(callEx);
                var len = callEx.argumentList.arguments.nonSeparatorCount();

                for (var i = 0; i < len; i++) {
                    var contextualType = callResolutionData.actualParametersContextTypeSymbols ? callResolutionData.actualParametersContextTypeSymbols[i] : null;
                    if (contextualType) {
                        context.pushNewContextualType(contextualType);
                    }

                    this.resolveAST(callEx.argumentList.arguments.nonSeparatorAt(i), contextualType !== null, context);

                    if (contextualType) {
                        context.popAnyContextualType();
                        contextualType = null;
                    }
                }
            }

            for (var i = 0; i < callResolutionData.diagnosticsFromOverloadResolution.length; i++) {
                context.postDiagnostic(callResolutionData.diagnosticsFromOverloadResolution[i]);
            }
        };

        PullTypeResolver.prototype.postOverloadResolutionDiagnostics = function (diagnostic, additionalResults, context) {
            if (!context.inProvisionalResolution()) {
                additionalResults.diagnosticsFromOverloadResolution.push(diagnostic);
            }
            context.postDiagnostic(diagnostic);
        };

        PullTypeResolver.prototype.computeObjectCreationExpressionSymbol = function (callEx, context, additionalResults) {
            var _this = this;
            var returnType = null;

            var targetSymbol = this.resolveAST(callEx.expression, false, context);
            var targetTypeSymbol = targetSymbol.isType() ? targetSymbol : targetSymbol.type;

            var targetAST = this.getCallTargetErrorSpanAST(callEx);

            var constructSignatures = targetTypeSymbol.getConstructSignatures();

            var explicitTypeArgs = null;
            var usedCallSignaturesInstead = false;
            var couldNotAssignToConstraint;
            var constraintDiagnostic = null;
            var typeArgumentCountDiagnostic = null;
            var diagnostics = [];

            if (this.isAnyOrEquivalent(targetTypeSymbol)) {
                if (callEx.argumentList) {
                    this.resolveAST(callEx.argumentList.arguments, false, context);
                }

                return targetTypeSymbol;
            }

            if (!constructSignatures.length) {
                constructSignatures = targetTypeSymbol.getCallSignatures();
                usedCallSignaturesInstead = true;

                if (this.compilationSettings.noImplicitAny()) {
                    this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(callEx, TypeScript.DiagnosticCode.new_expression_which_lacks_a_constructor_signature_implicitly_has_an_any_type), additionalResults, context);
                }
            }

            if (constructSignatures.length) {
                if (callEx.argumentList && callEx.argumentList.typeArgumentList) {
                    explicitTypeArgs = [];

                    if (callEx.argumentList.typeArgumentList && callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount()) {
                        for (var i = 0; i < callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount(); i++) {
                            explicitTypeArgs[i] = this.resolveTypeReference(callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorAt(i), context);
                        }
                    }
                }

                if (targetTypeSymbol.isGeneric()) {
                    var resolvedSignatures = [];
                    var inferredOrExplicitTypeArgs;
                    var specializedSignature;
                    var typeParameters;
                    var typeConstraint = null;
                    var triedToInferTypeArgs;
                    var targetTypeReplacementMap = targetTypeSymbol.getTypeParameterArgumentMap();

                    for (var i = 0; i < constructSignatures.length; i++) {
                        couldNotAssignToConstraint = false;

                        if (constructSignatures[i].isGeneric()) {
                            typeParameters = constructSignatures[i].getTypeParameters();

                            if (explicitTypeArgs) {
                                if (explicitTypeArgs.length === typeParameters.length) {
                                    inferredOrExplicitTypeArgs = explicitTypeArgs;
                                } else {
                                    typeArgumentCountDiagnostic = typeArgumentCountDiagnostic || this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Signature_expected_0_type_arguments_got_1_instead, [typeParameters.length, explicitTypeArgs.length]);
                                    continue;
                                }
                            } else if (callEx.argumentList) {
                                var typeArgumentInferenceContext = new TypeScript.InvocationTypeArgumentInferenceContext(this, context, constructSignatures[i], callEx.argumentList.arguments);
                                inferredOrExplicitTypeArgs = this.inferArgumentTypesForSignature(typeArgumentInferenceContext, new TypeComparisonInfo(), context);
                                triedToInferTypeArgs = true;
                            } else {
                                inferredOrExplicitTypeArgs = TypeScript.ArrayUtilities.select(typeParameters, function (typeParameter) {
                                    return typeParameter.getDefaultConstraint(_this.semanticInfoChain);
                                });
                            }

                            TypeScript.Debug.assert(inferredOrExplicitTypeArgs && inferredOrExplicitTypeArgs.length == typeParameters.length);

                            var mutableTypeReplacementMap = new TypeScript.PullInstantiationHelpers.MutableTypeArgumentMap(targetTypeReplacementMap ? targetTypeReplacementMap : []);
                            TypeScript.PullInstantiationHelpers.updateMutableTypeParameterArgumentMap(typeParameters, inferredOrExplicitTypeArgs, mutableTypeReplacementMap);
                            var typeReplacementMap = mutableTypeReplacementMap.typeParameterArgumentMap;

                            if (explicitTypeArgs) {
                                for (var j = 0; j < typeParameters.length; j++) {
                                    typeConstraint = typeParameters[j].getConstraint();

                                    if (typeConstraint) {
                                        if (typeConstraint.isGeneric()) {
                                            typeConstraint = this.instantiateType(typeConstraint, typeReplacementMap);
                                        }

                                        if (!this.sourceIsAssignableToTarget(inferredOrExplicitTypeArgs[j], typeConstraint, targetAST, context, null, true)) {
                                            var enclosingSymbol = this.getEnclosingSymbolForAST(targetAST);
                                            constraintDiagnostic = this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Type_0_does_not_satisfy_the_constraint_1_for_type_parameter_2, [inferredOrExplicitTypeArgs[j].toString(enclosingSymbol, true), typeConstraint.toString(enclosingSymbol, true), typeParameters[j].toString(enclosingSymbol, true)]);
                                            couldNotAssignToConstraint = true;
                                        }

                                        if (couldNotAssignToConstraint) {
                                            break;
                                        }
                                    }
                                }
                            }

                            if (couldNotAssignToConstraint) {
                                continue;
                            }

                            specializedSignature = this.instantiateSignature(constructSignatures[i], typeReplacementMap);

                            if (specializedSignature) {
                                resolvedSignatures[resolvedSignatures.length] = specializedSignature;
                            }
                        } else {
                            if (!(callEx.argumentList && callEx.argumentList.typeArgumentList && callEx.argumentList.typeArgumentList.typeArguments.nonSeparatorCount())) {
                                resolvedSignatures[resolvedSignatures.length] = constructSignatures[i];
                            }
                        }
                    }

                    constructSignatures = resolvedSignatures;
                }

                var signature = this.resolveOverloads(callEx, constructSignatures, callEx.argumentList && callEx.argumentList.typeArgumentList !== null, context, diagnostics);

                additionalResults.targetSymbol = targetSymbol;
                additionalResults.resolvedSignatures = constructSignatures;
                additionalResults.candidateSignature = signature;
                additionalResults.actualParametersContextTypeSymbols = [];

                if (!constructSignatures.length) {
                    if (constraintDiagnostic) {
                        this.postOverloadResolutionDiagnostics(constraintDiagnostic, additionalResults, context);
                    } else if (typeArgumentCountDiagnostic) {
                        this.postOverloadResolutionDiagnostics(typeArgumentCountDiagnostic, additionalResults, context);
                    }

                    return this.getNewErrorTypeSymbol();
                }

                var errorCondition = null;

                if (!signature) {
                    for (var i = 0; i < diagnostics.length; i++) {
                        this.postOverloadResolutionDiagnostics(diagnostics[i], additionalResults, context);
                    }

                    this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Could_not_select_overload_for_new_expression), additionalResults, context);

                    errorCondition = this.getNewErrorTypeSymbol();

                    if (!constructSignatures.length) {
                        return errorCondition;
                    }

                    signature = constructSignatures[0];
                }

                returnType = signature.returnType;

                if (returnType && !signature.isGeneric() && returnType.isGeneric() && !returnType.getIsSpecialized()) {
                    if (explicitTypeArgs && explicitTypeArgs.length) {
                        returnType = this.createInstantiatedType(returnType, explicitTypeArgs);
                    } else {
                        returnType = this.instantiateTypeToAny(returnType, context);
                    }
                }

                if (usedCallSignaturesInstead) {
                    if (returnType !== this.semanticInfoChain.voidTypeSymbol) {
                        this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Call_signatures_used_in_a_new_expression_must_have_a_void_return_type), additionalResults, context);

                        return this.getNewErrorTypeSymbol();
                    } else {
                        returnType = this.semanticInfoChain.anyTypeSymbol;
                    }
                }

                if (!returnType) {
                    returnType = signature.returnType;

                    if (!returnType) {
                        returnType = targetTypeSymbol;
                    }
                }

                var actualParametersContextTypeSymbols = [];
                if (callEx.argumentList && callEx.argumentList.arguments) {
                    var len = callEx.argumentList.arguments.nonSeparatorCount();
                    var params = signature.parameters;
                    var contextualType = null;
                    var signatureDecl = signature.getDeclarations()[0];

                    for (var i = 0; i < len; i++) {
                        if (params.length) {
                            if (i < params.length - 1 || (i < params.length && !signature.hasVarArgs)) {
                                this.resolveDeclaredSymbol(params[i], context);
                                contextualType = params[i].type;
                            } else if (signature.hasVarArgs) {
                                contextualType = params[params.length - 1].type;
                                if (contextualType.isArrayNamedTypeReference()) {
                                    contextualType = contextualType.getElementType();
                                }
                            }
                        }

                        if (contextualType) {
                            context.pushNewContextualType(contextualType);
                            actualParametersContextTypeSymbols[i] = contextualType;
                        }

                        this.resolveAST(callEx.argumentList.arguments.nonSeparatorAt(i), contextualType !== null, context);

                        if (contextualType) {
                            context.popAnyContextualType();
                            contextualType = null;
                        }
                    }
                }

                additionalResults.targetSymbol = targetSymbol;
                additionalResults.resolvedSignatures = constructSignatures;
                additionalResults.candidateSignature = signature;
                additionalResults.actualParametersContextTypeSymbols = actualParametersContextTypeSymbols;

                if (errorCondition) {
                    return errorCondition;
                }

                if (!returnType) {
                    returnType = this.semanticInfoChain.anyTypeSymbol;
                }

                return returnType;
            } else if (callEx.argumentList) {
                this.resolveAST(callEx.argumentList.arguments, false, context);
            }

            this.postOverloadResolutionDiagnostics(this.semanticInfoChain.diagnosticFromAST(targetAST, TypeScript.DiagnosticCode.Invalid_new_expression), additionalResults, context);

            return this.getNewErrorTypeSymbol();
        };

        PullTypeResolver.prototype.instantiateSignatureInContext = function (signatureAToInstantiate, contextualSignatureB, context, shouldFixContextualSignatureParameterTypes) {
            var typeReplacementMap = [];
            var inferredTypeArgs;
            var specializedSignature;
            var typeParameters = signatureAToInstantiate.getTypeParameters();
            var typeConstraint = null;

            var typeArgumentInferenceContext = new TypeScript.ContextualSignatureInstantiationTypeArgumentInferenceContext(this, context, signatureAToInstantiate, contextualSignatureB, shouldFixContextualSignatureParameterTypes);
            inferredTypeArgs = this.inferArgumentTypesForSignature(typeArgumentInferenceContext, new TypeComparisonInfo(), context);

            var functionTypeA = signatureAToInstantiate.functionType;
            var functionTypeB = contextualSignatureB.functionType;
            var enclosingTypeParameterMap;

            if (functionTypeA) {
                enclosingTypeParameterMap = functionTypeA.getTypeParameterArgumentMap();

                for (var id in enclosingTypeParameterMap) {
                    typeReplacementMap[id] = enclosingTypeParameterMap[id];
                }
            }

            if (functionTypeB) {
                enclosingTypeParameterMap = functionTypeB.getTypeParameterArgumentMap();

                for (var id in enclosingTypeParameterMap) {
                    typeReplacementMap[id] = enclosingTypeParameterMap[id];
                }
            }

            TypeScript.PullInstantiationHelpers.updateTypeParameterArgumentMap(typeParameters, inferredTypeArgs, typeReplacementMap);

            return this.instantiateSignature(signatureAToInstantiate, typeReplacementMap);
        };

        PullTypeResolver.prototype.resolveCastExpression = function (assertionExpression, context) {
            var typeAssertionType = this.resolveTypeReference(assertionExpression.type, context).type;

            if (this.canTypeCheckAST(assertionExpression, context)) {
                this.typeCheckCastExpression(assertionExpression, context, typeAssertionType);
            }

            return typeAssertionType;
        };

        PullTypeResolver.prototype.typeCheckCastExpression = function (assertionExpression, context, typeAssertionType) {
            this.setTypeChecked(assertionExpression, context);

            context.pushNewContextualType(typeAssertionType);
            var exprType = this.resolveAST(assertionExpression.expression, true, context).type;
            context.popAnyContextualType();

            this.resolveDeclaredSymbol(typeAssertionType, context);
            this.resolveDeclaredSymbol(exprType, context);

            var comparisonInfo = new TypeComparisonInfo();

            var isAssignable = this.sourceIsAssignableToTarget(exprType, typeAssertionType, assertionExpression, context, comparisonInfo);

            if (!isAssignable) {
                var widenedExprType = exprType.widenedType(this, assertionExpression.expression, context);
                isAssignable = this.sourceIsAssignableToTarget(typeAssertionType, widenedExprType, assertionExpression, context, comparisonInfo);
            }

            if (!isAssignable) {
                var enclosingSymbol = this.getEnclosingSymbolForAST(assertionExpression);
                if (comparisonInfo.message) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(assertionExpression, TypeScript.DiagnosticCode.Cannot_convert_0_to_1_NL_2, [exprType.toString(enclosingSymbol), typeAssertionType.toString(enclosingSymbol), comparisonInfo.message]));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(assertionExpression, TypeScript.DiagnosticCode.Cannot_convert_0_to_1, [exprType.toString(enclosingSymbol), typeAssertionType.toString(enclosingSymbol)]));
                }
            }
        };

        PullTypeResolver.prototype.resolveAssignmentExpression = function (binaryExpression, context) {
            var leftExpr = this.resolveAST(binaryExpression.left, false, context);
            var leftType = leftExpr.type;

            context.pushNewContextualType(leftType);
            var rightType = this.resolveAST(binaryExpression.right, true, context).type;
            context.popAnyContextualType();

            rightType = this.getInstanceTypeForAssignment(binaryExpression.left, rightType, context);

            if (this.canTypeCheckAST(binaryExpression, context)) {
                this.setTypeChecked(binaryExpression, context);

                if (!this.isReference(binaryExpression.left, leftExpr)) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(binaryExpression.left, TypeScript.DiagnosticCode.Invalid_left_hand_side_of_assignment_expression));
                } else {
                    this.checkAssignability(binaryExpression.left, rightType, leftExpr.type, context);
                }
            }

            return rightType;
        };

        PullTypeResolver.prototype.getInstanceTypeForAssignment = function (lhs, type, context) {
            var typeToReturn = type;
            if (typeToReturn && typeToReturn.isAlias()) {
                typeToReturn = typeToReturn.getExportAssignedTypeSymbol();
            }

            if (typeToReturn && typeToReturn.isContainer() && !typeToReturn.isEnum()) {
                var instanceTypeSymbol = typeToReturn.getInstanceType();

                if (!instanceTypeSymbol) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(lhs, TypeScript.DiagnosticCode.Tried_to_set_variable_type_to_uninitialized_module_type_0, [type.toString()]));
                    typeToReturn = null;
                } else {
                    typeToReturn = instanceTypeSymbol;
                }
            }

            return typeToReturn;
        };

        PullTypeResolver.prototype.widenType = function (type, ast, context) {
            if (type === this.semanticInfoChain.undefinedTypeSymbol || type === this.semanticInfoChain.nullTypeSymbol || type.isError()) {
                return this.semanticInfoChain.anyTypeSymbol;
            }

            if (type.isArrayNamedTypeReference()) {
                return this.widenArrayType(type, ast, context);
            } else if (type.kind === 256 /* ObjectLiteral */) {
                return this.widenObjectLiteralType(type, ast, context);
            }

            return type;
        };

        PullTypeResolver.prototype.widenArrayType = function (type, ast, context) {
            var elementType = type.getElementType().widenedType(this, ast, context);

            if (this.compilationSettings.noImplicitAny() && ast) {
                if (elementType === this.semanticInfoChain.anyTypeSymbol && type.getElementType() !== this.semanticInfoChain.anyTypeSymbol) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Array_Literal_implicitly_has_an_any_type_from_widening));
                }
            }

            return this.getArrayType(elementType);
        };

        PullTypeResolver.prototype.widenObjectLiteralType = function (type, ast, context) {
            if (!this.needsToWidenObjectLiteralType(type, ast, context)) {
                return type;
            }

            TypeScript.Debug.assert(type.name === "");
            var newObjectTypeSymbol = new TypeScript.PullTypeSymbol(type.name, type.kind);
            var declsOfObjectType = type.getDeclarations();
            TypeScript.Debug.assert(declsOfObjectType.length === 1);
            newObjectTypeSymbol.addDeclaration(declsOfObjectType[0]);
            var members = type.getMembers();

            for (var i = 0; i < members.length; i++) {
                var memberType = members[i].type;

                var widenedMemberType = members[i].type.widenedType(this, ast, context);
                var newMember = new TypeScript.PullSymbol(members[i].name, members[i].kind);

                var declsOfMember = members[i].getDeclarations();

                newMember.addDeclaration(declsOfMember[0]);
                newMember.type = widenedMemberType;
                newObjectTypeSymbol.addMember(newMember);
                newMember.setResolved();

                if (this.compilationSettings.noImplicitAny() && ast && widenedMemberType === this.semanticInfoChain.anyTypeSymbol && memberType !== this.semanticInfoChain.anyTypeSymbol) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Object_literal_s_property_0_implicitly_has_an_any_type_from_widening, [members[i].name]));
                }
            }

            var indexers = type.getIndexSignatures();
            for (var i = 0; i < indexers.length; i++) {
                var newIndexer = new TypeScript.PullSignatureSymbol(4194304 /* IndexSignature */);
                var parameter = indexers[i].parameters[0];
                var newParameter = new TypeScript.PullSymbol(parameter.name, parameter.kind);
                newParameter.type = parameter.type;
                newIndexer.addParameter(newParameter);
                newIndexer.returnType = indexers[i].returnType;
                newObjectTypeSymbol.addIndexSignature(newIndexer);
            }

            return newObjectTypeSymbol;
        };

        PullTypeResolver.prototype.needsToWidenObjectLiteralType = function (type, ast, context) {
            var members = type.getMembers();
            for (var i = 0; i < members.length; i++) {
                var memberType = members[i].type;
                if (memberType !== memberType.widenedType(this, ast, context)) {
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.findBestCommonType = function (collection, context, comparisonInfo) {
            var len = collection.getLength();

            for (var i = 0; i < len; i++) {
                var candidateType = collection.getTypeAtIndex(i);
                if (this.typeIsBestCommonTypeCandidate(candidateType, collection, context)) {
                    return candidateType;
                }
            }

            return this.semanticInfoChain.emptyTypeSymbol;
        };

        PullTypeResolver.prototype.typeIsBestCommonTypeCandidate = function (candidateType, collection, context) {
            for (var i = 0; i < collection.getLength(); i++) {
                var otherType = collection.getTypeAtIndex(i);
                if (candidateType === otherType) {
                    continue;
                }

                if (!this.sourceIsSubtypeOfTarget(otherType, candidateType, null, context)) {
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.typesAreIdenticalInEnclosingTypes = function (t1, t2, context) {
            t1 = this.getSymbolForRelationshipCheck(t1);
            t2 = this.getSymbolForRelationshipCheck(t2);

            if (t1 === t2) {
                return true;
            }

            if (t1 && t2) {
                if (context.oneOfClassificationsIsInfinitelyExpanding()) {
                    return this.infinitelyExpandingTypesAreIdentical(t1, t2, context);
                }
            }

            return this.typesAreIdentical(t1, t2, context);
        };

        PullTypeResolver.prototype.typesAreIdenticalWithNewEnclosingTypes = function (t1, t2, context) {
            var enclosingTypeWalkerStates = context.resetEnclosingTypeWalkerStates();
            var areTypesIdentical = this.typesAreIdentical(t1, t2, context);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return areTypesIdentical;
        };

        PullTypeResolver.prototype.typesAreIdentical = function (t1, t2, context) {
            t1 = this.getSymbolForRelationshipCheck(t1);
            t2 = this.getSymbolForRelationshipCheck(t2);

            if (t1 === t2) {
                return true;
            }

            if (!t1 || !t2) {
                return false;
            }

            if (TypeScript.hasFlag(t1.kind, 64 /* Enum */) || TypeScript.hasFlag(t2.kind, 64 /* Enum */)) {
                return false;
            }

            if (t1.isPrimitive() && t1.isStringConstant() && t2.isPrimitive() && t2.isStringConstant()) {
                return TypeScript.stripStartAndEndQuotes(t1.name) === TypeScript.stripStartAndEndQuotes(t2.name);
            }

            if (t1.isPrimitive() || t2.isPrimitive()) {
                return false;
            }

            if (t1.isError() && t2.isError()) {
                return true;
            }

            var isIdentical = this.identicalCache.valueAt(t1.pullSymbolID, t2.pullSymbolID);
            if (isIdentical != undefined) {
                return isIdentical;
            }

            if (t1.isTypeParameter() !== t2.isTypeParameter()) {
                return false;
            } else if (t1.isTypeParameter()) {
                var t1ParentDeclaration = t1.getDeclarations()[0].getParentDecl();
                var t2ParentDeclaration = t2.getDeclarations()[0].getParentDecl();

                if (t1ParentDeclaration === t2ParentDeclaration) {
                    return this.symbolsShareDeclaration(t1, t2);
                } else {
                    return false;
                }
            }

            if (t1.isPrimitive() !== t2.isPrimitive()) {
                return false;
            }

            this.identicalCache.setValueAt(t1.pullSymbolID, t2.pullSymbolID, true);
            var statesWhenStartedWalkingTypes = context.startWalkingTypes(t1, t2);
            isIdentical = this.typesAreIdenticalWorker(t1, t2, context);
            context.endWalkingTypes(statesWhenStartedWalkingTypes);
            this.identicalCache.setValueAt(t1.pullSymbolID, t2.pullSymbolID, isIdentical);

            return isIdentical;
        };

        PullTypeResolver.prototype.typesAreIdenticalWorker = function (t1, t2, context) {
            if (t1.getIsSpecialized() && t2.getIsSpecialized()) {
                if (TypeScript.PullHelpers.getRootType(t1) === TypeScript.PullHelpers.getRootType(t2) && TypeScript.PullHelpers.getRootType(t1).isNamedTypeSymbol()) {
                    var t1TypeArguments = t1.getTypeArguments();
                    var t2TypeArguments = t2.getTypeArguments();

                    if (t1TypeArguments && t2TypeArguments) {
                        for (var i = 0; i < t1TypeArguments.length; i++) {
                            if (!this.typesAreIdenticalWithNewEnclosingTypes(t1TypeArguments[i], t2TypeArguments[i], context)) {
                                return false;
                            }
                        }
                    }

                    return true;
                }
            }

            if (t1.hasMembers() && t2.hasMembers()) {
                var t1Members = t1.getAllMembers(68147712 /* SomeValue */, 0 /* all */);
                var t2Members = t2.getAllMembers(68147712 /* SomeValue */, 0 /* all */);

                if (t1Members.length !== t2Members.length) {
                    return false;
                }

                var t1MemberSymbol = null;
                var t2MemberSymbol = null;

                var t1MemberType = null;
                var t2MemberType = null;

                for (var iMember = 0; iMember < t1Members.length; iMember++) {
                    t1MemberSymbol = t1Members[iMember];
                    t2MemberSymbol = this.getNamedPropertySymbol(t1MemberSymbol.name, 68147712 /* SomeValue */, t2);

                    if (!this.propertiesAreIdentical(t1MemberSymbol, t2MemberSymbol, context)) {
                        return false;
                    }
                }
            } else if (t1.hasMembers() || t2.hasMembers()) {
                return false;
            }

            var t1CallSigs = t1.getCallSignatures();
            var t2CallSigs = t2.getCallSignatures();

            var t1ConstructSigs = t1.getConstructSignatures();
            var t2ConstructSigs = t2.getConstructSignatures();

            var t1IndexSigs = t1.getIndexSignatures();
            var t2IndexSigs = t2.getIndexSignatures();

            if (!this.signatureGroupsAreIdentical(t1CallSigs, t2CallSigs, context)) {
                return false;
            }

            if (!this.signatureGroupsAreIdentical(t1ConstructSigs, t2ConstructSigs, context)) {
                return false;
            }

            if (!this.signatureGroupsAreIdentical(t1IndexSigs, t2IndexSigs, context)) {
                return false;
            }

            return true;
        };

        PullTypeResolver.prototype.propertiesAreIdentical = function (propertySymbol1, propertySymbol2, context) {
            if (!propertySymbol2 || (propertySymbol1.isOptional !== propertySymbol2.isOptional)) {
                return false;
            }

            var t1MemberSymbolIsPrivate = propertySymbol1.anyDeclHasFlag(2 /* Private */);
            var t2MemberSymbolIsPrivate = propertySymbol2.anyDeclHasFlag(2 /* Private */);

            if (t1MemberSymbolIsPrivate !== t2MemberSymbolIsPrivate) {
                return false;
            } else if (t2MemberSymbolIsPrivate && t1MemberSymbolIsPrivate) {
                var t1MemberSymbolDecl = propertySymbol1.getDeclarations()[0];
                var sourceDecl = propertySymbol2.getDeclarations()[0];
                if (t1MemberSymbolDecl !== sourceDecl) {
                    return false;
                }
            }

            var t1MemberType = propertySymbol1.type;
            var t2MemberType = propertySymbol2.type;

            context.walkMemberTypes(propertySymbol1.name);
            var areMemberTypesIdentical = this.typesAreIdenticalInEnclosingTypes(t1MemberType, t2MemberType, context);
            context.postWalkMemberTypes();
            return areMemberTypesIdentical;
        };

        PullTypeResolver.prototype.propertiesAreIdenticalWithNewEnclosingTypes = function (type1, type2, property1, property2, context) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(type1, type2);
            var arePropertiesIdentical = this.propertiesAreIdentical(property1, property2, context);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return arePropertiesIdentical;
        };

        PullTypeResolver.prototype.signatureGroupsAreIdentical = function (sg1, sg2, context) {
            if (sg1 === sg2) {
                return true;
            }

            if (!sg1 || !sg2) {
                return false;
            }

            if (sg1.length !== sg2.length) {
                return false;
            }

            for (var i = 0; i < sg1.length; i++) {
                context.walkSignatures(sg1[i].kind, i);
                var areSignaturesIdentical = this.signaturesAreIdentical(sg1[i], sg2[i], context, true);
                context.postWalkSignatures();
                if (!areSignaturesIdentical) {
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.typeParametersAreIdentical = function (tp1, tp2, context) {
            var typeParamsAreIdentical = this.typeParametersAreIdenticalWorker(tp1, tp2, context);

            this.setTypeParameterIdentity(tp1, tp2, undefined);

            return typeParamsAreIdentical;
        };

        PullTypeResolver.prototype.typeParametersAreIdenticalWorker = function (tp1, tp2, context) {
            if (!!(tp1 && tp1.length) !== !!(tp2 && tp2.length)) {
                return false;
            }

            if (tp1 && tp2 && (tp1.length !== tp2.length)) {
                return false;
            }

            if (tp1 && tp2) {
                for (var i = 0; i < tp1.length; i++) {
                    context.walkTypeParameterConstraints(i);
                    var areConstraintsIdentical = this.typesAreIdentical(tp1[i].getConstraint(), tp2[i].getConstraint(), context);
                    context.postWalkTypeParameterConstraints();
                    if (!areConstraintsIdentical) {
                        return false;
                    }
                }
            }

            return true;
        };

        PullTypeResolver.prototype.setTypeParameterIdentity = function (tp1, tp2, val) {
            if (tp1 && tp2 && tp1.length === tp2.length) {
                for (var i = 0; i < tp1.length; i++) {
                    this.identicalCache.setValueAt(tp1[i].pullSymbolID, tp2[i].pullSymbolID, val);
                }
            }
        };

        PullTypeResolver.prototype.signaturesAreIdenticalWithNewEnclosingTypes = function (s1, s2, context, includingReturnType) {
            if (typeof includingReturnType === "undefined") { includingReturnType = true; }
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(s1, s2);
            var areSignaturesIdentical = this.signaturesAreIdentical(s1, s2, context, includingReturnType);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return areSignaturesIdentical;
        };

        PullTypeResolver.prototype.signaturesAreIdentical = function (s1, s2, context, includingReturnType) {
            if (typeof includingReturnType === "undefined") { includingReturnType = true; }
            if (s1 === s2) {
                return true;
            }

            var signaturesIdentical = this.identicalCache.valueAt(s1.pullSymbolID, s2.pullSymbolID);
            if (signaturesIdentical || (signaturesIdentical != undefined && includingReturnType)) {
                return signaturesIdentical;
            }

            var oldValue = signaturesIdentical;
            this.identicalCache.setValueAt(s1.pullSymbolID, s2.pullSymbolID, true);

            signaturesIdentical = this.signaturesAreIdenticalWorker(s1, s2, context, includingReturnType);

            if (includingReturnType) {
                this.identicalCache.setValueAt(s1.pullSymbolID, s2.pullSymbolID, signaturesIdentical);
            } else {
                this.identicalCache.setValueAt(s1.pullSymbolID, s2.pullSymbolID, oldValue);
            }

            return signaturesIdentical;
        };

        PullTypeResolver.prototype.signaturesAreIdenticalWorker = function (s1, s2, context, includingReturnType) {
            if (typeof includingReturnType === "undefined") { includingReturnType = true; }
            if (s1.hasVarArgs !== s2.hasVarArgs) {
                return false;
            }

            if (s1.nonOptionalParamCount !== s2.nonOptionalParamCount) {
                return false;
            }

            if (s1.parameters.length !== s2.parameters.length) {
                return false;
            }

            var s1TypeParameters = s1.getTypeParameters();
            var s2TypeParameters = s2.getTypeParameters();
            this.setTypeParameterIdentity(s1TypeParameters, s2TypeParameters, true);

            var typeParametersParametersAndReturnTypesAreIdentical = this.signatureTypeParametersParametersAndReturnTypesAreIdentical(s1, s2, context, includingReturnType);

            this.setTypeParameterIdentity(s1TypeParameters, s2TypeParameters, undefined);
            return typeParametersParametersAndReturnTypesAreIdentical;
        };

        PullTypeResolver.prototype.signatureTypeParametersParametersAndReturnTypesAreIdentical = function (s1, s2, context, includingReturnType) {
            if (!this.typeParametersAreIdenticalWorker(s1.getTypeParameters(), s2.getTypeParameters(), context)) {
                return false;
            }

            if (includingReturnType) {
                TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(s1);
                TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(s2);
                context.walkReturnTypes();
                var areReturnTypesIdentical = this.typesAreIdenticalInEnclosingTypes(s1.returnType, s2.returnType, context);
                context.postWalkReturnTypes();
                if (!areReturnTypesIdentical) {
                    return false;
                }
            }

            var s1Params = s1.parameters;
            var s2Params = s2.parameters;

            for (var iParam = 0; iParam < s1Params.length; iParam++) {
                TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(s1Params[iParam]);
                TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(s2Params[iParam]);
                context.walkParameterTypes(iParam);
                var areParameterTypesIdentical = this.typesAreIdenticalInEnclosingTypes(s1Params[iParam].type, s2Params[iParam].type, context);
                context.postWalkParameterTypes();

                if (!areParameterTypesIdentical) {
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.signatureReturnTypesAreIdentical = function (s1, s2, context) {
            var s1TypeParameters = s1.getTypeParameters();
            var s2TypeParameters = s2.getTypeParameters();
            this.setTypeParameterIdentity(s1TypeParameters, s2TypeParameters, true);

            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(s1, s2);
            context.walkReturnTypes();
            var returnTypeIsIdentical = this.typesAreIdenticalInEnclosingTypes(s1.returnType, s2.returnType, context);

            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);

            this.setTypeParameterIdentity(s1TypeParameters, s2TypeParameters, undefined);

            return returnTypeIsIdentical;
        };

        PullTypeResolver.prototype.symbolsShareDeclaration = function (symbol1, symbol2) {
            var decls1 = symbol1.getDeclarations();
            var decls2 = symbol2.getDeclarations();

            if (decls1.length && decls2.length) {
                return decls1[0] === decls2[0];
            }

            return false;
        };

        PullTypeResolver.prototype.sourceIsSubtypeOfTarget = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            return this.sourceIsRelatableToTarget(source, target, false, this.subtypeCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
        };

        PullTypeResolver.prototype.sourceMembersAreAssignableToTargetMembers = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(source, target);
            var areSourceMembersAreAssignableToTargetMembers = this.sourceMembersAreRelatableToTargetMembers(source, target, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return areSourceMembersAreAssignableToTargetMembers;
        };

        PullTypeResolver.prototype.sourcePropertyIsAssignableToTargetProperty = function (source, target, sourceProp, targetProp, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(source, target);
            var isSourcePropertyIsAssignableToTargetProperty = this.sourcePropertyIsRelatableToTargetProperty(source, target, sourceProp, targetProp, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return isSourcePropertyIsAssignableToTargetProperty;
        };

        PullTypeResolver.prototype.sourceCallSignaturesAreAssignableToTargetCallSignatures = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(source, target);
            var areSourceCallSignaturesAssignableToTargetCallSignatures = this.sourceCallSignaturesAreRelatableToTargetCallSignatures(source, target, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return areSourceCallSignaturesAssignableToTargetCallSignatures;
        };

        PullTypeResolver.prototype.sourceConstructSignaturesAreAssignableToTargetConstructSignatures = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(source, target);
            var areSourceConstructSignaturesAssignableToTargetConstructSignatures = this.sourceConstructSignaturesAreRelatableToTargetConstructSignatures(source, target, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return areSourceConstructSignaturesAssignableToTargetConstructSignatures;
        };

        PullTypeResolver.prototype.sourceIndexSignaturesAreAssignableToTargetIndexSignatures = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(source, target);
            var areSourceIndexSignaturesAssignableToTargetIndexSignatures = this.sourceIndexSignaturesAreRelatableToTargetIndexSignatures(source, target, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return areSourceIndexSignaturesAssignableToTargetIndexSignatures;
        };

        PullTypeResolver.prototype.typeIsAssignableToFunction = function (source, ast, context) {
            if (source.isFunctionType()) {
                return true;
            }

            return this.cachedFunctionInterfaceType() && this.sourceIsAssignableToTarget(source, this.cachedFunctionInterfaceType(), ast, context);
        };

        PullTypeResolver.prototype.signatureIsAssignableToTarget = function (s1, s2, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.setEnclosingTypeForSymbols(s1, s2);
            var isSignatureIsAssignableToTarget = this.signatureIsRelatableToTarget(s1, s2, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return isSignatureIsAssignableToTarget;
        };

        PullTypeResolver.prototype.sourceIsAssignableToTarget = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            return this.sourceIsRelatableToTarget(source, target, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
        };

        PullTypeResolver.prototype.sourceIsAssignableToTargetWithNewEnclosingTypes = function (source, target, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            return this.sourceIsRelatableToTargetWithNewEnclosingTypes(source, target, true, this.assignableCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
        };

        PullTypeResolver.prototype.getSymbolForRelationshipCheck = function (symbol) {
            if (symbol && symbol.isTypeReference()) {
                return symbol.getReferencedTypeSymbol();
            }

            return symbol;
        };

        PullTypeResolver.prototype.sourceIsRelatableToTargetInEnclosingTypes = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            source = this.getSymbolForRelationshipCheck(source);
            target = this.getSymbolForRelationshipCheck(target);

            if (source === target) {
                return true;
            }

            if (source && target) {
                if (context.oneOfClassificationsIsInfinitelyExpanding()) {
                    return this.infinitelyExpandingSourceTypeIsRelatableToTargetType(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
                }
            }

            return this.sourceIsRelatableToTarget(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
        };

        PullTypeResolver.prototype.sourceIsRelatableToTargetWithNewEnclosingTypes = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var enclosingTypeWalkerStates = context.resetEnclosingTypeWalkerStates();
            var isSourceRelatable = this.sourceIsRelatableToTarget(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
            return isSourceRelatable;
        };

        PullTypeResolver.prototype.sourceIsRelatableToTargetInCache = function (source, target, comparisonCache, comparisonInfo) {
            var isRelatable = comparisonCache.valueAt(source.pullSymbolID, target.pullSymbolID);

            if (isRelatable) {
                return { isRelatable: isRelatable };
            }

            if (isRelatable != undefined && !comparisonInfo) {
                return { isRelatable: isRelatable };
            }

            return null;
        };

        PullTypeResolver.prototype.sourceIsRelatableToTarget = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            source = this.getSymbolForRelationshipCheck(source);
            target = this.getSymbolForRelationshipCheck(target);

            if (source === target) {
                return true;
            }

            if (!(source && target)) {
                return true;
            }

            var sourceApparentType = this.getApparentType(source);

            var isRelatableInfo = this.sourceIsRelatableToTargetInCache(source, target, comparisonCache, comparisonInfo);
            if (isRelatableInfo) {
                return isRelatableInfo.isRelatable;
            }

            if (source === this.semanticInfoChain.stringTypeSymbol && target.isPrimitive() && target.isStringConstant()) {
                return comparisonInfo && comparisonInfo.stringConstantVal && (comparisonInfo.stringConstantVal.kind() === 14 /* StringLiteral */) && (TypeScript.stripStartAndEndQuotes(comparisonInfo.stringConstantVal.text()) === TypeScript.stripStartAndEndQuotes(target.name));
            }

            if (assignableTo) {
                if (this.isAnyOrEquivalent(source) || this.isAnyOrEquivalent(target)) {
                    return true;
                }
            } else {
                if (this.isAnyOrEquivalent(target)) {
                    return true;
                }
            }

            if (target === this.semanticInfoChain.stringTypeSymbol && source.isPrimitive() && source.isStringConstant()) {
                return true;
            }

            if (source.isPrimitive() && source.isStringConstant() && target.isPrimitive() && target.isStringConstant()) {
                return TypeScript.stripStartAndEndQuotes(source.name) === TypeScript.stripStartAndEndQuotes(target.name);
            }

            if (source === this.semanticInfoChain.undefinedTypeSymbol) {
                return true;
            }

            if ((source === this.semanticInfoChain.nullTypeSymbol) && (target !== this.semanticInfoChain.undefinedTypeSymbol && target != this.semanticInfoChain.voidTypeSymbol)) {
                return true;
            }

            if (target === this.semanticInfoChain.voidTypeSymbol) {
                if (source === this.semanticInfoChain.undefinedTypeSymbol || source == this.semanticInfoChain.nullTypeSymbol) {
                    return true;
                }

                return false;
            } else if (source === this.semanticInfoChain.voidTypeSymbol) {
                if (target === this.semanticInfoChain.anyTypeSymbol) {
                    return true;
                }

                return false;
            }

            if (target === this.semanticInfoChain.numberTypeSymbol && TypeScript.PullHelpers.symbolIsEnum(source)) {
                return true;
            }

            if (source === this.semanticInfoChain.numberTypeSymbol && TypeScript.PullHelpers.symbolIsEnum(target)) {
                return assignableTo;
            }

            if (TypeScript.PullHelpers.symbolIsEnum(target) && TypeScript.PullHelpers.symbolIsEnum(source)) {
                return this.symbolsShareDeclaration(target, source);
            }

            if ((source.kind & 64 /* Enum */) || (target.kind & 64 /* Enum */)) {
                return false;
            }

            if (source.getIsSpecialized() && target.getIsSpecialized()) {
                if (TypeScript.PullHelpers.getRootType(source) === TypeScript.PullHelpers.getRootType(target) && TypeScript.PullHelpers.getRootType(source).isNamedTypeSymbol()) {
                    var sourceTypeArguments = source.getTypeArguments();
                    var targetTypeArguments = target.getTypeArguments();

                    if (sourceTypeArguments && targetTypeArguments) {
                        comparisonCache.setValueAt(source.pullSymbolID, target.pullSymbolID, true);

                        for (var i = 0; i < sourceTypeArguments.length; i++) {
                            if (!this.sourceIsRelatableToTargetWithNewEnclosingTypes(sourceTypeArguments[i], targetTypeArguments[i], assignableTo, comparisonCache, ast, context, null, isComparingInstantiatedSignatures)) {
                                break;
                            }
                        }

                        if (i === sourceTypeArguments.length) {
                            return true;
                        } else {
                            comparisonCache.setValueAt(source.pullSymbolID, target.pullSymbolID, undefined);
                        }
                    }
                }
            }

            if (target.isTypeParameter()) {
                if (source.isTypeParameter()) {
                    if (!source.getConstraint()) {
                        return this.typesAreIdentical(target, source, context);
                    } else {
                        return this.isSourceTypeParameterConstrainedToTargetTypeParameter(source, target);
                    }
                } else {
                    if (isComparingInstantiatedSignatures) {
                        target = target.getBaseConstraint(this.semanticInfoChain);
                    } else {
                        return this.typesAreIdentical(target, sourceApparentType, context);
                    }
                }
            }

            if (sourceApparentType.isPrimitive() || target.isPrimitive()) {
                return false;
            }

            comparisonCache.setValueAt(source.pullSymbolID, target.pullSymbolID, true);

            var symbolsWhenStartedWalkingTypes = context.startWalkingTypes(sourceApparentType, target);
            var isRelatable = this.sourceIsRelatableToTargetWorker(sourceApparentType, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            context.endWalkingTypes(symbolsWhenStartedWalkingTypes);

            comparisonCache.setValueAt(source.pullSymbolID, target.pullSymbolID, isRelatable);
            return isRelatable;
        };

        PullTypeResolver.prototype.isSourceTypeParameterConstrainedToTargetTypeParameter = function (source, target) {
            var current = source;
            while (current && current.isTypeParameter()) {
                if (current === target) {
                    return true;
                }

                current = current.getConstraint();
            }
            return false;
        };

        PullTypeResolver.prototype.sourceIsRelatableToTargetWorker = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            if (target.hasMembers() && !this.sourceMembersAreRelatableToTargetMembers(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures)) {
                return false;
            }

            if (!this.sourceCallSignaturesAreRelatableToTargetCallSignatures(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures)) {
                return false;
            }

            if (!this.sourceConstructSignaturesAreRelatableToTargetConstructSignatures(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures)) {
                return false;
            }

            if (!this.sourceIndexSignaturesAreRelatableToTargetIndexSignatures(source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures)) {
                return false;
            }

            return true;
        };

        PullTypeResolver.prototype.sourceMembersAreRelatableToTargetMembers = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var targetProps = target.getAllMembers(68147712 /* SomeValue */, 0 /* all */);

            for (var itargetProp = 0; itargetProp < targetProps.length; itargetProp++) {
                var targetProp = targetProps[itargetProp];

                var sourceProp = this._getNamedPropertySymbolOfAugmentedType(targetProp.name, source);

                this.resolveDeclaredSymbol(targetProp, context);

                var targetPropType = targetProp.type;

                if (!sourceProp) {
                    if (!(targetProp.isOptional)) {
                        if (comparisonInfo) {
                            var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                            comparisonInfo.flags |= 2 /* RequiredPropertyIsMissing */;
                            comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Type_0_is_missing_property_1_from_type_2, [source.toString(enclosingSymbol), targetProp.getScopedNameEx().toString(), target.toString(enclosingSymbol)]));
                        }
                        return false;
                    }
                    continue;
                }

                if (!this.sourcePropertyIsRelatableToTargetProperty(source, target, sourceProp, targetProp, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures)) {
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.infinitelyExpandingSourceTypeIsRelatableToTargetType = function (sourceType, targetType, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var widenedTargetType = targetType.widenedType(this, null, context);
            var widenedSourceType = sourceType.widenedType(this, null, context);

            if ((widenedSourceType !== this.semanticInfoChain.anyTypeSymbol) && (widenedTargetType !== this.semanticInfoChain.anyTypeSymbol)) {
                var sourceTypeNamedTypeReference = TypeScript.PullHelpers.getRootType(sourceType);
                var targetTypeNamedTypeReference = TypeScript.PullHelpers.getRootType(targetType);

                if (sourceTypeNamedTypeReference !== targetTypeNamedTypeReference) {
                    comparisonCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, false);
                    if (comparisonInfo) {
                        var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                        comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Types_0_and_1_originating_in_infinitely_expanding_type_reference_do_not_refer_to_same_named_type, [sourceType.getScopedNameEx(enclosingSymbol).toString(), targetType.toString(enclosingSymbol)]));
                    }
                    return false;
                }

                var sourceTypeArguments = sourceType.getTypeArguments();
                var targetTypeArguments = targetType.getTypeArguments();

                if (!sourceTypeArguments && !targetTypeArguments) {
                    comparisonCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, true);
                    return true;
                }

                if (!(sourceTypeArguments && targetTypeArguments) || sourceTypeArguments.length !== targetTypeArguments.length) {
                    comparisonCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, false);
                    if (comparisonInfo) {
                        var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                        comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Types_0_and_1_originating_in_infinitely_expanding_type_reference_have_incompatible_type_arguments, [sourceType.toString(enclosingSymbol), targetType.toString(enclosingSymbol)]));
                    }
                    return false;
                }

                var comparisonInfoTypeArgumentsCheck = null;
                if (comparisonInfo && !comparisonInfo.onlyCaptureFirstError) {
                    comparisonInfoTypeArgumentsCheck = new TypeComparisonInfo(comparisonInfo);
                }
                var isRelatable = true;
                for (var i = 0; i < sourceTypeArguments.length && isRelatable; i++) {
                    context.walkTypeArgument(i);

                    if (!this.sourceIsRelatableToTargetInEnclosingTypes(sourceTypeArguments[i], targetTypeArguments[i], assignableTo, comparisonCache, ast, context, comparisonInfoTypeArgumentsCheck, isComparingInstantiatedSignatures)) {
                        isRelatable = false;
                        if (comparisonInfo) {
                            var message;
                            var enclosingSymbol = this.getEnclosingSymbolForAST(ast);

                            if (comparisonInfoTypeArgumentsCheck && comparisonInfoTypeArgumentsCheck.message) {
                                message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Types_0_and_1_originating_in_infinitely_expanding_type_reference_have_incompatible_type_arguments_NL_2, [sourceType.toString(enclosingSymbol), targetType.toString(enclosingSymbol), comparisonInfoTypeArgumentsCheck.message]);
                            } else {
                                message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Types_0_and_1_originating_in_infinitely_expanding_type_reference_have_incompatible_type_arguments, [sourceType.toString(enclosingSymbol), targetType.toString(enclosingSymbol)]);
                            }
                            comparisonInfo.addMessage(message);
                        }
                    }

                    context.postWalkTypeArgument();
                }
            }

            comparisonCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, isRelatable);
            return isRelatable;
        };

        PullTypeResolver.prototype.infinitelyExpandingTypesAreIdentical = function (sourceType, targetType, context) {
            var widenedTargetType = targetType.widenedType(this, null, null);
            var widenedSourceType = sourceType.widenedType(this, null, null);

            if ((widenedSourceType !== this.semanticInfoChain.anyTypeSymbol) && (widenedTargetType !== this.semanticInfoChain.anyTypeSymbol)) {
                var sourceTypeNamedTypeReference = TypeScript.PullHelpers.getRootType(sourceType);
                var targetTypeNamedTypeReference = TypeScript.PullHelpers.getRootType(targetType);
                if (sourceTypeNamedTypeReference !== targetTypeNamedTypeReference) {
                    this.identicalCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, false);
                    return false;
                }

                var sourceTypeArguments = sourceType.getTypeArguments();
                var targetTypeArguments = targetType.getTypeArguments();

                if (!sourceTypeArguments && !targetTypeArguments) {
                    this.identicalCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, true);
                    return true;
                }

                if (!(sourceTypeArguments && targetTypeArguments) || sourceTypeArguments.length !== targetTypeArguments.length) {
                    this.identicalCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, false);
                    return false;
                }

                for (var i = 0; i < sourceTypeArguments.length; i++) {
                    context.walkTypeArgument(i);
                    var areIdentical = this.typesAreIdenticalInEnclosingTypes(sourceTypeArguments[i], targetTypeArguments[i], context);
                    context.postWalkTypeArgument();

                    if (!areIdentical) {
                        this.identicalCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, false);
                        return false;
                    }
                }
            }

            this.identicalCache.setValueAt(sourceType.pullSymbolID, targetType.pullSymbolID, true);
            return true;
        };

        PullTypeResolver.prototype.sourcePropertyIsRelatableToTargetProperty = function (source, target, sourceProp, targetProp, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var _this = this;
            var sourceAndTargetAreConstructors = source.isConstructor() && target.isConstructor();

            var getNames = function (takeTypesFromPropertyContainers) {
                var enclosingSymbol = _this.getEnclosingSymbolForAST(ast);
                var sourceType = takeTypesFromPropertyContainers ? sourceProp.getContainer() : source;
                var targetType = takeTypesFromPropertyContainers ? targetProp.getContainer() : target;
                if (sourceAndTargetAreConstructors) {
                    sourceType = sourceType.getAssociatedContainerType();
                    targetType = targetType.getAssociatedContainerType();
                }
                return {
                    propertyName: targetProp.getScopedNameEx().toString(),
                    sourceTypeName: sourceType.toString(enclosingSymbol),
                    targetTypeName: targetType.toString(enclosingSymbol)
                };
            };

            var targetPropIsPrivate = targetProp.anyDeclHasFlag(2 /* Private */);
            var sourcePropIsPrivate = sourceProp.anyDeclHasFlag(2 /* Private */);

            if (targetPropIsPrivate !== sourcePropIsPrivate) {
                if (comparisonInfo) {
                    var names = getNames(true);
                    var code;
                    if (targetPropIsPrivate) {
                        code = sourceAndTargetAreConstructors ? TypeScript.DiagnosticCode.Static_property_0_defined_as_public_in_type_1_is_defined_as_private_in_type_2 : TypeScript.DiagnosticCode.Property_0_defined_as_public_in_type_1_is_defined_as_private_in_type_2;
                    } else {
                        code = sourceAndTargetAreConstructors ? TypeScript.DiagnosticCode.Static_property_0_defined_as_private_in_type_1_is_defined_as_public_in_type_2 : TypeScript.DiagnosticCode.Property_0_defined_as_private_in_type_1_is_defined_as_public_in_type_2;
                    }
                    comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(code, [names.propertyName, names.sourceTypeName, names.targetTypeName]));
                    comparisonInfo.flags |= 128 /* InconsistantPropertyAccesibility */;
                }
                return false;
            } else if (sourcePropIsPrivate && targetPropIsPrivate) {
                var targetDecl = targetProp.getDeclarations()[0];
                var sourceDecl = sourceProp.getDeclarations()[0];

                if (targetDecl !== sourceDecl) {
                    if (comparisonInfo) {
                        var names = getNames(true);

                        comparisonInfo.flags |= 128 /* InconsistantPropertyAccesibility */;
                        var code = sourceAndTargetAreConstructors ? TypeScript.DiagnosticCode.Types_0_and_1_define_static_property_2_as_private : TypeScript.DiagnosticCode.Types_0_and_1_define_property_2_as_private;
                        comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(code, [names.sourceTypeName, names.targetTypeName, names.propertyName]));
                    }

                    return false;
                }
            }

            if (sourceProp.isOptional && !targetProp.isOptional) {
                if (comparisonInfo) {
                    var names = getNames(true);
                    comparisonInfo.flags |= 2 /* RequiredPropertyIsMissing */;
                    comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Property_0_defined_as_optional_in_type_1_but_is_required_in_type_2, [names.propertyName, names.sourceTypeName, names.targetTypeName]));
                }
                return false;
            }

            this.resolveDeclaredSymbol(sourceProp, context);

            var sourcePropType = sourceProp.type;
            var targetPropType = targetProp.type;

            var isRelatableInfo = this.sourceIsRelatableToTargetInCache(sourcePropType, targetPropType, comparisonCache, comparisonInfo);
            if (isRelatableInfo) {
                return isRelatableInfo.isRelatable;
            }

            var comparisonInfoPropertyTypeCheck = null;
            if (comparisonInfo && !comparisonInfo.onlyCaptureFirstError) {
                comparisonInfoPropertyTypeCheck = new TypeComparisonInfo(comparisonInfo);
            }

            context.walkMemberTypes(targetProp.name);
            var isSourcePropertyRelatableToTargetProperty = this.sourceIsRelatableToTargetInEnclosingTypes(sourcePropType, targetPropType, assignableTo, comparisonCache, ast, context, comparisonInfoPropertyTypeCheck, isComparingInstantiatedSignatures);
            context.postWalkMemberTypes();

            if (!isSourcePropertyRelatableToTargetProperty && comparisonInfo) {
                var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                comparisonInfo.flags |= 32 /* IncompatiblePropertyTypes */;
                var message;
                var names = getNames(false);
                if (comparisonInfoPropertyTypeCheck && comparisonInfoPropertyTypeCheck.message) {
                    var code = sourceAndTargetAreConstructors ? TypeScript.DiagnosticCode.Types_of_static_property_0_of_class_1_and_class_2_are_incompatible_NL_3 : TypeScript.DiagnosticCode.Types_of_property_0_of_types_1_and_2_are_incompatible_NL_3;
                    message = TypeScript.getDiagnosticMessage(code, [names.propertyName, names.sourceTypeName, names.targetTypeName, comparisonInfoPropertyTypeCheck.message]);
                } else {
                    var code = sourceAndTargetAreConstructors ? TypeScript.DiagnosticCode.Types_of_static_property_0_of_class_1_and_class_2_are_incompatible : TypeScript.DiagnosticCode.Types_of_property_0_of_types_1_and_2_are_incompatible;
                    message = TypeScript.getDiagnosticMessage(code, [names.propertyName, names.sourceTypeName, names.targetTypeName]);
                }
                comparisonInfo.addMessage(message);
            }

            return isSourcePropertyRelatableToTargetProperty;
        };

        PullTypeResolver.prototype.sourceCallSignaturesAreRelatableToTargetCallSignatures = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var targetCallSigs = target.getCallSignatures();

            if (targetCallSigs.length) {
                var comparisonInfoSignatuesTypeCheck = null;
                if (comparisonInfo && !comparisonInfo.onlyCaptureFirstError) {
                    comparisonInfoSignatuesTypeCheck = new TypeComparisonInfo(comparisonInfo);
                }

                var sourceCallSigs = source.getCallSignatures();
                if (!this.signatureGroupIsRelatableToTarget(source, target, sourceCallSigs, targetCallSigs, assignableTo, comparisonCache, ast, context, comparisonInfoSignatuesTypeCheck, isComparingInstantiatedSignatures)) {
                    if (comparisonInfo) {
                        var message;
                        var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                        if (sourceCallSigs.length && targetCallSigs.length) {
                            if (comparisonInfoSignatuesTypeCheck && comparisonInfoSignatuesTypeCheck.message) {
                                message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Call_signatures_of_types_0_and_1_are_incompatible_NL_2, [source.toString(enclosingSymbol), target.toString(enclosingSymbol), comparisonInfoSignatuesTypeCheck.message]);
                            } else {
                                message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Call_signatures_of_types_0_and_1_are_incompatible, [source.toString(enclosingSymbol), target.toString(enclosingSymbol)]);
                            }
                        } else {
                            var hasSig = targetCallSigs.length ? target.toString(enclosingSymbol) : source.toString(enclosingSymbol);
                            var lacksSig = !targetCallSigs.length ? target.toString(enclosingSymbol) : source.toString(enclosingSymbol);
                            message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Type_0_requires_a_call_signature_but_type_1_lacks_one, [hasSig, lacksSig]);
                        }
                        comparisonInfo.flags |= 4 /* IncompatibleSignatures */;
                        comparisonInfo.addMessage(message);
                    }
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.sourceConstructSignaturesAreRelatableToTargetConstructSignatures = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var targetConstructSigs = target.getConstructSignatures();
            if (targetConstructSigs.length) {
                var comparisonInfoSignatuesTypeCheck = null;
                if (comparisonInfo && !comparisonInfo.onlyCaptureFirstError) {
                    comparisonInfoSignatuesTypeCheck = new TypeComparisonInfo(comparisonInfo);
                }

                var sourceConstructSigs = source.getConstructSignatures();
                if (!this.signatureGroupIsRelatableToTarget(source, target, sourceConstructSigs, targetConstructSigs, assignableTo, comparisonCache, ast, context, comparisonInfoSignatuesTypeCheck, isComparingInstantiatedSignatures)) {
                    if (comparisonInfo) {
                        var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                        var message;
                        if (sourceConstructSigs.length && targetConstructSigs.length) {
                            if (comparisonInfoSignatuesTypeCheck && comparisonInfoSignatuesTypeCheck.message) {
                                message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Construct_signatures_of_types_0_and_1_are_incompatible_NL_2, [source.toString(enclosingSymbol), target.toString(enclosingSymbol), comparisonInfoSignatuesTypeCheck.message]);
                            } else {
                                message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Construct_signatures_of_types_0_and_1_are_incompatible, [source.toString(enclosingSymbol), target.toString(enclosingSymbol)]);
                            }
                        } else {
                            var hasSig = targetConstructSigs.length ? target.toString(enclosingSymbol) : source.toString(enclosingSymbol);
                            var lacksSig = !targetConstructSigs.length ? target.toString(enclosingSymbol) : source.toString(enclosingSymbol);
                            message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Type_0_requires_a_construct_signature_but_type_1_lacks_one, [hasSig, lacksSig]);
                        }
                        comparisonInfo.flags |= 4 /* IncompatibleSignatures */;
                        comparisonInfo.addMessage(message);
                    }
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.sourceIndexSignaturesAreRelatableToTargetIndexSignatures = function (source, target, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var targetIndexSigs = this.getBothKindsOfIndexSignaturesExcludingAugmentedType(target, context);
            var targetStringSig = targetIndexSigs.stringSignature;
            var targetNumberSig = targetIndexSigs.numericSignature;

            if (targetStringSig || targetNumberSig) {
                var sourceIndexSigs = this.getBothKindsOfIndexSignaturesIncludingAugmentedType(source, context);
                var enclosingTypeIndexSigs = context.getBothKindOfIndexSignatures(true, false);
                var sourceStringSig = sourceIndexSigs.stringSignature;
                var sourceNumberSig = sourceIndexSigs.numericSignature;

                var comparable = true;
                var comparisonInfoSignatuesTypeCheck = null;
                if (comparisonInfo && !comparisonInfo.onlyCaptureFirstError) {
                    comparisonInfoSignatuesTypeCheck = new TypeComparisonInfo(comparisonInfo);
                }

                if (targetStringSig) {
                    if (sourceStringSig) {
                        context.walkIndexSignatureReturnTypes(enclosingTypeIndexSigs, true, true);
                        comparable = this.sourceIsRelatableToTargetInEnclosingTypes(sourceStringSig.returnType, targetStringSig.returnType, assignableTo, comparisonCache, ast, context, comparisonInfoSignatuesTypeCheck, isComparingInstantiatedSignatures);
                        context.postWalkIndexSignatureReturnTypes();
                    } else {
                        comparable = false;
                    }
                }

                if (comparable && targetNumberSig) {
                    if (sourceNumberSig) {
                        context.walkIndexSignatureReturnTypes(enclosingTypeIndexSigs, false, false);
                        comparable = this.sourceIsRelatableToTargetInEnclosingTypes(sourceNumberSig.returnType, targetNumberSig.returnType, assignableTo, comparisonCache, ast, context, comparisonInfoSignatuesTypeCheck, isComparingInstantiatedSignatures);
                        context.postWalkIndexSignatureReturnTypes();
                    } else if (sourceStringSig) {
                        context.walkIndexSignatureReturnTypes(enclosingTypeIndexSigs, true, false);
                        comparable = this.sourceIsRelatableToTargetInEnclosingTypes(sourceStringSig.returnType, targetNumberSig.returnType, assignableTo, comparisonCache, ast, context, comparisonInfoSignatuesTypeCheck, isComparingInstantiatedSignatures);
                        context.postWalkIndexSignatureReturnTypes();
                    } else {
                        comparable = false;
                    }
                }

                if (!comparable) {
                    if (comparisonInfo) {
                        var message;
                        var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                        if (comparisonInfoSignatuesTypeCheck && comparisonInfoSignatuesTypeCheck.message) {
                            message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Index_signatures_of_types_0_and_1_are_incompatible_NL_2, [source.toString(enclosingSymbol), target.toString(enclosingSymbol), comparisonInfoSignatuesTypeCheck.message]);
                        } else {
                            message = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Index_signatures_of_types_0_and_1_are_incompatible, [source.toString(enclosingSymbol), target.toString(enclosingSymbol)]);
                        }
                        comparisonInfo.flags |= 4 /* IncompatibleSignatures */;
                        comparisonInfo.addMessage(message);
                    }
                    return false;
                }
            }

            return true;
        };

        PullTypeResolver.prototype.signatureGroupIsRelatableToTarget = function (source, target, sourceSG, targetSG, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            if (sourceSG === targetSG) {
                return true;
            }

            if (!(sourceSG.length && targetSG.length)) {
                return false;
            }

            var foundMatch = false;

            var targetExcludeDefinition = targetSG.length > 1;
            var sourceExcludeDefinition = sourceSG.length > 1;
            var sigsCompared = 0;
            var comparisonInfoSignatuesTypeCheck = null;
            if (comparisonInfo) {
                comparisonInfoSignatuesTypeCheck = new TypeComparisonInfo(comparisonInfo, true);
                comparisonInfoSignatuesTypeCheck.message = comparisonInfo.message;
            }
            for (var iMSig = 0; iMSig < targetSG.length; iMSig++) {
                var mSig = targetSG[iMSig];

                if (mSig.isStringConstantOverloadSignature() || (targetExcludeDefinition && mSig.isDefinition())) {
                    continue;
                }

                for (var iNSig = 0; iNSig < sourceSG.length; iNSig++) {
                    var nSig = sourceSG[iNSig];

                    if (nSig.isStringConstantOverloadSignature() || (sourceExcludeDefinition && nSig.isDefinition())) {
                        continue;
                    }

                    context.walkSignatures(nSig.kind, iNSig, iMSig);
                    var isSignatureRelatableToTarget = this.signatureIsRelatableToTarget(nSig, mSig, assignableTo, comparisonCache, ast, context, sigsCompared == 0 ? comparisonInfoSignatuesTypeCheck : null, isComparingInstantiatedSignatures);
                    context.postWalkSignatures();

                    sigsCompared++;

                    if (isSignatureRelatableToTarget) {
                        foundMatch = true;
                        break;
                    }
                }

                if (foundMatch) {
                    foundMatch = false;
                    continue;
                }

                if (comparisonInfo && sigsCompared == 1) {
                    comparisonInfo.message = comparisonInfoSignatuesTypeCheck.message;
                }

                return false;
            }

            return true;
        };

        PullTypeResolver.prototype.signatureIsRelatableToTarget = function (sourceSig, targetSig, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var isRelatableInfo = this.sourceIsRelatableToTargetInCache(sourceSig, targetSig, comparisonCache, comparisonInfo);
            if (isRelatableInfo) {
                return isRelatableInfo.isRelatable;
            }

            comparisonCache.setValueAt(sourceSig.pullSymbolID, targetSig.pullSymbolID, true);
            var isRelatable = this.signatureIsRelatableToTargetWorker(sourceSig, targetSig, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
            comparisonCache.setValueAt(sourceSig.pullSymbolID, targetSig.pullSymbolID, isRelatable);
            return isRelatable;
        };

        PullTypeResolver.prototype.signatureIsRelatableToTargetWorker = function (sourceSig, targetSig, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures) {
            var _this = this;
            var sourceParameters = sourceSig.parameters;
            var targetParameters = targetSig.parameters;

            if (!sourceParameters || !targetParameters) {
                return false;
            }

            var targetNonOptionalParamCount = targetSig.nonOptionalParamCount;
            var sourceNonOptionalParamCount = sourceSig.nonOptionalParamCount;

            if (!targetSig.hasVarArgs && sourceNonOptionalParamCount > targetParameters.length) {
                if (comparisonInfo) {
                    comparisonInfo.flags |= 3 /* SourceSignatureHasTooManyParameters */;
                    comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Call_signature_expects_0_or_fewer_parameters, [targetParameters.length]));
                }
                return false;
            }

            if (this.signaturesAreIdentical(sourceSig, targetSig, context)) {
                return true;
            }

            if (targetSig.isGeneric()) {
                targetSig = this.instantiateSignatureToAny(targetSig);
            }

            if (sourceSig.isGeneric()) {
                sourceSig = this.instantiateSignatureToAny(sourceSig);
            }

            var sourceReturnType = sourceSig.returnType;
            var targetReturnType = targetSig.returnType;

            if (targetReturnType !== this.semanticInfoChain.voidTypeSymbol) {
                context.walkReturnTypes();
                var returnTypesAreRelatable = this.sourceIsRelatableToTargetInEnclosingTypes(sourceReturnType, targetReturnType, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
                context.postWalkReturnTypes();
                if (!returnTypesAreRelatable) {
                    if (comparisonInfo) {
                        comparisonInfo.flags |= 16 /* IncompatibleReturnTypes */;
                    }

                    return false;
                }
            }

            return targetSig.forAllCorrespondingParameterTypesInThisAndOtherSignature(sourceSig, function (targetParamType, sourceParamType, iParam) {
                context.walkParameterTypes(iParam);
                var areParametersRelatable = _this.sourceIsRelatableToTargetInEnclosingTypes(sourceParamType, targetParamType, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
                if (!areParametersRelatable) {
                    context.swapEnclosingTypeWalkers();
                    areParametersRelatable = _this.sourceIsRelatableToTargetInEnclosingTypes(targetParamType, sourceParamType, assignableTo, comparisonCache, ast, context, comparisonInfo, isComparingInstantiatedSignatures);
                    context.swapEnclosingTypeWalkers();
                }
                context.postWalkParameterTypes();

                if (!areParametersRelatable) {
                    if (comparisonInfo) {
                        comparisonInfo.flags |= 64 /* IncompatibleParameterTypes */;
                    }
                }

                return areParametersRelatable;
            });
        };

        PullTypeResolver.prototype.resolveOverloads = function (application, group, haveTypeArgumentsAtCallSite, context, diagnostics) {
            var _this = this;
            var hasOverloads = group.length > 1;
            var comparisonInfo = new TypeComparisonInfo();
            var args = application.argumentList ? application.argumentList.arguments : null;

            var initialCandidates = TypeScript.ArrayUtilities.where(group, function (signature) {
                if (hasOverloads && signature.isDefinition()) {
                    return false;
                }

                var rootSignature = signature.getRootSymbol();
                if (haveTypeArgumentsAtCallSite && !rootSignature.isGeneric()) {
                    return false;
                }

                return _this.overloadHasCorrectArity(signature, args);
            });

            var firstAssignableButNotSupertypeSignature = null;
            var firstAssignableWithProvisionalErrorsSignature = null;

            for (var i = 0; i < initialCandidates.length; i++) {
                var applicability = this.overloadIsApplicable(initialCandidates[i], args, context, comparisonInfo);
                if (applicability === 3 /* Subtype */) {
                    return initialCandidates[i];
                } else if (applicability === 2 /* AssignableWithNoProvisionalErrors */ && !firstAssignableButNotSupertypeSignature) {
                    firstAssignableButNotSupertypeSignature = initialCandidates[i];
                } else if (applicability === 1 /* AssignableButWithProvisionalErrors */ && !firstAssignableWithProvisionalErrorsSignature) {
                    firstAssignableWithProvisionalErrorsSignature = initialCandidates[i];
                }
            }

            if (firstAssignableButNotSupertypeSignature || firstAssignableWithProvisionalErrorsSignature) {
                return firstAssignableButNotSupertypeSignature || firstAssignableWithProvisionalErrorsSignature;
            } else {
                var target = this.getCallTargetErrorSpanAST(application);
                if (comparisonInfo.message) {
                    diagnostics.push(this.semanticInfoChain.diagnosticFromAST(target, TypeScript.DiagnosticCode.Supplied_parameters_do_not_match_any_signature_of_call_target_NL_0, [comparisonInfo.message]));
                } else {
                    diagnostics.push(this.semanticInfoChain.diagnosticFromAST(target, TypeScript.DiagnosticCode.Supplied_parameters_do_not_match_any_signature_of_call_target, null));
                }
            }

            return null;
        };

        PullTypeResolver.prototype.getCallTargetErrorSpanAST = function (callEx) {
            return (callEx.expression.kind() === 212 /* MemberAccessExpression */) ? callEx.expression.name : callEx.expression;
        };

        PullTypeResolver.prototype.overloadHasCorrectArity = function (signature, args) {
            if (args == null) {
                return signature.nonOptionalParamCount === 0;
            }

            var numberOfArgs = (args.nonSeparatorCount() && args.nonSeparatorCount() === args.separatorCount()) ? args.separatorCount() + 1 : args.nonSeparatorCount();
            if (numberOfArgs < signature.nonOptionalParamCount) {
                return false;
            }
            if (!signature.hasVarArgs && numberOfArgs > signature.parameters.length) {
                return false;
            }

            return true;
        };

        PullTypeResolver.prototype.overloadIsApplicable = function (signature, args, context, comparisonInfo) {
            if (args === null) {
                return 3 /* Subtype */;
            }

            var isInVarArg = false;
            var parameters = signature.parameters;
            var paramType = null;

            var overloadApplicability = 3 /* Subtype */;

            for (var i = 0; i < args.nonSeparatorCount(); i++) {
                if (!isInVarArg) {
                    this.resolveDeclaredSymbol(parameters[i], context);

                    if (parameters[i].isVarArg) {
                        paramType = parameters[i].type.getElementType() || this.getNewErrorTypeSymbol(parameters[i].type.getName());
                        isInVarArg = true;
                    } else {
                        paramType = parameters[i].type;
                    }
                }

                var statusOfCurrentArgument = this.overloadIsApplicableForArgument(paramType, args.nonSeparatorAt(i), i, context, comparisonInfo);

                if (statusOfCurrentArgument === 0 /* NotAssignable */) {
                    return 0 /* NotAssignable */;
                } else if (statusOfCurrentArgument === 1 /* AssignableButWithProvisionalErrors */) {
                    overloadApplicability = 1 /* AssignableButWithProvisionalErrors */;
                } else if (overloadApplicability !== 1 /* AssignableButWithProvisionalErrors */ && statusOfCurrentArgument === 2 /* AssignableWithNoProvisionalErrors */) {
                    overloadApplicability = 2 /* AssignableWithNoProvisionalErrors */;
                }
            }

            return overloadApplicability;
        };

        PullTypeResolver.prototype.overloadIsApplicableForArgument = function (paramType, arg, argIndex, context, comparisonInfo) {
            if (paramType.isAny()) {
                return 3 /* Subtype */;
            } else if (paramType.isError()) {
                return 1 /* AssignableButWithProvisionalErrors */;
            } else if (arg.kind() === 219 /* SimpleArrowFunctionExpression */) {
                var simpleArrowFunction = arg;
                return this.overloadIsApplicableForAnyFunctionExpressionArgument(paramType, arg, null, TypeScript.ASTHelpers.parametersFromIdentifier(simpleArrowFunction.identifier), null, simpleArrowFunction.block, simpleArrowFunction.expression, argIndex, context, comparisonInfo);
            } else if (arg.kind() === 218 /* ParenthesizedArrowFunctionExpression */) {
                var arrowFunction = arg;
                return this.overloadIsApplicableForAnyFunctionExpressionArgument(paramType, arg, arrowFunction.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(arrowFunction.callSignature.parameterList), TypeScript.ASTHelpers.getType(arrowFunction), arrowFunction.block, arrowFunction.expression, argIndex, context, comparisonInfo);
            } else if (arg.kind() === 222 /* FunctionExpression */) {
                var functionExpression = arg;
                return this.overloadIsApplicableForAnyFunctionExpressionArgument(paramType, arg, functionExpression.callSignature.typeParameterList, TypeScript.ASTHelpers.parametersFromParameterList(functionExpression.callSignature.parameterList), TypeScript.ASTHelpers.getType(functionExpression), functionExpression.block, null, argIndex, context, comparisonInfo);
            } else if (arg.kind() === 215 /* ObjectLiteralExpression */) {
                return this.overloadIsApplicableForObjectLiteralArgument(paramType, arg, argIndex, context, comparisonInfo);
            } else if (arg.kind() === 214 /* ArrayLiteralExpression */) {
                return this.overloadIsApplicableForArrayLiteralArgument(paramType, arg, argIndex, context, comparisonInfo);
            } else {
                return this.overloadIsApplicableForOtherArgument(paramType, arg, argIndex, context, comparisonInfo);
            }
        };

        PullTypeResolver.prototype.overloadIsApplicableForAnyFunctionExpressionArgument = function (paramType, arg, typeParameters, parameters, returnTypeAnnotation, block, bodyExpression, argIndex, context, comparisonInfo) {
            if (this.cachedFunctionInterfaceType() && paramType === this.cachedFunctionInterfaceType()) {
                return 2 /* AssignableWithNoProvisionalErrors */;
            }

            context.pushProvisionalType(paramType);

            var argSym = this.resolveAnyFunctionExpression(arg, typeParameters, parameters, returnTypeAnnotation, block, bodyExpression, true, context);

            var applicabilityStatus = this.overloadIsApplicableForArgumentHelper(paramType, argSym.type, argIndex, comparisonInfo, arg, context);

            context.popAnyContextualType();

            return applicabilityStatus;
        };

        PullTypeResolver.prototype.overloadIsApplicableForObjectLiteralArgument = function (paramType, arg, argIndex, context, comparisonInfo) {
            if (this.cachedObjectInterfaceType() && paramType === this.cachedObjectInterfaceType()) {
                return 2 /* AssignableWithNoProvisionalErrors */;
            }

            context.pushProvisionalType(paramType);
            var argSym = this.resolveObjectLiteralExpression(arg, true, context);

            var applicabilityStatus = this.overloadIsApplicableForArgumentHelper(paramType, argSym.type, argIndex, comparisonInfo, arg, context);

            context.popAnyContextualType();

            return applicabilityStatus;
        };

        PullTypeResolver.prototype.overloadIsApplicableForArrayLiteralArgument = function (paramType, arg, argIndex, context, comparisonInfo) {
            if (paramType === this.cachedArrayInterfaceType()) {
                return 2 /* AssignableWithNoProvisionalErrors */;
            }

            context.pushProvisionalType(paramType);
            var argSym = this.resolveArrayLiteralExpression(arg, true, context);

            var applicabilityStatus = this.overloadIsApplicableForArgumentHelper(paramType, argSym.type, argIndex, comparisonInfo, arg, context);

            context.popAnyContextualType();

            return applicabilityStatus;
        };

        PullTypeResolver.prototype.overloadIsApplicableForOtherArgument = function (paramType, arg, argIndex, context, comparisonInfo) {
            var argSym = this.resolveAST(arg, false, context);

            if (argSym.type.isAlias()) {
                var aliasSym = argSym.type;
                argSym = aliasSym.getExportAssignedTypeSymbol();
            }

            comparisonInfo.stringConstantVal = arg;
            return this.overloadIsApplicableForArgumentHelper(paramType, argSym.type, argIndex, comparisonInfo, arg, context);
        };

        PullTypeResolver.prototype.overloadIsApplicableForArgumentHelper = function (paramType, argSym, argumentIndex, comparisonInfo, arg, context) {
            var tempComparisonInfo = new TypeComparisonInfo();
            tempComparisonInfo.stringConstantVal = comparisonInfo.stringConstantVal;
            if (!context.hasProvisionalErrors() && this.sourceIsSubtypeOfTarget(argSym.type, paramType, arg, context, tempComparisonInfo)) {
                return 3 /* Subtype */;
            }

            if (this.sourceIsAssignableToTarget(argSym.type, paramType, arg, context, comparisonInfo.message ? tempComparisonInfo : comparisonInfo)) {
                return context.hasProvisionalErrors() ? 1 /* AssignableButWithProvisionalErrors */ : 2 /* AssignableWithNoProvisionalErrors */;
            }

            if (!comparisonInfo.message) {
                var enclosingSymbol = this.getEnclosingSymbolForAST(arg);
                comparisonInfo.addMessage(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Could_not_apply_type_0_to_argument_1_which_is_of_type_2, [paramType.toString(enclosingSymbol), (argumentIndex + 1), argSym.getTypeName(enclosingSymbol)]));
            }

            return 0 /* NotAssignable */;
        };

        PullTypeResolver.prototype.inferArgumentTypesForSignature = function (argContext, comparisonInfo, context) {
            var inferenceResultTypes = argContext.inferTypeArguments();
            var typeParameters = argContext.signatureBeingInferred.getTypeParameters();
            TypeScript.Debug.assert(typeParameters.length == inferenceResultTypes.length);

            var typeReplacementMapForConstraints = null;
            for (var i = 0; i < inferenceResultTypes.length; i++) {
                if (typeParameters[i].getConstraint()) {
                    typeReplacementMapForConstraints = typeReplacementMapForConstraints || TypeScript.PullInstantiationHelpers.createTypeParameterArgumentMap(typeParameters, inferenceResultTypes);
                    var associatedConstraint = this.instantiateType(typeParameters[i].getConstraint(), typeReplacementMapForConstraints);
                    if (!this.sourceIsAssignableToTargetWithNewEnclosingTypes(inferenceResultTypes[i], associatedConstraint, null, context, null, false)) {
                        inferenceResultTypes[i] = associatedConstraint;
                    }
                }
            }

            if (argContext.isInvocationInferenceContext()) {
                var invocationContext = argContext;
                if (!this.typeParametersAreInScopeAtArgumentList(typeParameters, invocationContext.argumentASTs)) {
                    for (var i = 0; i < inferenceResultTypes.length; i++) {
                        if (inferenceResultTypes[i].wrapsSomeTypeParameter(argContext.candidateCache)) {
                            inferenceResultTypes[i] = this.semanticInfoChain.anyTypeSymbol;
                        }
                    }
                }
            }

            return inferenceResultTypes;
        };

        PullTypeResolver.prototype.typeParametersAreInScopeAtArgumentList = function (typeParameters, args) {
            var enclosingDecl = this.getEnclosingDeclForAST(args);
            var typeParameterParentDecl = typeParameters[0].getDeclarations()[0].getParentDecl();
            return enclosingDecl.getParentPath().indexOf(typeParameterParentDecl) > -1;
        };

        PullTypeResolver.prototype.relateTypeToTypeParametersInEnclosingType = function (expressionType, parameterType, argContext, context) {
            if (expressionType && parameterType) {
                if (context.oneOfClassificationsIsInfinitelyExpanding()) {
                    this.relateInifinitelyExpandingTypeToTypeParameters(expressionType, parameterType, argContext, context);
                    return;
                }
            }
            this.relateTypeToTypeParameters(expressionType, parameterType, argContext, context);
        };

        PullTypeResolver.prototype.relateTypeToTypeParametersWithNewEnclosingTypes = function (expressionType, parameterType, argContext, context) {
            var enclosingTypeWalkerStates = context.resetEnclosingTypeWalkerStates();
            this.relateTypeToTypeParameters(expressionType, parameterType, argContext, context);
            context.setEnclosingTypeWalkerStates(enclosingTypeWalkerStates);
        };

        PullTypeResolver.prototype.relateTypeToTypeParameters = function (expressionType, parameterType, argContext, context) {
            if (!expressionType || !parameterType) {
                return;
            }

            if (expressionType.isError()) {
                expressionType = this.semanticInfoChain.anyTypeSymbol;
            }

            if (parameterType.isTypeParameter()) {
                var typeParameter = parameterType;
                argContext.addCandidateForInference(typeParameter, expressionType);
                return;
            }

            if (parameterType.isNamedTypeSymbol() && !parameterType.isGeneric() && !parameterType.getTypeArguments()) {
                return;
            }

            if (TypeScript.PullInstantiationHelpers.twoTypesAreInstantiationsOfSameNamedGenericType(expressionType, parameterType)) {
                this.relateTypeArgumentsOfTypeToTypeParameters(expressionType, parameterType, argContext, context);
            } else {
                var symbolsWhenStartedWalkingTypes = context.startWalkingTypes(expressionType, parameterType);
                this.relateObjectTypeToTypeParameters(expressionType, parameterType, argContext, context);
                context.endWalkingTypes(symbolsWhenStartedWalkingTypes);
            }
        };

        PullTypeResolver.prototype.relateTypeArgumentsOfTypeToTypeParameters = function (expressionType, parameterType, argContext, context) {
            var parameterSideTypeArguments = parameterType.getTypeArguments();
            var argumentSideTypeArguments = expressionType.getTypeArguments();

            TypeScript.Debug.assert(parameterSideTypeArguments && argumentSideTypeArguments && parameterSideTypeArguments.length === argumentSideTypeArguments.length);
            for (var i = 0; i < parameterSideTypeArguments.length; i++) {
                this.relateTypeToTypeParametersWithNewEnclosingTypes(argumentSideTypeArguments[i], parameterSideTypeArguments[i], argContext, context);
            }
        };

        PullTypeResolver.prototype.relateInifinitelyExpandingTypeToTypeParameters = function (expressionType, parameterType, argContext, context) {
            if (!expressionType || !parameterType) {
                return;
            }

            var expressionTypeNamedTypeReference = TypeScript.PullHelpers.getRootType(expressionType);
            var parameterTypeNamedTypeReference = TypeScript.PullHelpers.getRootType(parameterType);
            if (expressionTypeNamedTypeReference !== parameterTypeNamedTypeReference) {
                return;
            }

            var expressionTypeTypeArguments = expressionType.getTypeArguments();
            var parameterTypeArguments = parameterType.getTypeArguments();

            if (expressionTypeTypeArguments && parameterTypeArguments && expressionTypeTypeArguments.length === parameterTypeArguments.length) {
                for (var i = 0; i < expressionTypeTypeArguments.length; i++) {
                    this.relateTypeArgumentsOfTypeToTypeParameters(expressionType, parameterType, argContext, context);
                }
            }
        };

        PullTypeResolver.prototype.relateFunctionSignatureToTypeParameters = function (expressionSignature, parameterSignature, argContext, context) {
            var _this = this;
            var expressionReturnType = expressionSignature.returnType;
            var parameterReturnType = parameterSignature.returnType;

            parameterSignature.forAllCorrespondingParameterTypesInThisAndOtherSignature(expressionSignature, function (parameterSignatureParameterType, expressionSignatureParameterType, i) {
                context.walkParameterTypes(i);
                _this.relateTypeToTypeParametersInEnclosingType(expressionSignatureParameterType, parameterSignatureParameterType, argContext, context);
                context.postWalkParameterTypes();
                return true;
            });

            context.walkReturnTypes();
            this.relateTypeToTypeParametersInEnclosingType(expressionReturnType, parameterReturnType, argContext, context);
            context.postWalkReturnTypes();
        };

        PullTypeResolver.prototype.relateObjectTypeToTypeParameters = function (objectType, parameterType, argContext, context) {
            var parameterTypeMembers = parameterType.getMembers();
            var parameterSignatures;

            var objectMember;
            var objectSignatures;

            if (argContext.alreadyRelatingTypes(objectType, parameterType)) {
                return;
            }

            for (var i = 0; i < parameterTypeMembers.length; i++) {
                objectMember = this.getNamedPropertySymbol(parameterTypeMembers[i].name, 68147712 /* SomeValue */, objectType);
                if (objectMember) {
                    this.resolveDeclaredSymbol(objectMember);
                    this.resolveDeclaredSymbol(parameterTypeMembers[i]);
                    context.walkMemberTypes(parameterTypeMembers[i].name);
                    this.relateTypeToTypeParametersInEnclosingType(objectMember.type, parameterTypeMembers[i].type, argContext, context);
                    context.postWalkMemberTypes();
                }
            }

            this.relateSignatureGroupToTypeParameters(objectType.getCallSignatures(), parameterType.getCallSignatures(), 1048576 /* CallSignature */, argContext, context);

            this.relateSignatureGroupToTypeParameters(objectType.getConstructSignatures(), parameterType.getConstructSignatures(), 2097152 /* ConstructSignature */, argContext, context);

            var parameterIndexSignatures = this.getBothKindsOfIndexSignaturesExcludingAugmentedType(parameterType, context);
            var objectIndexSignatures = this.getBothKindsOfIndexSignaturesExcludingAugmentedType(objectType, context);
            var indexSigInfo = context.getBothKindOfIndexSignatures(false, false);

            if (parameterIndexSignatures.stringSignature && objectIndexSignatures.stringSignature) {
                context.walkIndexSignatureReturnTypes(indexSigInfo, true, true, true);
                this.relateFunctionSignatureToTypeParameters(objectIndexSignatures.stringSignature, parameterIndexSignatures.stringSignature, argContext, context);
                context.postWalkIndexSignatureReturnTypes(true);
            }
            if (parameterIndexSignatures.numericSignature && objectIndexSignatures.numericSignature) {
                context.walkIndexSignatureReturnTypes(indexSigInfo, false, false, true);
                this.relateFunctionSignatureToTypeParameters(objectIndexSignatures.numericSignature, parameterIndexSignatures.numericSignature, argContext, context);
                context.postWalkIndexSignatureReturnTypes(true);
            }
        };

        PullTypeResolver.prototype.relateSignatureGroupToTypeParameters = function (argumentSignatures, parameterSignatures, signatureKind, argContext, context) {
            for (var i = 0; i < parameterSignatures.length; i++) {
                var paramSignature = parameterSignatures[i];
                if (argumentSignatures.length > 0 && paramSignature.isGeneric()) {
                    paramSignature = this.instantiateSignatureToAny(paramSignature);
                }
                for (var j = 0; j < argumentSignatures.length; j++) {
                    var argumentSignature = argumentSignatures[j];
                    if (argumentSignature.nonOptionalParamCount > paramSignature.nonOptionalParamCount) {
                        continue;
                    }

                    if (argumentSignature.isGeneric()) {
                        argumentSignature = this.instantiateSignatureToAny(argumentSignature);
                    }

                    context.walkSignatures(signatureKind, j, i);
                    this.relateFunctionSignatureToTypeParameters(argumentSignature, paramSignature, argContext, context);
                    context.postWalkSignatures();
                }
            }
        };

        PullTypeResolver.prototype.alterPotentialGenericFunctionTypeToInstantiatedFunctionTypeForTypeArgumentInference = function (expressionSymbol, context) {
            var inferentialType = context.getContextualType();
            TypeScript.Debug.assert(inferentialType);
            var expressionType = expressionSymbol.type;
            if (this.isFunctionTypeWithExactlyOneCallSignatureAndNoOtherMembers(expressionType, true) && this.isFunctionTypeWithExactlyOneCallSignatureAndNoOtherMembers(inferentialType, false)) {
                var genericExpressionSignature = expressionType.getCallSignatures()[0];
                var contextualSignature = inferentialType.getCallSignatures()[0];

                var instantiatedSignature = this.instantiateSignatureInContext(genericExpressionSignature, contextualSignature, context, true);
                if (instantiatedSignature === null) {
                    return expressionSymbol;
                }

                var newType = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);
                newType.appendCallSignature(instantiatedSignature);
                return newType;
            }

            return expressionSymbol;
        };

        PullTypeResolver.prototype.isFunctionTypeWithExactlyOneCallSignatureAndNoOtherMembers = function (type, callSignatureShouldBeGeneric) {
            TypeScript.Debug.assert(type);
            if (type.getCallSignatures().length !== 1) {
                return false;
            }

            var callSignatureIsGeneric = type.getCallSignatures()[0].isGeneric();
            if (callSignatureIsGeneric !== callSignatureShouldBeGeneric) {
                return false;
            }

            var typeHasOtherMembers = type.getConstructSignatures().length || type.getIndexSignatures().length || type.getAllMembers(68147712 /* SomeValue */, 0 /* all */).length;
            if (typeHasOtherMembers) {
                return false;
            }

            return true;
        };

        PullTypeResolver.prototype.instantiateTypeToAny = function (typeToSpecialize, context) {
            var typeParameters = typeToSpecialize.getTypeParameters();

            if (!typeParameters.length) {
                return typeToSpecialize;
            }

            var typeArguments = null;

            if (!this._cachedAnyTypeArgs) {
                this._cachedAnyTypeArgs = [
                    [this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol]
                ];
            }

            if (typeParameters.length < this._cachedAnyTypeArgs.length) {
                typeArguments = this._cachedAnyTypeArgs[typeParameters.length - 1];
            } else {
                typeArguments = [];

                for (var i = 0; i < typeParameters.length; i++) {
                    typeArguments[typeArguments.length] = this.semanticInfoChain.anyTypeSymbol;
                }
            }

            var type = this.createInstantiatedType(typeToSpecialize, typeArguments);

            return type;
        };

        PullTypeResolver.prototype.instantiateSignatureToAny = function (signature) {
            var typeParameters = signature.getTypeParameters();
            if (!this._cachedAnyTypeArgs) {
                this._cachedAnyTypeArgs = [
                    [this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol],
                    [this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol, this.semanticInfoChain.anyTypeSymbol]
                ];
            }

            if (typeParameters.length < this._cachedAnyTypeArgs.length) {
                var typeArguments = this._cachedAnyTypeArgs[typeParameters.length - 1];
            } else {
                var typeArguments = [];

                for (var i = 0; i < typeParameters.length; i++) {
                    typeArguments[typeArguments.length] = this.semanticInfoChain.anyTypeSymbol;
                }
            }

            var typeParameterArgumentMap = TypeScript.PullInstantiationHelpers.createTypeParameterArgumentMap(typeParameters, typeArguments);
            return this.instantiateSignature(signature, typeParameterArgumentMap);
        };

        PullTypeResolver.typeCheck = function (compilationSettings, semanticInfoChain, document) {
            var sourceUnit = document.sourceUnit();

            var resolver = semanticInfoChain.getResolver();
            var context = new TypeScript.PullTypeResolutionContext(resolver, true, sourceUnit.fileName());

            if (resolver.canTypeCheckAST(sourceUnit, context)) {
                resolver.resolveAST(sourceUnit, false, context);
                resolver.validateVariableDeclarationGroups(semanticInfoChain.getDeclForAST(sourceUnit), context);

                while (resolver.typeCheckCallBacks.length) {
                    var callBack = resolver.typeCheckCallBacks.pop();
                    callBack(context);
                }

                resolver.processPostTypeCheckWorkItems(context);
            }
        };

        PullTypeResolver.prototype.validateVariableDeclarationGroups = function (enclosingDecl, context) {
            var _this = this;
            this.scanVariableDeclarationGroups(enclosingDecl, function (_) {
            }, function (subsequentDecl, firstSymbol) {
                if (TypeScript.hasFlag(subsequentDecl.kind, 2048 /* Parameter */) || TypeScript.hasFlag(subsequentDecl.flags, 8388608 /* PropertyParameter */)) {
                    return;
                }

                var boundDeclAST = _this.semanticInfoChain.getASTForDecl(subsequentDecl);

                var symbol = subsequentDecl.getSymbol();
                var symbolType = symbol.type;
                var firstSymbolType = firstSymbol.type;

                if (symbolType && firstSymbolType && symbolType !== firstSymbolType && !_this.typesAreIdentical(symbolType, firstSymbolType, context)) {
                    context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(boundDeclAST, TypeScript.DiagnosticCode.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, [symbol.getScopedName(), firstSymbolType.toString(firstSymbol), symbolType.toString(symbol)]));
                }
            });
        };

        PullTypeResolver.prototype.typeCheckFunctionOverloads = function (funcDecl, context, signature, allSignatures) {
            if (!signature) {
                var functionSignatureInfo = TypeScript.PullHelpers.getSignatureForFuncDecl(this.semanticInfoChain.getDeclForAST(funcDecl));
                signature = functionSignatureInfo.signature;
                allSignatures = functionSignatureInfo.allSignatures;
            }
            var functionDeclaration = this.semanticInfoChain.getDeclForAST(funcDecl);
            var funcSymbol = functionDeclaration.getSymbol();

            var definitionSignature = null;
            for (var i = allSignatures.length - 1; i >= 0; i--) {
                if (allSignatures[i].isDefinition()) {
                    definitionSignature = allSignatures[i];
                    break;
                }
            }

            if (!signature.isDefinition()) {
                var signatureParentDecl = signature.getDeclarations()[0].getParentDecl();
                for (var i = 0; i < allSignatures.length; i++) {
                    if (allSignatures[i] === signature) {
                        break;
                    }

                    var allSignaturesParentDecl = allSignatures[i].getDeclarations()[0].getParentDecl();
                    if (allSignaturesParentDecl !== signatureParentDecl) {
                        continue;
                    }

                    if (this.signaturesAreIdenticalWithNewEnclosingTypes(allSignatures[i], signature, context, false)) {
                        if (!this.signatureReturnTypesAreIdentical(allSignatures[i], signature, context)) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Overloads_cannot_differ_only_by_return_type));
                        } else if (funcDecl.kind() === 137 /* ConstructorDeclaration */) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Duplicate_constructor_overload_signature));
                        } else if (functionDeclaration.kind === 2097152 /* ConstructSignature */) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Duplicate_overload_construct_signature));
                        } else if (functionDeclaration.kind === 1048576 /* CallSignature */) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Duplicate_overload_call_signature));
                        } else {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Duplicate_overload_signature_for_0, [funcSymbol.getScopedNameEx().toString()]));
                        }

                        break;
                    }
                }
            }

            var isConstantOverloadSignature = signature.isStringConstantOverloadSignature();
            if (isConstantOverloadSignature) {
                if (signature.isDefinition()) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Overload_signature_implementation_cannot_use_specialized_type));
                } else {
                    var foundSubtypeSignature = false;
                    for (var i = 0; i < allSignatures.length; i++) {
                        if (allSignatures[i].isDefinition() || allSignatures[i] === signature) {
                            continue;
                        }

                        if (!allSignatures[i].isResolved) {
                            this.resolveDeclaredSymbol(allSignatures[i], context);
                        }

                        if (allSignatures[i].isStringConstantOverloadSignature()) {
                            continue;
                        }

                        if (this.signatureIsAssignableToTarget(signature, allSignatures[i], null, context)) {
                            foundSubtypeSignature = true;
                            break;
                        }
                    }

                    if (!foundSubtypeSignature) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature));
                    }
                }
            } else if (definitionSignature && definitionSignature !== signature) {
                var comparisonInfo = new TypeComparisonInfo();

                if (!definitionSignature.isResolved) {
                    this.resolveDeclaredSymbol(definitionSignature, context);
                }

                if (!this.signatureIsAssignableToTarget(definitionSignature, signature, funcDecl, context, comparisonInfo)) {
                    if (comparisonInfo.message) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Overload_signature_is_not_compatible_with_function_definition_NL_0, [comparisonInfo.message]));
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, TypeScript.DiagnosticCode.Overload_signature_is_not_compatible_with_function_definition));
                    }
                }
            }

            var signatureForVisibilityCheck = definitionSignature;
            if (!definitionSignature) {
                if (allSignatures[0] === signature) {
                    return;
                }
                signatureForVisibilityCheck = allSignatures[0];
            }

            if (funcDecl.kind() !== 137 /* ConstructorDeclaration */ && functionDeclaration.kind !== 2097152 /* ConstructSignature */ && signatureForVisibilityCheck && signature !== signatureForVisibilityCheck) {
                var errorCode;

                if (signatureForVisibilityCheck.anyDeclHasFlag(2 /* Private */) !== signature.anyDeclHasFlag(2 /* Private */)) {
                    errorCode = TypeScript.DiagnosticCode.Overload_signatures_must_all_be_public_or_private;
                } else if (signatureForVisibilityCheck.anyDeclHasFlag(1 /* Exported */) !== signature.anyDeclHasFlag(1 /* Exported */)) {
                    errorCode = TypeScript.DiagnosticCode.Overload_signatures_must_all_be_exported_or_not_exported;
                } else if (signatureForVisibilityCheck.anyDeclHasFlag(8 /* Ambient */) !== signature.anyDeclHasFlag(8 /* Ambient */)) {
                    errorCode = TypeScript.DiagnosticCode.Overload_signatures_must_all_be_ambient_or_non_ambient;
                } else if (signatureForVisibilityCheck.anyDeclHasFlag(128 /* Optional */) !== signature.anyDeclHasFlag(128 /* Optional */)) {
                    errorCode = TypeScript.DiagnosticCode.Overload_signatures_must_all_be_optional_or_required;
                }

                if (errorCode) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(funcDecl, errorCode));
                }
            }
        };

        PullTypeResolver.prototype.checkSymbolPrivacy = function (declSymbol, symbol, privacyErrorReporter) {
            if (!symbol || symbol.kind === 2 /* Primitive */) {
                return;
            }

            if (symbol.isType()) {
                var typeSymbol = symbol;
                var isNamedType = typeSymbol.isNamedTypeSymbol();

                if (typeSymbol.isArrayNamedTypeReference()) {
                    this.checkSymbolPrivacy(declSymbol, typeSymbol.getElementType(), privacyErrorReporter);
                    return;
                }

                if (!isNamedType) {
                    var typeOfSymbol = typeSymbol.getTypeOfSymbol();
                    if (typeOfSymbol) {
                        this.checkSymbolPrivacy(declSymbol, typeOfSymbol, privacyErrorReporter);
                        return;
                    }
                }

                if (typeSymbol.inSymbolPrivacyCheck) {
                    return;
                }

                typeSymbol.inSymbolPrivacyCheck = true;

                var typars = typeSymbol.getTypeArgumentsOrTypeParameters();
                if (typars) {
                    for (var i = 0; i < typars.length; i++) {
                        this.checkSymbolPrivacy(declSymbol, typars[i], privacyErrorReporter);
                    }
                }

                if (!isNamedType) {
                    var members = typeSymbol.getMembers();
                    for (var i = 0; i < members.length; i++) {
                        this.checkSymbolPrivacy(declSymbol, members[i].type, privacyErrorReporter);
                    }

                    this.checkTypePrivacyOfSignatures(declSymbol, typeSymbol.getCallSignatures(), privacyErrorReporter);
                    this.checkTypePrivacyOfSignatures(declSymbol, typeSymbol.getConstructSignatures(), privacyErrorReporter);
                    this.checkTypePrivacyOfSignatures(declSymbol, typeSymbol.getIndexSignatures(), privacyErrorReporter);
                } else if (typeSymbol.kind === 8192 /* TypeParameter */) {
                    this.checkSymbolPrivacy(declSymbol, typeSymbol.getConstraint(), privacyErrorReporter);
                }

                typeSymbol.inSymbolPrivacyCheck = false;

                if (!isNamedType) {
                    return;
                }
            }

            if (declSymbol.isExternallyVisible()) {
                var symbolIsVisible = symbol.isExternallyVisible();

                if (symbolIsVisible && symbol.kind !== 8192 /* TypeParameter */) {
                    var symbolPath = symbol.pathToRoot();
                    var declSymbolPath = declSymbol.pathToRoot();

                    if (symbolPath[symbolPath.length - 1].kind === 32 /* DynamicModule */ && declSymbolPath[declSymbolPath.length - 1].kind === 32 /* DynamicModule */ && declSymbolPath[declSymbolPath.length - 1] !== symbolPath[symbolPath.length - 1]) {
                        symbolIsVisible = false;
                        var declSymbolScope = declSymbolPath[declSymbolPath.length - 1];
                        for (var i = symbolPath.length - 1; i >= 0; i--) {
                            var aliasSymbols = symbolPath[i].getExternalAliasedSymbols(declSymbolScope);
                            if (aliasSymbols) {
                                symbolIsVisible = true;
                                aliasSymbols[0].setTypeUsedExternally();
                                break;
                            }
                        }
                        symbol = symbolPath[symbolPath.length - 1];
                    }
                } else if (symbol.kind === 128 /* TypeAlias */) {
                    var aliasSymbol = symbol;
                    symbolIsVisible = true;
                    aliasSymbol.setTypeUsedExternally();
                }

                if (!symbolIsVisible) {
                    privacyErrorReporter(symbol);
                }
            }
        };

        PullTypeResolver.prototype.checkTypePrivacyOfSignatures = function (declSymbol, signatures, privacyErrorReporter) {
            for (var i = 0; i < signatures.length; i++) {
                var signature = signatures[i];
                if (signatures.length > 1 && signature.isDefinition()) {
                    continue;
                }

                var typeParams = signature.getTypeParameters();
                for (var j = 0; j < typeParams.length; j++) {
                    this.checkSymbolPrivacy(declSymbol, typeParams[j], privacyErrorReporter);
                }

                var params = signature.parameters;
                for (var j = 0; j < params.length; j++) {
                    var paramType = params[j].type;
                    this.checkSymbolPrivacy(declSymbol, paramType, privacyErrorReporter);
                }

                var returnType = signature.returnType;
                this.checkSymbolPrivacy(declSymbol, returnType, privacyErrorReporter);
            }
        };

        PullTypeResolver.prototype.typeParameterOfTypeDeclarationPrivacyErrorReporter = function (classOrInterface, typeParameterAST, typeParameter, symbol, context) {
            var decl = this.semanticInfoChain.getDeclForAST(classOrInterface);
            var enclosingDecl = this.getEnclosingDecl(decl);
            var enclosingSymbol = enclosingDecl ? enclosingDecl.getSymbol() : null;
            var messageCode;

            var typeParameters = classOrInterface.kind() === 131 /* ClassDeclaration */ ? classOrInterface.typeParameterList : classOrInterface.typeParameterList;

            var typeSymbol = symbol;
            var typeSymbolName = typeSymbol.getScopedName(enclosingSymbol);
            if (typeSymbol.isContainer() && !typeSymbol.isEnum()) {
                if (!TypeScript.isQuoted(typeSymbolName)) {
                    typeSymbolName = "'" + typeSymbolName + "'";
                }
                if (classOrInterface.kind() === 131 /* ClassDeclaration */) {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_exported_class_is_using_inaccessible_module_1;
                } else {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_exported_interface_is_using_inaccessible_module_1;
                }
            } else {
                if (classOrInterface.kind() === 131 /* ClassDeclaration */) {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_exported_class_has_or_is_using_private_type_1;
                } else {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_exported_interface_has_or_is_using_private_type_1;
                }
            }

            var messageArguments = [typeParameter.getScopedName(enclosingSymbol, false, true), typeSymbolName];
            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(typeParameterAST, messageCode, messageArguments));
        };

        PullTypeResolver.prototype.baseListPrivacyErrorReporter = function (classOrInterface, declSymbol, baseAst, isExtendedType, symbol, context) {
            var decl = this.semanticInfoChain.getDeclForAST(classOrInterface);
            var enclosingDecl = this.getEnclosingDecl(decl);
            var enclosingSymbol = enclosingDecl ? enclosingDecl.getSymbol() : null;
            var messageCode;

            var typeSymbol = symbol;
            var typeSymbolName = typeSymbol.getScopedName(enclosingSymbol);
            if (typeSymbol.isContainer() && !typeSymbol.isEnum()) {
                if (!TypeScript.isQuoted(typeSymbolName)) {
                    typeSymbolName = "'" + typeSymbolName + "'";
                }
                if (classOrInterface.kind() === 131 /* ClassDeclaration */) {
                    if (isExtendedType) {
                        messageCode = TypeScript.DiagnosticCode.Exported_class_0_extends_class_from_inaccessible_module_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Exported_class_0_implements_interface_from_inaccessible_module_1;
                    }
                } else {
                    messageCode = TypeScript.DiagnosticCode.Exported_interface_0_extends_interface_from_inaccessible_module_1;
                }
            } else {
                if (classOrInterface.kind() === 131 /* ClassDeclaration */) {
                    if (isExtendedType) {
                        messageCode = TypeScript.DiagnosticCode.Exported_class_0_extends_private_class_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Exported_class_0_implements_private_interface_1;
                    }
                } else {
                    messageCode = TypeScript.DiagnosticCode.Exported_interface_0_extends_private_interface_1;
                }
            }

            var messageArguments = [declSymbol.getScopedName(enclosingSymbol), typeSymbolName];
            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(baseAst, messageCode, messageArguments));
        };

        PullTypeResolver.prototype.variablePrivacyErrorReporter = function (declAST, declSymbol, symbol, context) {
            var typeSymbol = symbol;
            var enclosingDecl = this.getEnclosingDecl(declSymbol.getDeclarations()[0]);
            var enclosingSymbol = enclosingDecl ? enclosingDecl.getSymbol() : null;

            var isProperty = declSymbol.kind === 4096 /* Property */;
            var isPropertyOfClass = false;
            var declParent = declSymbol.getContainer();
            if (declParent && (declParent.kind === 8 /* Class */ || declParent.kind === 32768 /* ConstructorMethod */)) {
                isPropertyOfClass = true;
            }

            var messageCode;
            var typeSymbolName = typeSymbol.getScopedName(enclosingSymbol);
            if (typeSymbol.isContainer() && !typeSymbol.isEnum()) {
                if (!TypeScript.isQuoted(typeSymbolName)) {
                    typeSymbolName = "'" + typeSymbolName + "'";
                }

                if (declSymbol.anyDeclHasFlag(16 /* Static */)) {
                    messageCode = TypeScript.DiagnosticCode.Public_static_property_0_of_exported_class_is_using_inaccessible_module_1;
                } else if (isProperty) {
                    if (isPropertyOfClass) {
                        messageCode = TypeScript.DiagnosticCode.Public_property_0_of_exported_class_is_using_inaccessible_module_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Property_0_of_exported_interface_is_using_inaccessible_module_1;
                    }
                } else {
                    messageCode = TypeScript.DiagnosticCode.Exported_variable_0_is_using_inaccessible_module_1;
                }
            } else {
                if (declSymbol.anyDeclHasFlag(16 /* Static */)) {
                    messageCode = TypeScript.DiagnosticCode.Public_static_property_0_of_exported_class_has_or_is_using_private_type_1;
                } else if (isProperty) {
                    if (isPropertyOfClass) {
                        messageCode = TypeScript.DiagnosticCode.Public_property_0_of_exported_class_has_or_is_using_private_type_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Property_0_of_exported_interface_has_or_is_using_private_type_1;
                    }
                } else {
                    messageCode = TypeScript.DiagnosticCode.Exported_variable_0_has_or_is_using_private_type_1;
                }
            }

            var messageArguments = [declSymbol.getScopedName(enclosingSymbol), typeSymbolName];
            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(declAST, messageCode, messageArguments));
        };

        PullTypeResolver.prototype.checkFunctionTypePrivacy = function (funcDeclAST, isStatic, typeParameters, parameters, returnTypeAnnotation, block, context) {
            var _this = this;
            if (funcDeclAST.kind() === 222 /* FunctionExpression */ || funcDeclAST.kind() === 241 /* FunctionPropertyAssignment */ || (funcDeclAST.kind() === 139 /* GetAccessor */ && funcDeclAST.parent.parent.kind() === 215 /* ObjectLiteralExpression */) || (funcDeclAST.kind() === 140 /* SetAccessor */ && funcDeclAST.parent.parent.kind() === 215 /* ObjectLiteralExpression */)) {
                return;
            }

            var functionDecl = this.semanticInfoChain.getDeclForAST(funcDeclAST);
            var functionSymbol = functionDecl.getSymbol();
            ;
            var functionSignature;

            var isGetter = funcDeclAST.kind() === 139 /* GetAccessor */;
            var isSetter = funcDeclAST.kind() === 140 /* SetAccessor */;
            var isIndexSignature = functionDecl.kind === 4194304 /* IndexSignature */;

            if (isGetter || isSetter) {
                var accessorSymbol = functionSymbol;
                functionSignature = (isGetter ? accessorSymbol.getGetter() : accessorSymbol.getSetter()).type.getCallSignatures()[0];
            } else {
                if (!functionSymbol) {
                    var parentDecl = functionDecl.getParentDecl();
                    functionSymbol = parentDecl.getSymbol();
                    if (functionSymbol && functionSymbol.isType() && !functionSymbol.isNamedTypeSymbol()) {
                        return;
                    }
                } else if (functionSymbol.kind === 65536 /* Method */ && !isStatic && !functionSymbol.getContainer().isNamedTypeSymbol()) {
                    return;
                }
                functionSignature = functionDecl.getSignatureSymbol();
            }

            if (typeParameters && !isGetter && !isSetter && !isIndexSignature && funcDeclAST.kind() !== 137 /* ConstructorDeclaration */) {
                for (var i = 0; i < typeParameters.typeParameters.nonSeparatorCount(); i++) {
                    var typeParameterAST = typeParameters.typeParameters.nonSeparatorAt(i);
                    var typeParameter = this.resolveTypeParameterDeclaration(typeParameterAST, context);
                    this.checkSymbolPrivacy(functionSymbol, typeParameter, function (symbol) {
                        return _this.functionTypeArgumentArgumentTypePrivacyErrorReporter(funcDeclAST, isStatic, typeParameterAST, typeParameter, symbol, context);
                    });
                }
            }

            if (!isGetter && !isIndexSignature) {
                var funcParams = functionSignature.parameters;
                for (var i = 0; i < funcParams.length; i++) {
                    this.checkSymbolPrivacy(functionSymbol, funcParams[i].type, function (symbol) {
                        return _this.functionArgumentTypePrivacyErrorReporter(funcDeclAST, isStatic, parameters, i, funcParams[i], symbol, context);
                    });
                }
            }

            if (!isSetter) {
                this.checkSymbolPrivacy(functionSymbol, functionSignature.returnType, function (symbol) {
                    return _this.functionReturnTypePrivacyErrorReporter(funcDeclAST, isStatic, returnTypeAnnotation, block, functionSignature.returnType, symbol, context);
                });
            }
        };

        PullTypeResolver.prototype.functionTypeArgumentArgumentTypePrivacyErrorReporter = function (declAST, isStatic, typeParameterAST, typeParameter, symbol, context) {
            var decl = this.semanticInfoChain.getDeclForAST(declAST);
            var enclosingDecl = this.getEnclosingDecl(decl);
            var enclosingSymbol = enclosingDecl ? enclosingDecl.getSymbol() : null;

            var isMethod = decl.kind === 65536 /* Method */;
            var isMethodOfClass = false;
            var declParent = decl.getParentDecl();
            if (declParent && (declParent.kind === 8 /* Class */ || isStatic)) {
                isMethodOfClass = true;
            }

            var typeSymbol = symbol;
            var typeSymbolName = typeSymbol.getScopedName(enclosingSymbol);
            var messageCode;
            if (typeSymbol.isContainer() && !typeSymbol.isEnum()) {
                if (!TypeScript.isQuoted(typeSymbolName)) {
                    typeSymbolName = "'" + typeSymbolName + "'";
                }

                if (decl.kind === 2097152 /* ConstructSignature */) {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_constructor_signature_from_exported_interface_is_using_inaccessible_module_1;
                } else if (decl.kind === 1048576 /* CallSignature */) {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_call_signature_from_exported_interface_is_using_inaccessible_module_1;
                } else if (isMethod) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_public_static_method_from_exported_class_is_using_inaccessible_module_1;
                    } else if (isMethodOfClass) {
                        messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_public_method_from_exported_class_is_using_inaccessible_module_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_method_from_exported_interface_is_using_inaccessible_module_1;
                    }
                } else {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_exported_function_is_using_inaccessible_module_1;
                }
            } else {
                if (decl.kind === 2097152 /* ConstructSignature */) {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_type_1;
                } else if (decl.kind === 1048576 /* CallSignature */) {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_type_1;
                } else if (isMethod) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_type_1;
                    } else if (isMethodOfClass) {
                        messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_public_method_from_exported_class_has_or_is_using_private_type_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_method_from_exported_interface_has_or_is_using_private_type_1;
                    }
                } else {
                    messageCode = TypeScript.DiagnosticCode.TypeParameter_0_of_exported_function_has_or_is_using_private_type_1;
                }
            }

            if (messageCode) {
                var messageArgs = [typeParameter.getScopedName(enclosingSymbol, false, true), typeSymbolName];
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(typeParameterAST, messageCode, messageArgs));
            }
        };

        PullTypeResolver.prototype.functionArgumentTypePrivacyErrorReporter = function (declAST, isStatic, parameters, argIndex, paramSymbol, symbol, context) {
            var decl = this.semanticInfoChain.getDeclForAST(declAST);
            var enclosingDecl = this.getEnclosingDecl(decl);
            var enclosingSymbol = enclosingDecl ? enclosingDecl.getSymbol() : null;

            var isGetter = declAST.kind() === 139 /* GetAccessor */;
            var isSetter = declAST.kind() === 140 /* SetAccessor */;
            var isMethod = decl.kind === 65536 /* Method */;
            var isMethodOfClass = false;
            var declParent = decl.getParentDecl();
            if (declParent && (declParent.kind === 8 /* Class */ || isStatic)) {
                isMethodOfClass = true;
            }

            var typeSymbol = symbol;
            var typeSymbolName = typeSymbol.getScopedName(enclosingSymbol);
            var messageCode;
            if (typeSymbol.isContainer() && !typeSymbol.isEnum()) {
                if (!TypeScript.isQuoted(typeSymbolName)) {
                    typeSymbolName = "'" + typeSymbolName + "'";
                }

                if (declAST.kind() === 137 /* ConstructorDeclaration */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_constructor_from_exported_class_is_using_inaccessible_module_1;
                } else if (isSetter) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_static_property_setter_from_exported_class_is_using_inaccessible_module_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_property_setter_from_exported_class_is_using_inaccessible_module_1;
                    }
                } else if (decl.kind === 2097152 /* ConstructSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_constructor_signature_from_exported_interface_is_using_inaccessible_module_1;
                } else if (decl.kind === 1048576 /* CallSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_call_signature_from_exported_interface_is_using_inaccessible_module_1;
                } else if (isMethod) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_static_method_from_exported_class_is_using_inaccessible_module_1;
                    } else if (isMethodOfClass) {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_method_from_exported_class_is_using_inaccessible_module_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_method_from_exported_interface_is_using_inaccessible_module_1;
                    }
                } else if (!isGetter) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_exported_function_is_using_inaccessible_module_1;
                }
            } else {
                if (declAST.kind() === 137 /* ConstructorDeclaration */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_type_1;
                } else if (isSetter) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_type_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_type_1;
                    }
                } else if (decl.kind === 2097152 /* ConstructSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_type_1;
                } else if (decl.kind === 1048576 /* CallSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_type_1;
                } else if (isMethod) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_type_1;
                    } else if (isMethodOfClass) {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_type_1;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_type_1;
                    }
                } else if (!isGetter && decl.kind !== 4194304 /* IndexSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Parameter_0_of_exported_function_has_or_is_using_private_type_1;
                }
            }

            if (messageCode) {
                var parameter = parameters.astAt(argIndex);

                var messageArgs = [paramSymbol.getScopedName(enclosingSymbol), typeSymbolName];
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(parameter, messageCode, messageArgs));
            }
        };

        PullTypeResolver.prototype.functionReturnTypePrivacyErrorReporter = function (declAST, isStatic, returnTypeAnnotation, block, funcReturnType, symbol, context) {
            var _this = this;
            var decl = this.semanticInfoChain.getDeclForAST(declAST);
            var enclosingDecl = this.getEnclosingDecl(decl);

            var isGetter = declAST.kind() === 139 /* GetAccessor */;
            var isSetter = declAST.kind() === 140 /* SetAccessor */;
            var isMethod = decl.kind === 65536 /* Method */;
            var isMethodOfClass = false;
            var declParent = decl.getParentDecl();
            if (declParent && (declParent.kind === 8 /* Class */ || isStatic)) {
                isMethodOfClass = true;
            }

            var messageCode = null;
            var typeSymbol = symbol;
            var typeSymbolName = typeSymbol.getScopedName(enclosingDecl ? enclosingDecl.getSymbol() : null);
            if (typeSymbol.isContainer() && !typeSymbol.isEnum()) {
                if (!TypeScript.isQuoted(typeSymbolName)) {
                    typeSymbolName = "'" + typeSymbolName + "'";
                }

                if (isGetter) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_static_property_getter_from_exported_class_is_using_inaccessible_module_0;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_property_getter_from_exported_class_is_using_inaccessible_module_0;
                    }
                } else if (decl.kind === 2097152 /* ConstructSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_constructor_signature_from_exported_interface_is_using_inaccessible_module_0;
                } else if (decl.kind === 1048576 /* CallSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_call_signature_from_exported_interface_is_using_inaccessible_module_0;
                } else if (decl.kind === 4194304 /* IndexSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_index_signature_from_exported_interface_is_using_inaccessible_module_0;
                } else if (isMethod) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_static_method_from_exported_class_is_using_inaccessible_module_0;
                    } else if (isMethodOfClass) {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_method_from_exported_class_is_using_inaccessible_module_0;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_method_from_exported_interface_is_using_inaccessible_module_0;
                    }
                } else if (!isSetter && declAST.kind() !== 137 /* ConstructorDeclaration */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_exported_function_is_using_inaccessible_module_0;
                }
            } else {
                if (isGetter) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_type_0;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_type_0;
                    }
                } else if (decl.kind === 2097152 /* ConstructSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_type_0;
                } else if (decl.kind === 1048576 /* CallSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_type_0;
                } else if (decl.kind === 4194304 /* IndexSignature */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_type_0;
                } else if (isMethod) {
                    if (isStatic) {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_type_0;
                    } else if (isMethodOfClass) {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_public_method_from_exported_class_has_or_is_using_private_type_0;
                    } else {
                        messageCode = TypeScript.DiagnosticCode.Return_type_of_method_from_exported_interface_has_or_is_using_private_type_0;
                    }
                } else if (!isSetter && declAST.kind() !== 137 /* ConstructorDeclaration */) {
                    messageCode = TypeScript.DiagnosticCode.Return_type_of_exported_function_has_or_is_using_private_type_0;
                }
            }

            if (messageCode) {
                var messageArguments = [typeSymbolName];
                var reportOnFuncDecl = false;

                if (returnTypeAnnotation) {
                    var returnExpressionSymbol = this.resolveTypeReference(returnTypeAnnotation, context);

                    if (TypeScript.PullHelpers.typeSymbolsAreIdentical(returnExpressionSymbol, funcReturnType)) {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(returnTypeAnnotation, messageCode, messageArguments));
                    }
                }

                if (block) {
                    var reportErrorOnReturnExpressions = function (ast, walker) {
                        var go = true;
                        switch (ast.kind()) {
                            case 129 /* FunctionDeclaration */:
                            case 219 /* SimpleArrowFunctionExpression */:
                            case 218 /* ParenthesizedArrowFunctionExpression */:
                            case 222 /* FunctionExpression */:
                                go = false;
                                break;

                            case 150 /* ReturnStatement */:
                                var returnStatement = ast;
                                var returnExpressionSymbol = _this.resolveAST(returnStatement.expression, false, context).type;

                                if (TypeScript.PullHelpers.typeSymbolsAreIdentical(returnExpressionSymbol, funcReturnType)) {
                                    context.postDiagnostic(_this.semanticInfoChain.diagnosticFromAST(returnStatement, messageCode, messageArguments));
                                } else {
                                    reportOnFuncDecl = true;
                                }
                                go = false;
                                break;

                            default:
                                break;
                        }

                        walker.options.goChildren = go;
                        return ast;
                    };

                    TypeScript.getAstWalkerFactory().walk(block, reportErrorOnReturnExpressions);
                }

                if (reportOnFuncDecl) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(declAST, messageCode, messageArguments));
                }
            }
        };

        PullTypeResolver.prototype.enclosingClassIsDerived = function (classDecl) {
            TypeScript.Debug.assert(classDecl.kind === 8 /* Class */);

            var classSymbol = classDecl.getSymbol();
            return classSymbol.getExtendedTypes().length > 0;
        };

        PullTypeResolver.prototype.isSuperInvocationExpression = function (ast) {
            if (ast.kind() === 213 /* InvocationExpression */) {
                var invocationExpression = ast;
                if (invocationExpression.expression.kind() === 50 /* SuperKeyword */) {
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.isSuperInvocationExpressionStatement = function (node) {
            if (node && node.kind() === 149 /* ExpressionStatement */) {
                var expressionStatement = node;
                if (this.isSuperInvocationExpression(expressionStatement.expression)) {
                    return true;
                }
            }
            return false;
        };

        PullTypeResolver.prototype.getFirstStatementOfBlockOrNull = function (block) {
            if (block && block.statements && block.statements.childCount() > 0) {
                return block.statements.childAt(0);
            }

            return null;
        };

        PullTypeResolver.prototype.superCallMustBeFirstStatementInConstructor = function (constructorDecl) {
            TypeScript.Debug.assert(constructorDecl.kind === 32768 /* ConstructorMethod */);

            if (constructorDecl) {
                var enclosingClass = constructorDecl.getParentDecl();

                var classSymbol = enclosingClass.getSymbol();
                if (classSymbol.getExtendedTypes().length === 0) {
                    return false;
                }

                var classMembers = classSymbol.getMembers();
                for (var i = 0, n1 = classMembers.length; i < n1; i++) {
                    var member = classMembers[i];

                    if (member.kind === 4096 /* Property */) {
                        var declarations = member.getDeclarations();
                        for (var j = 0, n2 = declarations.length; j < n2; j++) {
                            var declaration = declarations[j];
                            var ast = this.semanticInfoChain.getASTForDecl(declaration);
                            if (ast.kind() === 242 /* Parameter */) {
                                return true;
                            }

                            if (ast.kind() === 136 /* MemberVariableDeclaration */) {
                                var variableDeclarator = ast;
                                if (variableDeclarator.variableDeclarator.equalsValueClause) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

            return false;
        };

        PullTypeResolver.prototype.checkForThisCaptureInArrowFunction = function (expression) {
            var enclosingDecl = this.getEnclosingDeclForAST(expression);

            var declPath = enclosingDecl.getParentPath();

            if (declPath.length) {
                var inArrowFunction = false;
                for (var i = declPath.length - 1; i >= 0; i--) {
                    var decl = declPath[i];
                    var declKind = decl.kind;
                    var declFlags = decl.flags;

                    if (declKind === 131072 /* FunctionExpression */ && TypeScript.hasFlag(declFlags, 8192 /* ArrowFunction */)) {
                        inArrowFunction = true;
                        continue;
                    }

                    if (inArrowFunction) {
                        if (declKind === 16384 /* Function */ || declKind === 65536 /* Method */ || declKind === 32768 /* ConstructorMethod */ || declKind === 262144 /* GetAccessor */ || declKind === 524288 /* SetAccessor */ || declKind === 131072 /* FunctionExpression */ || declKind === 8 /* Class */ || declKind === 4 /* Container */ || declKind === 32 /* DynamicModule */ || declKind === 1 /* Script */) {
                            decl.setFlags(decl.flags | 262144 /* MustCaptureThis */);

                            if (declKind === 8 /* Class */) {
                                var constructorSymbol = decl.getSymbol().getConstructorMethod();
                                var constructorDecls = constructorSymbol.getDeclarations();
                                for (var i = 0; i < constructorDecls.length; i++) {
                                    constructorDecls[i].flags = constructorDecls[i].flags | 262144 /* MustCaptureThis */;
                                }
                            }
                            break;
                        }
                    } else if (declKind === 16384 /* Function */ || declKind === 131072 /* FunctionExpression */) {
                        break;
                    }
                }
            }
        };

        PullTypeResolver.prototype.typeCheckMembersAgainstIndexer = function (containerType, containerTypeDecl, context) {
            var indexSignatures = this.getBothKindsOfIndexSignaturesExcludingAugmentedType(containerType, context);
            var stringSignature = indexSignatures.stringSignature;
            var numberSignature = indexSignatures.numericSignature;

            if (stringSignature || numberSignature) {
                var members = containerTypeDecl.getChildDecls();
                for (var i = 0; i < members.length; i++) {
                    var member = members[i];
                    if ((member.name || (member.kind === 4096 /* Property */ && member.name === "")) && member.kind !== 32768 /* ConstructorMethod */ && !TypeScript.hasFlag(member.flags, 16 /* Static */)) {
                        var memberSymbol = member.getSymbol();
                        var relevantSignature = this.determineRelevantIndexerForMember(memberSymbol, numberSignature, stringSignature);
                        if (relevantSignature) {
                            var comparisonInfo = new TypeComparisonInfo();
                            if (!this.sourceIsAssignableToTarget(memberSymbol.type, relevantSignature.returnType, member.ast(), context, comparisonInfo)) {
                                this.reportErrorThatMemberIsNotSubtypeOfIndexer(memberSymbol, relevantSignature, member.ast(), context, comparisonInfo);
                            }
                        }
                    }
                }
            }
        };

        PullTypeResolver.prototype.determineRelevantIndexerForMember = function (member, numberIndexSignature, stringIndexSignature) {
            if (numberIndexSignature && TypeScript.PullHelpers.isNameNumeric(member.name)) {
                return numberIndexSignature;
            } else if (stringIndexSignature) {
                return stringIndexSignature;
            }

            return null;
        };

        PullTypeResolver.prototype.reportErrorThatMemberIsNotSubtypeOfIndexer = function (member, indexSignature, astForError, context, comparisonInfo) {
            var enclosingSymbol = this.getEnclosingSymbolForAST(astForError);
            if (indexSignature.parameters[0].type === this.semanticInfoChain.numberTypeSymbol) {
                if (comparisonInfo.message) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(astForError, TypeScript.DiagnosticCode.All_numerically_named_properties_must_be_assignable_to_numeric_indexer_type_0_NL_1, [indexSignature.returnType.toString(enclosingSymbol), comparisonInfo.message]));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(astForError, TypeScript.DiagnosticCode.All_numerically_named_properties_must_be_assignable_to_numeric_indexer_type_0, [indexSignature.returnType.toString(enclosingSymbol)]));
                }
            } else {
                if (comparisonInfo.message) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(astForError, TypeScript.DiagnosticCode.All_named_properties_must_be_assignable_to_string_indexer_type_0_NL_1, [indexSignature.returnType.toString(enclosingSymbol), comparisonInfo.message]));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(astForError, TypeScript.DiagnosticCode.All_named_properties_must_be_assignable_to_string_indexer_type_0, [indexSignature.returnType.toString(enclosingSymbol)]));
                }
            }
        };

        PullTypeResolver.prototype.typeCheckIfTypeMemberPropertyOkToOverride = function (typeSymbol, extendedType, typeMember, extendedTypeMember, enclosingDecl, comparisonInfo) {
            if (!typeSymbol.isClass()) {
                return true;
            }

            var typeMemberKind = typeMember.kind;
            var extendedMemberKind = extendedTypeMember.kind;

            if (typeMemberKind === extendedMemberKind) {
                return true;
            }

            var errorCode;
            if (typeMemberKind === 4096 /* Property */) {
                if (typeMember.isAccessor()) {
                    errorCode = TypeScript.DiagnosticCode.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                } else {
                    errorCode = TypeScript.DiagnosticCode.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                }
            } else if (typeMemberKind === 65536 /* Method */) {
                if (extendedTypeMember.isAccessor()) {
                    errorCode = TypeScript.DiagnosticCode.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
                } else {
                    errorCode = TypeScript.DiagnosticCode.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property;
                }
            }

            var message = TypeScript.getDiagnosticMessage(errorCode, [typeSymbol.toString(), typeMember.getScopedNameEx().toString(), extendedType.toString()]);
            comparisonInfo.addMessage(message);
            return false;
        };

        PullTypeResolver.prototype.typeCheckIfTypeExtendsType = function (classOrInterface, name, typeSymbol, extendedType, enclosingDecl, context) {
            var typeMembers = typeSymbol.getMembers();

            var comparisonInfo = new TypeComparisonInfo();
            var foundError = false;
            var foundError1 = false;
            var foundError2 = false;

            for (var i = 0; i < typeMembers.length; i++) {
                var propName = typeMembers[i].name;
                var extendedTypeProp = extendedType.findMember(propName, true);
                if (extendedTypeProp) {
                    this.resolveDeclaredSymbol(extendedTypeProp, context);
                    foundError1 = !this.typeCheckIfTypeMemberPropertyOkToOverride(typeSymbol, extendedType, typeMembers[i], extendedTypeProp, enclosingDecl, comparisonInfo);

                    if (!foundError1) {
                        foundError2 = !this.sourcePropertyIsAssignableToTargetProperty(typeSymbol, extendedType, typeMembers[i], extendedTypeProp, classOrInterface, context, comparisonInfo);
                    }

                    if (foundError1 || foundError2) {
                        foundError = true;
                        break;
                    }
                }
            }

            if (!foundError && typeSymbol.hasOwnCallSignatures()) {
                foundError = !this.sourceCallSignaturesAreAssignableToTargetCallSignatures(typeSymbol, extendedType, classOrInterface, context, comparisonInfo);
            }

            if (!foundError && typeSymbol.hasOwnConstructSignatures()) {
                foundError = !this.sourceConstructSignaturesAreAssignableToTargetConstructSignatures(typeSymbol, extendedType, classOrInterface, context, comparisonInfo);
            }

            if (!foundError && typeSymbol.hasOwnIndexSignatures()) {
                foundError = !this.sourceIndexSignaturesAreAssignableToTargetIndexSignatures(typeSymbol, extendedType, classOrInterface, context, comparisonInfo);
            }

            if (!foundError && typeSymbol.isClass()) {
                var typeConstructorType = typeSymbol.getConstructorMethod().type;
                var typeConstructorTypeMembers = typeConstructorType.getMembers();
                if (typeConstructorTypeMembers.length) {
                    var extendedConstructorType = extendedType.getConstructorMethod().type;
                    var comparisonInfoForPropTypeCheck = new TypeComparisonInfo(comparisonInfo);

                    for (var i = 0; i < typeConstructorTypeMembers.length; i++) {
                        var propName = typeConstructorTypeMembers[i].name;
                        var extendedConstructorTypeProp = extendedConstructorType.findMember(propName, true);
                        if (extendedConstructorTypeProp) {
                            if (!extendedConstructorTypeProp.isResolved) {
                                this.resolveDeclaredSymbol(extendedConstructorTypeProp, context);
                            }

                            if (!this.sourcePropertyIsAssignableToTargetProperty(typeConstructorType, extendedConstructorType, typeConstructorTypeMembers[i], extendedConstructorTypeProp, classOrInterface, context, comparisonInfo)) {
                                foundError = true;
                                break;
                            }
                        }
                    }
                }
            }

            if (foundError) {
                var errorCode;
                if (typeSymbol.isClass()) {
                    errorCode = TypeScript.DiagnosticCode.Class_0_cannot_extend_class_1_NL_2;
                } else {
                    if (extendedType.isClass()) {
                        errorCode = TypeScript.DiagnosticCode.Interface_0_cannot_extend_class_1_NL_2;
                    } else {
                        errorCode = TypeScript.DiagnosticCode.Interface_0_cannot_extend_interface_1_NL_2;
                    }
                }

                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(name, errorCode, [typeSymbol.getScopedName(), extendedType.getScopedName(), comparisonInfo.message]));
            }
        };

        PullTypeResolver.prototype.typeCheckIfClassImplementsType = function (classDecl, classSymbol, implementedType, enclosingDecl, context) {
            var comparisonInfo = new TypeComparisonInfo();
            var foundError = !this.sourceMembersAreAssignableToTargetMembers(classSymbol, implementedType, classDecl, context, comparisonInfo);
            if (!foundError) {
                foundError = !this.sourceCallSignaturesAreAssignableToTargetCallSignatures(classSymbol, implementedType, classDecl, context, comparisonInfo);
                if (!foundError) {
                    foundError = !this.sourceConstructSignaturesAreAssignableToTargetConstructSignatures(classSymbol, implementedType, classDecl, context, comparisonInfo);
                    if (!foundError) {
                        foundError = !this.sourceIndexSignaturesAreAssignableToTargetIndexSignatures(classSymbol, implementedType, classDecl, context, comparisonInfo);
                    }
                }
            }

            if (foundError) {
                var enclosingSymbol = this.getEnclosingSymbolForAST(classDecl);
                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(classDecl.identifier, TypeScript.DiagnosticCode.Class_0_declares_interface_1_but_does_not_implement_it_NL_2, [classSymbol.getScopedName(enclosingSymbol), implementedType.getScopedName(enclosingSymbol), comparisonInfo.message]));
            }
        };

        PullTypeResolver.prototype.computeValueSymbolFromAST = function (valueDeclAST, context) {
            var prevInTypeCheck = context.inTypeCheck;
            context.inTypeCheck = false;

            var typeSymbolAlias = this.semanticInfoChain.getAliasSymbolForAST(valueDeclAST);

            if (valueDeclAST.kind() == 11 /* IdentifierName */) {
                var valueSymbol = this.computeNameExpression(valueDeclAST, context);
            } else {
                TypeScript.Debug.assert(valueDeclAST.kind() == 121 /* QualifiedName */);
                var qualifiedName = valueDeclAST;

                var lhs = this.computeValueSymbolFromAST(qualifiedName.left, context);
                var valueSymbol = this.computeDottedNameExpressionFromLHS(lhs.symbol, qualifiedName.left, qualifiedName.right, context, false);
            }
            var valueSymbolAlias = this.semanticInfoChain.getAliasSymbolForAST(valueDeclAST);

            this.semanticInfoChain.setAliasSymbolForAST(valueDeclAST, typeSymbolAlias);
            context.inTypeCheck = prevInTypeCheck;

            return { symbol: valueSymbol, alias: valueSymbolAlias };
        };

        PullTypeResolver.prototype.hasClassTypeSymbolConflictAsValue = function (baseDeclAST, typeSymbol, enclosingDecl, context) {
            var typeSymbolAlias = this.semanticInfoChain.getAliasSymbolForAST(baseDeclAST);

            var valueDeclAST = baseDeclAST.kind() == 126 /* GenericType */ ? baseDeclAST.name : baseDeclAST;
            var valueSymbolInfo = this.computeValueSymbolFromAST(valueDeclAST, context);
            var valueSymbol = valueSymbolInfo.symbol;
            var valueSymbolAlias = valueSymbolInfo.alias;

            if (typeSymbolAlias && valueSymbolAlias) {
                return typeSymbolAlias !== valueSymbolAlias;
            }

            if (!valueSymbol.anyDeclHasFlag(16384 /* ClassConstructorVariable */)) {
                return true;
            }

            var associatedContainerType = valueSymbol.type ? valueSymbol.type.getAssociatedContainerType() : null;

            if (associatedContainerType) {
                return associatedContainerType !== typeSymbol.getRootSymbol();
            }

            return true;
        };

        PullTypeResolver.prototype.typeCheckBase = function (classOrInterface, name, typeSymbol, baseDeclAST, isExtendedType, enclosingDecl, context) {
            var _this = this;
            var typeDecl = this.semanticInfoChain.getDeclForAST(classOrInterface);

            var baseType = this.resolveTypeReference(baseDeclAST, context).type;

            if (!baseType) {
                return;
            }

            var typeDeclIsClass = typeSymbol.isClass();

            if (!typeSymbol.isValidBaseKind(baseType, isExtendedType)) {
                if (!baseType.isError()) {
                    if (isExtendedType) {
                        if (typeDeclIsClass) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(baseDeclAST, TypeScript.DiagnosticCode.A_class_may_only_extend_another_class));
                        } else {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(baseDeclAST, TypeScript.DiagnosticCode.An_interface_may_only_extend_another_class_or_interface));
                        }
                    } else {
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(baseDeclAST, TypeScript.DiagnosticCode.A_class_may_only_implement_another_class_or_interface));
                    }
                }
                return;
            } else if (typeDeclIsClass && isExtendedType) {
                if (this.hasClassTypeSymbolConflictAsValue(baseDeclAST, baseType, enclosingDecl, context)) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(baseDeclAST, TypeScript.DiagnosticCode.Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_1, [TypeScript.ASTHelpers.getNameOfIdenfierOrQualifiedName(baseDeclAST.kind() == 126 /* GenericType */ ? baseDeclAST.name : baseDeclAST), baseType.toString(enclosingDecl ? enclosingDecl.getSymbol() : null)]));
                }
            }

            if (baseType.hasBase(typeSymbol)) {
                typeSymbol.setHasBaseTypeConflict();
                baseType.setHasBaseTypeConflict();

                context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(name, typeDeclIsClass ? TypeScript.DiagnosticCode.Class_0_is_recursively_referenced_as_a_base_type_of_itself : TypeScript.DiagnosticCode.Interface_0_is_recursively_referenced_as_a_base_type_of_itself, [typeSymbol.getScopedName()]));
                return;
            }

            if (isExtendedType) {
                this.typeCheckCallBacks.push(function (context) {
                    return _this.typeCheckIfTypeExtendsType(classOrInterface, name, typeSymbol, baseType, enclosingDecl, context);
                });
            } else {
                TypeScript.Debug.assert(classOrInterface.kind() === 131 /* ClassDeclaration */);

                this.typeCheckCallBacks.push(function (context) {
                    return _this.typeCheckIfClassImplementsType(classOrInterface, typeSymbol, baseType, enclosingDecl, context);
                });
            }

            this.checkSymbolPrivacy(typeSymbol, baseType, function (errorSymbol) {
                return _this.baseListPrivacyErrorReporter(classOrInterface, typeSymbol, baseDeclAST, isExtendedType, errorSymbol, context);
            });
        };

        PullTypeResolver.prototype.typeCheckBases = function (classOrInterface, name, heritageClauses, typeSymbol, enclosingDecl, context) {
            var _this = this;
            var extendsClause = TypeScript.ASTHelpers.getExtendsHeritageClause(heritageClauses);
            var implementsClause = TypeScript.ASTHelpers.getImplementsHeritageClause(heritageClauses);
            if (!extendsClause && !implementsClause) {
                return;
            }

            if (extendsClause) {
                for (var i = 0; i < extendsClause.typeNames.nonSeparatorCount(); i++) {
                    this.typeCheckBase(classOrInterface, name, typeSymbol, extendsClause.typeNames.nonSeparatorAt(i), true, enclosingDecl, context);
                }
            }

            if (typeSymbol.isClass()) {
                if (implementsClause) {
                    for (var i = 0; i < implementsClause.typeNames.nonSeparatorCount(); i++) {
                        this.typeCheckBase(classOrInterface, name, typeSymbol, implementsClause.typeNames.nonSeparatorAt(i), false, enclosingDecl, context);
                    }
                }
            } else if (extendsClause && !typeSymbol.hasBaseTypeConflict() && typeSymbol.getExtendedTypes().length > 1) {
                var firstInterfaceASTWithExtendsClause = TypeScript.ArrayUtilities.firstOrDefault(typeSymbol.getDeclarations(), function (decl) {
                    return decl.ast().heritageClauses !== null;
                }).ast();
                if (classOrInterface === firstInterfaceASTWithExtendsClause) {
                    this.typeCheckCallBacks.push(function (context) {
                        _this.checkTypeCompatibilityBetweenBases(classOrInterface.identifier, typeSymbol, context);
                    });
                }
            }
        };

        PullTypeResolver.prototype.checkTypeCompatibilityBetweenBases = function (name, typeSymbol, context) {
            var derivedIndexSignatures = typeSymbol.getOwnIndexSignatures();

            var inheritedMembersMap = TypeScript.createIntrinsicsObject();
            var inheritedIndexSignatures = new InheritedIndexSignatureInfo();

            var typeHasOwnNumberIndexer = false;
            var typeHasOwnStringIndexer = false;

            if (typeSymbol.hasOwnIndexSignatures()) {
                var ownIndexSignatures = typeSymbol.getOwnIndexSignatures();
                for (var i = 0; i < ownIndexSignatures.length; i++) {
                    if (ownIndexSignatures[i].parameters[0].type === this.semanticInfoChain.numberTypeSymbol) {
                        typeHasOwnNumberIndexer = true;
                    } else {
                        typeHasOwnStringIndexer = true;
                    }
                }
            }
            var baseTypes = typeSymbol.getExtendedTypes();
            for (var i = 0; i < baseTypes.length; i++) {
                if (this.checkNamedPropertyIdentityBetweenBases(name, typeSymbol, baseTypes[i], inheritedMembersMap, context) || this.checkIndexSignatureIdentityBetweenBases(name, typeSymbol, baseTypes[i], inheritedIndexSignatures, typeHasOwnNumberIndexer, typeHasOwnStringIndexer, context)) {
                    return;
                }
            }

            if (this.checkThatInheritedNumberSignatureIsSubtypeOfInheritedStringSignature(name, typeSymbol, inheritedIndexSignatures, context)) {
                return;
            }

            this.checkInheritedMembersAgainstInheritedIndexSignatures(name, typeSymbol, inheritedIndexSignatures, inheritedMembersMap, context);
        };

        PullTypeResolver.prototype.checkNamedPropertyIdentityBetweenBases = function (interfaceName, interfaceSymbol, baseTypeSymbol, inheritedMembersMap, context) {
            var baseMembers = baseTypeSymbol.getAllMembers(4096 /* Property */ | 65536 /* Method */, 0 /* all */);
            for (var i = 0; i < baseMembers.length; i++) {
                var member = baseMembers[i];
                var memberName = member.name;

                if (interfaceSymbol.findMember(memberName, false)) {
                    continue;
                }

                this.resolveDeclaredSymbol(member, context);

                if (inheritedMembersMap[memberName]) {
                    var prevMember = inheritedMembersMap[memberName];
                    if (prevMember.baseOrigin !== baseTypeSymbol && !this.propertiesAreIdenticalWithNewEnclosingTypes(baseTypeSymbol, prevMember.baseOrigin, member, prevMember.memberSymbol, context)) {
                        var innerDiagnostic = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Named_properties_0_of_types_1_and_2_are_not_identical, [memberName, prevMember.baseOrigin.getScopedName(), baseTypeSymbol.getScopedName()]);
                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(interfaceName, TypeScript.DiagnosticCode.Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3, [interfaceSymbol.getDisplayName(), prevMember.baseOrigin.getScopedName(), baseTypeSymbol.getScopedName(), innerDiagnostic]));
                        return true;
                    }
                } else {
                    inheritedMembersMap[memberName] = new MemberWithBaseOrigin(member, baseTypeSymbol);
                }
            }

            return false;
        };

        PullTypeResolver.prototype.checkIndexSignatureIdentityBetweenBases = function (interfaceName, interfaceSymbol, baseTypeSymbol, allInheritedSignatures, derivedTypeHasOwnNumberSignature, derivedTypeHasOwnStringSignature, context) {
            if (derivedTypeHasOwnNumberSignature && derivedTypeHasOwnStringSignature) {
                return false;
            }

            var indexSignaturesFromThisBaseType = baseTypeSymbol.getIndexSignatures();
            for (var i = 0; i < indexSignaturesFromThisBaseType.length; i++) {
                var currentInheritedSignature = indexSignaturesFromThisBaseType[i];

                var parameterTypeIsString = currentInheritedSignature.parameters[0].type === this.semanticInfoChain.stringTypeSymbol;
                var parameterTypeIsNumber = currentInheritedSignature.parameters[0].type === this.semanticInfoChain.numberTypeSymbol;

                if (parameterTypeIsString && derivedTypeHasOwnStringSignature || parameterTypeIsNumber && derivedTypeHasOwnNumberSignature) {
                    continue;
                }

                if (parameterTypeIsString) {
                    if (allInheritedSignatures.stringSignatureWithBaseOrigin) {
                        if (allInheritedSignatures.stringSignatureWithBaseOrigin.baseOrigin !== baseTypeSymbol && !this.typesAreIdentical(allInheritedSignatures.stringSignatureWithBaseOrigin.signature.returnType, currentInheritedSignature.returnType, context)) {
                            var innerDiagnostic = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Types_of_string_indexer_of_types_0_and_1_are_not_identical, [allInheritedSignatures.stringSignatureWithBaseOrigin.baseOrigin.getScopedName(), baseTypeSymbol.getScopedName()]);
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(interfaceName, TypeScript.DiagnosticCode.Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3, [interfaceSymbol.getDisplayName(), allInheritedSignatures.stringSignatureWithBaseOrigin.baseOrigin.getScopedName(), baseTypeSymbol.getScopedName(), innerDiagnostic]));
                            return true;
                        }
                    } else {
                        allInheritedSignatures.stringSignatureWithBaseOrigin = new SignatureWithBaseOrigin(currentInheritedSignature, baseTypeSymbol);
                    }
                } else if (parameterTypeIsNumber) {
                    if (allInheritedSignatures.numberSignatureWithBaseOrigin) {
                        if (allInheritedSignatures.numberSignatureWithBaseOrigin.baseOrigin !== baseTypeSymbol && !this.typesAreIdentical(allInheritedSignatures.numberSignatureWithBaseOrigin.signature.returnType, currentInheritedSignature.returnType, context)) {
                            var innerDiagnostic = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Types_of_number_indexer_of_types_0_and_1_are_not_identical, [allInheritedSignatures.numberSignatureWithBaseOrigin.baseOrigin.getScopedName(), baseTypeSymbol.getScopedName()]);
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(interfaceName, TypeScript.DiagnosticCode.Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3, [interfaceSymbol.getDisplayName(), allInheritedSignatures.numberSignatureWithBaseOrigin.baseOrigin.getScopedName(), baseTypeSymbol.getScopedName(), innerDiagnostic]));
                            return true;
                        }
                    } else {
                        allInheritedSignatures.numberSignatureWithBaseOrigin = new SignatureWithBaseOrigin(currentInheritedSignature, baseTypeSymbol);
                    }
                }
            }

            return false;
        };

        PullTypeResolver.prototype.checkInheritedMembersAgainstInheritedIndexSignatures = function (interfaceName, interfaceSymbol, inheritedIndexSignatures, inheritedMembers, context) {
            if (!inheritedIndexSignatures.stringSignatureWithBaseOrigin && !inheritedIndexSignatures.numberSignatureWithBaseOrigin) {
                return false;
            }

            var comparisonInfo = new TypeComparisonInfo();
            var stringSignature = inheritedIndexSignatures.stringSignatureWithBaseOrigin && inheritedIndexSignatures.stringSignatureWithBaseOrigin.signature;
            var numberSignature = inheritedIndexSignatures.numberSignatureWithBaseOrigin && inheritedIndexSignatures.numberSignatureWithBaseOrigin.signature;
            for (var memberName in inheritedMembers) {
                var memberWithBaseOrigin = inheritedMembers[memberName];
                if (!memberWithBaseOrigin) {
                    continue;
                }

                var relevantSignature = this.determineRelevantIndexerForMember(memberWithBaseOrigin.memberSymbol, numberSignature, stringSignature);
                if (!relevantSignature) {
                    continue;
                }

                var relevantSignatureIsNumberSignature = relevantSignature.parameters[0].type === this.semanticInfoChain.numberTypeSymbol;
                var signatureBaseOrigin = relevantSignatureIsNumberSignature ? inheritedIndexSignatures.numberSignatureWithBaseOrigin.baseOrigin : inheritedIndexSignatures.stringSignatureWithBaseOrigin.baseOrigin;

                if (signatureBaseOrigin === memberWithBaseOrigin.baseOrigin) {
                    continue;
                }

                var memberIsSubtype = this.sourceIsAssignableToTarget(memberWithBaseOrigin.memberSymbol.type, relevantSignature.returnType, interfaceName, context, comparisonInfo);

                if (!memberIsSubtype) {
                    var enclosingSymbol = this.getEnclosingSymbolForAST(interfaceName);
                    if (relevantSignatureIsNumberSignature) {
                        var innerDiagnostic = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Type_of_property_0_in_type_1_is_not_assignable_to_number_indexer_type_in_type_2_NL_3, [memberName, memberWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), inheritedIndexSignatures.numberSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), comparisonInfo.message]);

                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(interfaceName, TypeScript.DiagnosticCode.Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3, [interfaceSymbol.getDisplayName(enclosingSymbol), memberWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), inheritedIndexSignatures.numberSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), innerDiagnostic]));
                    } else {
                        var innerDiagnostic = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Type_of_property_0_in_type_1_is_not_assignable_to_string_indexer_type_in_type_2_NL_3, [memberName, memberWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), inheritedIndexSignatures.stringSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), comparisonInfo.message]);

                        context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(interfaceName, TypeScript.DiagnosticCode.Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3, [interfaceSymbol.getDisplayName(enclosingSymbol), memberWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), inheritedIndexSignatures.stringSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), innerDiagnostic]));
                    }
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.checkThatInheritedNumberSignatureIsSubtypeOfInheritedStringSignature = function (interfaceName, interfaceSymbol, inheritedIndexSignatures, context) {
            if (inheritedIndexSignatures.numberSignatureWithBaseOrigin && inheritedIndexSignatures.stringSignatureWithBaseOrigin) {
                if (inheritedIndexSignatures.numberSignatureWithBaseOrigin.baseOrigin === inheritedIndexSignatures.stringSignatureWithBaseOrigin.baseOrigin) {
                    return false;
                }

                var comparisonInfo = new TypeComparisonInfo();
                var signatureIsSubtype = this.sourceIsAssignableToTarget(inheritedIndexSignatures.numberSignatureWithBaseOrigin.signature.returnType, inheritedIndexSignatures.stringSignatureWithBaseOrigin.signature.returnType, interfaceName, context, comparisonInfo);

                if (!signatureIsSubtype) {
                    var enclosingSymbol = this.getEnclosingSymbolForAST(interfaceName);
                    var innerDiagnostic = TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Type_of_number_indexer_in_type_0_is_not_assignable_to_string_indexer_type_in_type_1_NL_2, [
                        inheritedIndexSignatures.numberSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol),
                        inheritedIndexSignatures.stringSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), comparisonInfo.message]);
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(interfaceName, TypeScript.DiagnosticCode.Interface_0_cannot_simultaneously_extend_types_1_and_2_NL_3, [
                        interfaceSymbol.getDisplayName(enclosingSymbol), inheritedIndexSignatures.numberSignatureWithBaseOrigin.baseOrigin.getScopedName(),
                        inheritedIndexSignatures.stringSignatureWithBaseOrigin.baseOrigin.getScopedName(enclosingSymbol), innerDiagnostic]));
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.checkAssignability = function (ast, source, target, context) {
            var comparisonInfo = new TypeComparisonInfo();

            var isAssignable = this.sourceIsAssignableToTarget(source, target, ast, context, comparisonInfo);

            if (!isAssignable) {
                var enclosingSymbol = this.getEnclosingSymbolForAST(ast);
                if (comparisonInfo.message) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Cannot_convert_0_to_1_NL_2, [source.toString(enclosingSymbol), target.toString(enclosingSymbol), comparisonInfo.message]));
                } else {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Cannot_convert_0_to_1, [source.toString(enclosingSymbol), target.toString(enclosingSymbol)]));
                }
            }
        };

        PullTypeResolver.prototype.isReference = function (ast, astSymbol) {
            if (ast.kind() === 217 /* ParenthesizedExpression */) {
                return this.isReference(ast.expression, astSymbol);
            }

            if (ast.kind() !== 11 /* IdentifierName */ && ast.kind() !== 212 /* MemberAccessExpression */ && ast.kind() !== 221 /* ElementAccessExpression */) {
                return false;
            }

            if (ast.kind() === 11 /* IdentifierName */) {
                if (astSymbol.kind === 512 /* Variable */ && astSymbol.anyDeclHasFlag(4096 /* Enum */)) {
                    return false;
                }

                if (astSymbol.kind === 512 /* Variable */ && astSymbol.anyDeclHasFlag(102400 /* SomeInitializedModule */)) {
                    return false;
                }

                if (astSymbol.kind === 32768 /* ConstructorMethod */ || astSymbol.kind === 16384 /* Function */) {
                    return false;
                }
            }

            if (ast.kind() === 212 /* MemberAccessExpression */ && astSymbol.kind === 67108864 /* EnumMember */) {
                return false;
            }

            return true;
        };

        PullTypeResolver.prototype.checkForSuperMemberAccess = function (expression, name, resolvedName, context) {
            if (resolvedName) {
                if (expression.kind() === 50 /* SuperKeyword */ && !resolvedName.isError() && resolvedName.kind !== 65536 /* Method */) {
                    context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(name, TypeScript.DiagnosticCode.Only_public_methods_of_the_base_class_are_accessible_via_the_super_keyword));
                    return true;
                }
            }

            return false;
        };

        PullTypeResolver.prototype.getEnclosingDeclForAST = function (ast) {
            return this.semanticInfoChain.getEnclosingDecl(ast);
        };

        PullTypeResolver.prototype.getEnclosingSymbolForAST = function (ast) {
            var enclosingDecl = this.getEnclosingDeclForAST(ast);
            return enclosingDecl ? enclosingDecl.getSymbol() : null;
        };

        PullTypeResolver.prototype.checkForPrivateMemberAccess = function (name, expressionType, resolvedName, context) {
            if (resolvedName) {
                if (resolvedName.anyDeclHasFlag(2 /* Private */)) {
                    var memberContainer = resolvedName.getContainer();
                    if (memberContainer && memberContainer.kind === 33554432 /* ConstructorType */) {
                        memberContainer = memberContainer.getAssociatedContainerType();
                    }

                    if (memberContainer && memberContainer.isClass()) {
                        var memberClass = memberContainer.getDeclarations()[0].ast();
                        TypeScript.Debug.assert(memberClass);

                        var containingClass = this.getEnclosingClassDeclaration(name);

                        if (!containingClass || containingClass !== memberClass) {
                            context.postDiagnostic(this.semanticInfoChain.diagnosticFromAST(name, TypeScript.DiagnosticCode._0_1_is_inaccessible, [memberContainer.toString(null, false), name.text()]));
                            return true;
                        }
                    }
                }
            }

            return false;
        };

        PullTypeResolver.prototype.instantiateType = function (type, typeParameterArgumentMap) {
            if (type.isPrimitive()) {
                return type;
            }

            if (type.isError()) {
                return type;
            }

            if (typeParameterArgumentMap[type.pullSymbolID]) {
                return typeParameterArgumentMap[type.pullSymbolID];
            }

            type._resolveDeclaredSymbol();
            if (type.isTypeParameter()) {
                return this.instantiateTypeParameter(type, typeParameterArgumentMap);
            }

            if (type.wrapsSomeTypeParameter(typeParameterArgumentMap)) {
                return TypeScript.PullInstantiatedTypeReferenceSymbol.create(this, type, typeParameterArgumentMap);
            }

            return type;
        };

        PullTypeResolver.prototype.instantiateTypeParameter = function (typeParameter, typeParameterArgumentMap) {
            var constraint = typeParameter.getConstraint();
            if (!constraint) {
                return typeParameter;
            }

            var instantiatedConstraint = this.instantiateType(constraint, typeParameterArgumentMap);

            if (instantiatedConstraint == constraint) {
                return typeParameter;
            }

            var rootTypeParameter = typeParameter.getRootSymbol();
            var instantiation = rootTypeParameter.getSpecialization([instantiatedConstraint]);
            if (instantiation) {
                return instantiation;
            }

            instantiation = new TypeScript.PullInstantiatedTypeParameterSymbol(rootTypeParameter, instantiatedConstraint);
            return instantiation;
        };

        PullTypeResolver.prototype.instantiateSignature = function (signature, typeParameterArgumentMap) {
            if (!signature.wrapsSomeTypeParameter(typeParameterArgumentMap)) {
                return signature;
            }

            var rootSignature = signature.getRootSymbol();
            var mutableTypeParameterMap = new TypeScript.PullInstantiationHelpers.MutableTypeArgumentMap(typeParameterArgumentMap);
            TypeScript.PullInstantiationHelpers.instantiateTypeArgument(this, signature, mutableTypeParameterMap);

            var instantiatedSignature = rootSignature.getSpecialization(mutableTypeParameterMap.typeParameterArgumentMap);
            if (instantiatedSignature) {
                return instantiatedSignature;
            }

            TypeScript.PullInstantiationHelpers.cleanUpTypeArgumentMap(signature, mutableTypeParameterMap);
            typeParameterArgumentMap = mutableTypeParameterMap.typeParameterArgumentMap;

            instantiatedSignature = new TypeScript.PullInstantiatedSignatureSymbol(rootSignature, typeParameterArgumentMap);

            instantiatedSignature.returnType = this.instantiateType((rootSignature.returnType || this.semanticInfoChain.anyTypeSymbol), typeParameterArgumentMap);
            instantiatedSignature.functionType = this.instantiateType(rootSignature.functionType, typeParameterArgumentMap);

            var parameters = rootSignature.parameters;
            var parameter = null;

            if (parameters) {
                for (var j = 0; j < parameters.length; j++) {
                    parameter = new TypeScript.PullSymbol(parameters[j].name, 2048 /* Parameter */);
                    parameter.setRootSymbol(parameters[j]);

                    if (parameters[j].isOptional) {
                        parameter.isOptional = true;
                    }
                    if (parameters[j].isVarArg) {
                        parameter.isVarArg = true;
                        instantiatedSignature.hasVarArgs = true;
                    }
                    instantiatedSignature.addParameter(parameter, parameter.isOptional);

                    parameter.type = this.instantiateType(parameters[j].type, typeParameterArgumentMap);
                }
            }

            return instantiatedSignature;
        };
        PullTypeResolver.globalTypeCheckPhase = 0;
        return PullTypeResolver;
    })();
    TypeScript.PullTypeResolver = PullTypeResolver;

    var TypeComparisonInfo = (function () {
        function TypeComparisonInfo(sourceComparisonInfo, useSameIndent) {
            this.onlyCaptureFirstError = false;
            this.flags = 0 /* SuccessfulComparison */;
            this.message = "";
            this.stringConstantVal = null;
            this.indent = 1;
            if (sourceComparisonInfo) {
                this.flags = sourceComparisonInfo.flags;
                this.onlyCaptureFirstError = sourceComparisonInfo.onlyCaptureFirstError;
                this.stringConstantVal = sourceComparisonInfo.stringConstantVal;
                this.indent = sourceComparisonInfo.indent;
                if (!useSameIndent) {
                    this.indent++;
                }
            }
        }
        TypeComparisonInfo.prototype.indentString = function () {
            var result = "";

            for (var i = 0; i < this.indent; i++) {
                result += "\t";
            }

            return result;
        };

        TypeComparisonInfo.prototype.addMessage = function (message) {
            if (!this.onlyCaptureFirstError && this.message) {
                this.message = this.message + TypeScript.newLine() + this.indentString() + message;
            } else {
                this.message = this.indentString() + message;
            }
        };
        return TypeComparisonInfo;
    })();
    TypeScript.TypeComparisonInfo = TypeComparisonInfo;

    function getPropertyAssignmentNameTextFromIdentifier(identifier) {
        if (identifier.kind() === 11 /* IdentifierName */) {
            return { actualText: identifier.text(), memberName: identifier.valueText() };
        } else if (identifier.kind() === 14 /* StringLiteral */) {
            return { actualText: identifier.text(), memberName: identifier.valueText() };
        } else if (identifier.kind() === 13 /* NumericLiteral */) {
            return { actualText: identifier.text(), memberName: identifier.valueText() };
        } else {
            throw TypeScript.Errors.invalidOperation();
        }
    }
    TypeScript.getPropertyAssignmentNameTextFromIdentifier = getPropertyAssignmentNameTextFromIdentifier;

    function isTypesOnlyLocation(ast) {
        while (ast && ast.parent) {
            switch (ast.parent.kind()) {
                case 244 /* TypeAnnotation */:
                    return true;
                case 127 /* TypeQuery */:
                    return false;
                case 125 /* ConstructorType */:
                    var constructorType = ast.parent;
                    if (constructorType.type === ast) {
                        return true;
                    }
                    break;
                case 123 /* FunctionType */:
                    var functionType = ast.parent;
                    if (functionType.type === ast) {
                        return true;
                    }
                    break;
                case 239 /* Constraint */:
                    var constraint = ast.parent;
                    if (constraint.type === ast) {
                        return true;
                    }
                    break;
                case 220 /* CastExpression */:
                    var castExpression = ast.parent;
                    return castExpression.type === ast;
                case 230 /* ExtendsHeritageClause */:
                case 231 /* ImplementsHeritageClause */:
                    return true;
                case 228 /* TypeArgumentList */:
                    return true;
                case 131 /* ClassDeclaration */:
                case 128 /* InterfaceDeclaration */:
                case 130 /* ModuleDeclaration */:
                case 129 /* FunctionDeclaration */:
                case 145 /* MethodSignature */:
                case 212 /* MemberAccessExpression */:
                case 242 /* Parameter */:
                    return false;
            }

            ast = ast.parent;
        }

        return false;
    }
    TypeScript.isTypesOnlyLocation = isTypesOnlyLocation;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    TypeScript.declCacheHit = 0;
    TypeScript.declCacheMiss = 0;
    TypeScript.symbolCacheHit = 0;
    TypeScript.symbolCacheMiss = 0;

    var sentinalEmptyArray = [];

    var SemanticInfoChain = (function () {
        function SemanticInfoChain(compiler, logger) {
            this.compiler = compiler;
            this.logger = logger;
            this.documents = [];
            this.fileNameToDocument = TypeScript.createIntrinsicsObject();
            this.anyTypeDecl = null;
            this.booleanTypeDecl = null;
            this.numberTypeDecl = null;
            this.stringTypeDecl = null;
            this.nullTypeDecl = null;
            this.undefinedTypeDecl = null;
            this.voidTypeDecl = null;
            this.undefinedValueDecl = null;
            this.anyTypeSymbol = null;
            this.booleanTypeSymbol = null;
            this.numberTypeSymbol = null;
            this.stringTypeSymbol = null;
            this.nullTypeSymbol = null;
            this.undefinedTypeSymbol = null;
            this.voidTypeSymbol = null;
            this.undefinedValueSymbol = null;
            this.emptyTypeSymbol = null;
            this.astSymbolMap = [];
            this.astAliasSymbolMap = [];
            this.astCallResolutionDataMap = [];
            this.declSymbolMap = [];
            this.declSignatureSymbolMap = [];
            this.declCache = null;
            this.symbolCache = null;
            this.fileNameToDiagnostics = null;
            this._binder = null;
            this._resolver = null;
            this._topLevelDecls = null;
            this._fileNames = null;
            var globalDecl = new TypeScript.RootPullDecl("", "", 0 /* Global */, 0 /* None */, this, false);
            this.documents[0] = new TypeScript.Document(this.compiler, this, "", [], null, 0 /* None */, 0, false, null, globalDecl);

            this.anyTypeDecl = new TypeScript.NormalPullDecl("any", "any", 2 /* Primitive */, 0 /* None */, globalDecl);
            this.booleanTypeDecl = new TypeScript.NormalPullDecl("boolean", "boolean", 2 /* Primitive */, 0 /* None */, globalDecl);
            this.numberTypeDecl = new TypeScript.NormalPullDecl("number", "number", 2 /* Primitive */, 0 /* None */, globalDecl);
            this.stringTypeDecl = new TypeScript.NormalPullDecl("string", "string", 2 /* Primitive */, 0 /* None */, globalDecl);
            this.voidTypeDecl = new TypeScript.NormalPullDecl("void", "void", 2 /* Primitive */, 0 /* None */, globalDecl);

            this.nullTypeDecl = new TypeScript.RootPullDecl("null", "", 2 /* Primitive */, 0 /* None */, this, false);
            this.undefinedTypeDecl = new TypeScript.RootPullDecl("undefined", "", 2 /* Primitive */, 0 /* None */, this, false);
            this.undefinedValueDecl = new TypeScript.NormalPullDecl("undefined", "undefined", 512 /* Variable */, 8 /* Ambient */, globalDecl);

            this.invalidate();
        }
        SemanticInfoChain.prototype.getDocument = function (fileName) {
            var document = this.fileNameToDocument[fileName];
            return document || null;
        };

        SemanticInfoChain.prototype.lineMap = function (fileName) {
            return this.getDocument(fileName).lineMap();
        };

        SemanticInfoChain.prototype.fileNames = function () {
            if (this._fileNames === null) {
                this._fileNames = this.documents.slice(1).map(function (s) {
                    return s.fileName;
                });
            }

            return this._fileNames;
        };

        SemanticInfoChain.prototype.bindPrimitiveSymbol = function (decl, newSymbol) {
            newSymbol.addDeclaration(decl);
            decl.setSymbol(newSymbol);
            newSymbol.setResolved();

            return newSymbol;
        };

        SemanticInfoChain.prototype.addPrimitiveTypeSymbol = function (decl) {
            var newSymbol = new TypeScript.PullPrimitiveTypeSymbol(decl.name);
            return this.bindPrimitiveSymbol(decl, newSymbol);
        };

        SemanticInfoChain.prototype.addPrimitiveValueSymbol = function (decl, type) {
            var newSymbol = new TypeScript.PullSymbol(decl.name, 512 /* Variable */);
            newSymbol.type = type;
            return this.bindPrimitiveSymbol(decl, newSymbol);
        };

        SemanticInfoChain.prototype.resetGlobalSymbols = function () {
            this.anyTypeSymbol = this.addPrimitiveTypeSymbol(this.anyTypeDecl);
            this.booleanTypeSymbol = this.addPrimitiveTypeSymbol(this.booleanTypeDecl);
            this.numberTypeSymbol = this.addPrimitiveTypeSymbol(this.numberTypeDecl);
            this.stringTypeSymbol = this.addPrimitiveTypeSymbol(this.stringTypeDecl);
            this.voidTypeSymbol = this.addPrimitiveTypeSymbol(this.voidTypeDecl);
            this.nullTypeSymbol = this.addPrimitiveTypeSymbol(this.nullTypeDecl);
            this.undefinedTypeSymbol = this.addPrimitiveTypeSymbol(this.undefinedTypeDecl);
            this.undefinedValueSymbol = this.addPrimitiveValueSymbol(this.undefinedValueDecl, this.undefinedTypeSymbol);

            var emptyTypeDecl = new TypeScript.PullSynthesizedDecl("{}", "{}", 8388608 /* ObjectType */, 0 /* None */, null, this);
            var emptyTypeSymbol = new TypeScript.PullTypeSymbol("{}", 8388608 /* ObjectType */);
            emptyTypeDecl.setSymbol(emptyTypeSymbol);
            emptyTypeSymbol.addDeclaration(emptyTypeDecl);
            emptyTypeSymbol.setResolved();
            this.emptyTypeSymbol = emptyTypeSymbol;
        };

        SemanticInfoChain.prototype.addDocument = function (document) {
            var fileName = document.fileName;

            var existingIndex = TypeScript.ArrayUtilities.indexOf(this.documents, function (u) {
                return u.fileName === fileName;
            });
            if (existingIndex < 0) {
                this.documents.push(document);
            } else {
                this.documents[existingIndex] = document;
            }

            this.fileNameToDocument[fileName] = document;

            this.invalidate();
        };

        SemanticInfoChain.prototype.removeDocument = function (fileName) {
            TypeScript.Debug.assert(fileName !== "", "Can't remove the semantic info for the global decl.");
            var index = TypeScript.ArrayUtilities.indexOf(this.documents, function (u) {
                return u.fileName === fileName;
            });
            if (index > 0) {
                this.fileNameToDocument[fileName] = undefined;
                this.documents.splice(index, 1);
                this.invalidate();
            }
        };

        SemanticInfoChain.prototype.getDeclPathCacheID = function (declPath, declKind) {
            var cacheID = "";

            for (var i = 0; i < declPath.length; i++) {
                cacheID += "#" + declPath[i];
            }

            return cacheID + "#" + declKind.toString();
        };

        SemanticInfoChain.prototype.findTopLevelSymbol = function (name, kind, doNotGoPastThisDecl) {
            var cacheID = this.getDeclPathCacheID([name], kind);

            var symbol = this.symbolCache[cacheID];

            if (!symbol) {
                for (var i = 0, n = this.documents.length; i < n; i++) {
                    var topLevelDecl = this.documents[i].topLevelDecl();

                    var symbol = this.findTopLevelSymbolInDecl(topLevelDecl, name, kind, doNotGoPastThisDecl);
                    if (symbol) {
                        break;
                    }

                    if (doNotGoPastThisDecl && topLevelDecl.name === doNotGoPastThisDecl.fileName()) {
                        return null;
                    }
                }

                if (symbol) {
                    this.symbolCache[cacheID] = symbol;
                }
            }

            return symbol;
        };

        SemanticInfoChain.prototype.findTopLevelSymbolInDecl = function (topLevelDecl, name, kind, doNotGoPastThisDecl) {
            var doNotGoPastThisPosition = doNotGoPastThisDecl && doNotGoPastThisDecl.fileName() === topLevelDecl.fileName() ? doNotGoPastThisDecl.ast().start() : -1;

            var foundDecls = topLevelDecl.searchChildDecls(name, kind);

            for (var j = 0; j < foundDecls.length; j++) {
                var foundDecl = foundDecls[j];

                if (doNotGoPastThisPosition !== -1 && foundDecl.ast() && foundDecl.ast().start() > doNotGoPastThisPosition) {
                    break;
                }

                var symbol = foundDecls[j].getSymbol();
                if (symbol) {
                    return symbol;
                }
            }

            return null;
        };

        SemanticInfoChain.prototype.findExternalModule = function (id) {
            id = TypeScript.normalizePath(id);

            var tsFile = id + ".ts";
            var tsCacheID = this.getDeclPathCacheID([tsFile], 32 /* DynamicModule */);
            symbol = this.symbolCache[tsCacheID];
            if (symbol != undefined) {
                return symbol;
            }

            var dtsFile = id + ".d.ts";
            var dtsCacheID = this.getDeclPathCacheID([dtsFile], 32 /* DynamicModule */);
            var symbol = this.symbolCache[dtsCacheID];
            if (symbol) {
                return symbol;
            }

            var dtsSymbol;
            for (var i = 0; i < this.documents.length; i++) {
                var document = this.documents[i];
                var topLevelDecl = document.topLevelDecl();

                if (topLevelDecl.isExternalModule()) {
                    var isTsFile = document.fileName === tsFile;
                    if (isTsFile || document.fileName === dtsFile) {
                        var dynamicModuleDecl = topLevelDecl.getChildDecls()[0];
                        symbol = dynamicModuleDecl.getSymbol();

                        if (isTsFile) {
                            this.symbolCache[tsCacheID] = symbol;

                            return symbol;
                        } else {
                            dtsSymbol = symbol;
                        }
                    }
                }
            }

            if (dtsSymbol) {
                this.symbolCache[dtsCacheID] = symbol;
                return dtsSymbol;
            }

            this.symbolCache[dtsCacheID] = null;
            this.symbolCache[tsCacheID] = null;

            return null;
        };

        SemanticInfoChain.prototype.findAmbientExternalModuleInGlobalContext = function (id) {
            var cacheID = this.getDeclPathCacheID([id], 32 /* DynamicModule */);

            var symbol = this.symbolCache[cacheID];
            if (symbol == undefined) {
                symbol = null;
                for (var i = 0; i < this.documents.length; i++) {
                    var document = this.documents[i];
                    var topLevelDecl = document.topLevelDecl();

                    if (!topLevelDecl.isExternalModule()) {
                        var dynamicModules = topLevelDecl.searchChildDecls(id, 32 /* DynamicModule */);
                        if (dynamicModules.length) {
                            symbol = dynamicModules[0].getSymbol();
                            break;
                        }
                    }
                }

                this.symbolCache[cacheID] = symbol;
            }

            return symbol;
        };

        SemanticInfoChain.prototype.findDecls = function (declPath, declKind) {
            var cacheID = this.getDeclPathCacheID(declPath, declKind);

            if (declPath.length) {
                var cachedDecls = this.declCache[cacheID];

                if (cachedDecls && cachedDecls.length) {
                    TypeScript.declCacheHit++;
                    return cachedDecls;
                }
            }

            TypeScript.declCacheMiss++;

            var declsToSearch = this.topLevelDecls();

            var decls = TypeScript.sentinelEmptyArray;
            var path;
            var foundDecls = TypeScript.sentinelEmptyArray;

            for (var i = 0; i < declPath.length; i++) {
                path = declPath[i];
                decls = TypeScript.sentinelEmptyArray;

                var kind = (i === declPath.length - 1) ? declKind : 164 /* SomeContainer */;
                for (var j = 0; j < declsToSearch.length; j++) {
                    foundDecls = declsToSearch[j].searchChildDecls(path, kind);

                    for (var k = 0; k < foundDecls.length; k++) {
                        if (decls === TypeScript.sentinelEmptyArray) {
                            decls = [];
                        }
                        decls[decls.length] = foundDecls[k];
                    }
                }

                declsToSearch = decls;

                if (!declsToSearch) {
                    break;
                }
            }

            if (decls.length) {
                this.declCache[cacheID] = decls;
            }

            return decls;
        };

        SemanticInfoChain.prototype.findDeclsFromPath = function (declPath, declKind) {
            var declString = [];

            for (var i = 0, n = declPath.length; i < n; i++) {
                if (declPath[i].kind & 1 /* Script */) {
                    continue;
                }

                declString.push(declPath[i].name);
            }

            return this.findDecls(declString, declKind);
        };

        SemanticInfoChain.prototype.findSymbol = function (declPath, declType) {
            var cacheID = this.getDeclPathCacheID(declPath, declType);

            if (declPath.length) {
                var cachedSymbol = this.symbolCache[cacheID];

                if (cachedSymbol) {
                    TypeScript.symbolCacheHit++;
                    return cachedSymbol;
                }
            }

            TypeScript.symbolCacheMiss++;

            var decls = this.findDecls(declPath, declType);
            var symbol = null;

            if (decls.length) {
                var decl = decls[0];
                if (TypeScript.hasFlag(decl.kind, 164 /* SomeContainer */)) {
                    var valueDecl = decl.getValueDecl();
                    if (valueDecl) {
                        valueDecl.ensureSymbolIsBound();
                    }
                }
                symbol = decl.getSymbol();

                if (symbol) {
                    for (var i = 1; i < decls.length; i++) {
                        decls[i].ensureSymbolIsBound();
                    }

                    this.symbolCache[cacheID] = symbol;
                }
            }

            return symbol;
        };

        SemanticInfoChain.prototype.cacheGlobalSymbol = function (symbol, kind) {
            var cacheID1 = this.getDeclPathCacheID([symbol.name], kind);
            var cacheID2 = this.getDeclPathCacheID([symbol.name], symbol.kind);

            if (!this.symbolCache[cacheID1]) {
                this.symbolCache[cacheID1] = symbol;
            }

            if (!this.symbolCache[cacheID2]) {
                this.symbolCache[cacheID2] = symbol;
            }
        };

        SemanticInfoChain.prototype.invalidate = function (oldSettings, newSettings) {
            if (typeof oldSettings === "undefined") { oldSettings = null; }
            if (typeof newSettings === "undefined") { newSettings = null; }
            TypeScript.PullTypeResolver.globalTypeCheckPhase++;

            var cleanStart = new Date().getTime();

            this.astSymbolMap.length = 0;
            this.astAliasSymbolMap.length = 0;
            this.astCallResolutionDataMap.length = 0;

            this.declCache = TypeScript.createIntrinsicsObject();
            this.symbolCache = TypeScript.createIntrinsicsObject();
            this.fileNameToDiagnostics = TypeScript.createIntrinsicsObject();
            this._binder = null;
            this._resolver = null;
            this._topLevelDecls = null;
            this._fileNames = null;

            this.declSymbolMap.length = 0;
            this.declSignatureSymbolMap.length = 0;

            if (oldSettings && newSettings) {
                if (this.settingsChangeAffectsSyntax(oldSettings, newSettings)) {
                    for (var i = 1, n = this.documents.length; i < n; i++) {
                        this.documents[i].invalidate();
                    }
                }
            }

            TypeScript.pullSymbolID = 0;

            this.resetGlobalSymbols();

            var cleanEnd = new Date().getTime();
        };

        SemanticInfoChain.prototype.settingsChangeAffectsSyntax = function (before, after) {
            return before.allowAutomaticSemicolonInsertion() !== after.allowAutomaticSemicolonInsertion() || before.codeGenTarget() !== after.codeGenTarget() || before.propagateEnumConstants() !== after.propagateEnumConstants();
        };

        SemanticInfoChain.prototype.setSymbolForAST = function (ast, symbol) {
            this.astSymbolMap[ast.syntaxID()] = symbol;
        };

        SemanticInfoChain.prototype.getSymbolForAST = function (ast) {
            return this.astSymbolMap[ast.syntaxID()] || null;
        };

        SemanticInfoChain.prototype.setAliasSymbolForAST = function (ast, symbol) {
            this.astAliasSymbolMap[ast.syntaxID()] = symbol;
        };

        SemanticInfoChain.prototype.getAliasSymbolForAST = function (ast) {
            return this.astAliasSymbolMap[ast.syntaxID()];
        };

        SemanticInfoChain.prototype.getCallResolutionDataForAST = function (ast) {
            return this.astCallResolutionDataMap[ast.syntaxID()];
        };

        SemanticInfoChain.prototype.setCallResolutionDataForAST = function (ast, callResolutionData) {
            if (callResolutionData) {
                this.astCallResolutionDataMap[ast.syntaxID()] = callResolutionData;
            }
        };

        SemanticInfoChain.prototype.setSymbolForDecl = function (decl, symbol) {
            this.declSymbolMap[decl.declID] = symbol;
        };

        SemanticInfoChain.prototype.getSymbolForDecl = function (decl) {
            return this.declSymbolMap[decl.declID];
        };

        SemanticInfoChain.prototype.setSignatureSymbolForDecl = function (decl, signatureSymbol) {
            this.declSignatureSymbolMap[decl.declID] = signatureSymbol;
        };

        SemanticInfoChain.prototype.getSignatureSymbolForDecl = function (decl) {
            return this.declSignatureSymbolMap[decl.declID];
        };

        SemanticInfoChain.prototype.addDiagnostic = function (diagnostic) {
            var fileName = diagnostic.fileName();
            var diagnostics = this.fileNameToDiagnostics[fileName];
            if (!diagnostics) {
                diagnostics = [];
                this.fileNameToDiagnostics[fileName] = diagnostics;
            }

            diagnostics.push(diagnostic);
        };

        SemanticInfoChain.prototype.getDiagnostics = function (fileName) {
            var diagnostics = this.fileNameToDiagnostics[fileName];
            return diagnostics || [];
        };

        SemanticInfoChain.prototype.getBinder = function () {
            if (!this._binder) {
                this._binder = new TypeScript.PullSymbolBinder(this);
            }

            return this._binder;
        };

        SemanticInfoChain.prototype.getResolver = function () {
            if (!this._resolver) {
                this._resolver = new TypeScript.PullTypeResolver(this.compiler.compilationSettings(), this);
            }

            return this._resolver;
        };

        SemanticInfoChain.prototype.addSyntheticIndexSignature = function (containingDecl, containingSymbol, ast, indexParamName, indexParamType, returnType) {
            var indexSignature = new TypeScript.PullSignatureSymbol(4194304 /* IndexSignature */);
            var indexParameterSymbol = new TypeScript.PullSymbol(indexParamName, 2048 /* Parameter */);
            indexParameterSymbol.type = indexParamType;
            indexSignature.addParameter(indexParameterSymbol);
            indexSignature.returnType = returnType;
            indexSignature.setResolved();
            indexParameterSymbol.setResolved();

            containingSymbol.addIndexSignature(indexSignature);

            var indexSigDecl = new TypeScript.PullSynthesizedDecl("", "", 4194304 /* IndexSignature */, 2048 /* Signature */, containingDecl, containingDecl.semanticInfoChain);
            var indexParamDecl = new TypeScript.PullSynthesizedDecl(indexParamName, indexParamName, 2048 /* Parameter */, 0 /* None */, indexSigDecl, containingDecl.semanticInfoChain);
            indexSigDecl.setSignatureSymbol(indexSignature);
            indexParamDecl.setSymbol(indexParameterSymbol);
            indexSignature.addDeclaration(indexSigDecl);
            indexParameterSymbol.addDeclaration(indexParamDecl);
        };

        SemanticInfoChain.prototype.getDeclForAST = function (ast) {
            var document = this.getDocument(ast.fileName());

            if (document) {
                return document._getDeclForAST(ast);
            }

            return null;
        };

        SemanticInfoChain.prototype.getEnclosingDecl = function (ast) {
            return this.getDocument(ast.fileName()).getEnclosingDecl(ast);
        };

        SemanticInfoChain.prototype.setDeclForAST = function (ast, decl) {
            this.getDocument(decl.fileName())._setDeclForAST(ast, decl);
        };

        SemanticInfoChain.prototype.getASTForDecl = function (decl) {
            var document = this.getDocument(decl.fileName());
            if (document) {
                return document._getASTForDecl(decl);
            }

            return null;
        };

        SemanticInfoChain.prototype.setASTForDecl = function (decl, ast) {
            this.getDocument(decl.fileName())._setASTForDecl(decl, ast);
        };

        SemanticInfoChain.prototype.topLevelDecl = function (fileName) {
            var document = this.getDocument(fileName);
            if (document) {
                return document.topLevelDecl();
            }

            return null;
        };

        SemanticInfoChain.prototype.topLevelDecls = function () {
            if (!this._topLevelDecls) {
                this._topLevelDecls = TypeScript.ArrayUtilities.select(this.documents, function (u) {
                    return u.topLevelDecl();
                });
            }

            return this._topLevelDecls;
        };

        SemanticInfoChain.prototype.addDiagnosticFromAST = function (ast, diagnosticKey, _arguments, additionalLocations) {
            if (typeof _arguments === "undefined") { _arguments = null; }
            if (typeof additionalLocations === "undefined") { additionalLocations = null; }
            this.addDiagnostic(this.diagnosticFromAST(ast, diagnosticKey, _arguments, additionalLocations));
        };

        SemanticInfoChain.prototype.diagnosticFromAST = function (ast, diagnosticKey, _arguments, additionalLocations) {
            if (typeof _arguments === "undefined") { _arguments = null; }
            if (typeof additionalLocations === "undefined") { additionalLocations = null; }
            return new TypeScript.Diagnostic(ast.fileName(), this.lineMap(ast.fileName()), ast.start(), ast.width(), diagnosticKey, _arguments, additionalLocations);
        };

        SemanticInfoChain.prototype.locationFromAST = function (ast) {
            return new TypeScript.Location(ast.fileName(), this.lineMap(ast.fileName()), ast.start(), ast.width());
        };

        SemanticInfoChain.prototype.duplicateIdentifierDiagnosticFromAST = function (ast, identifier, additionalLocationAST) {
            return this.diagnosticFromAST(ast, TypeScript.DiagnosticCode.Duplicate_identifier_0, [identifier], additionalLocationAST ? [this.locationFromAST(additionalLocationAST)] : null);
        };

        SemanticInfoChain.prototype.addDuplicateIdentifierDiagnosticFromAST = function (ast, identifier, additionalLocationAST) {
            this.addDiagnostic(this.duplicateIdentifierDiagnosticFromAST(ast, identifier, additionalLocationAST));
        };
        return SemanticInfoChain;
    })();
    TypeScript.SemanticInfoChain = SemanticInfoChain;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var DeclCollectionContext = (function () {
        function DeclCollectionContext(document, semanticInfoChain, propagateEnumConstants) {
            this.document = document;
            this.semanticInfoChain = semanticInfoChain;
            this.propagateEnumConstants = propagateEnumConstants;
            this.isDeclareFile = false;
            this.parentChain = [];
        }
        DeclCollectionContext.prototype.getParent = function () {
            return this.parentChain ? this.parentChain[this.parentChain.length - 1] : null;
        };

        DeclCollectionContext.prototype.pushParent = function (parentDecl) {
            if (parentDecl) {
                this.parentChain[this.parentChain.length] = parentDecl;
            }
        };

        DeclCollectionContext.prototype.popParent = function () {
            this.parentChain.length--;
        };
        return DeclCollectionContext;
    })();

    function moduleElementsHasExportAssignment(moduleElements) {
        return moduleElements.any(function (m) {
            return m.kind() === 134 /* ExportAssignment */;
        });
    }

    function containingModuleHasExportAssignment(ast) {
        ast = ast.parent;
        while (ast) {
            if (ast.kind() === 130 /* ModuleDeclaration */) {
                var moduleDecl = ast;
                return moduleElementsHasExportAssignment(moduleDecl.moduleElements);
            } else if (ast.kind() === 120 /* SourceUnit */) {
                var sourceUnit = ast;
                return moduleElementsHasExportAssignment(sourceUnit.moduleElements);
            }

            ast = ast.parent;
        }

        return false;
    }

    function isParsingAmbientModule(ast, context) {
        ast = ast.parent;
        while (ast) {
            if (ast.kind() === 130 /* ModuleDeclaration */) {
                if (TypeScript.hasModifier(ast.modifiers, 8 /* Ambient */)) {
                    return true;
                }
            }

            ast = ast.parent;
        }

        return false;
    }

    function preCollectImportDecls(ast, context) {
        var importDecl = ast;
        var declFlags = 0 /* None */;

        var parent = context.getParent();

        if (TypeScript.hasModifier(importDecl.modifiers, 1 /* Exported */) && !containingModuleHasExportAssignment(ast)) {
            declFlags |= 1 /* Exported */;
        }

        var decl = new TypeScript.NormalPullDecl(importDecl.identifier.valueText(), importDecl.identifier.text(), 128 /* TypeAlias */, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(ast, decl);
        context.semanticInfoChain.setASTForDecl(decl, ast);
    }

    function preCollectScriptDecls(sourceUnit, context) {
        var fileName = sourceUnit.fileName();

        var isExternalModule = context.document.isExternalModule();

        var decl = new TypeScript.RootPullDecl(fileName, fileName, 1 /* Script */, 0 /* None */, context.semanticInfoChain, isExternalModule);
        context.semanticInfoChain.setDeclForAST(sourceUnit, decl);
        context.semanticInfoChain.setASTForDecl(decl, sourceUnit);

        context.isDeclareFile = context.document.isDeclareFile();

        context.pushParent(decl);

        if (isExternalModule) {
            var declFlags = 1 /* Exported */;
            if (TypeScript.isDTSFile(fileName)) {
                declFlags |= 8 /* Ambient */;
            }

            var moduleContainsExecutableCode = containsExecutableCode(sourceUnit.moduleElements);
            var kind = 32 /* DynamicModule */;
            var valueText = TypeScript.quoteStr(fileName);

            var decl = new TypeScript.NormalPullDecl(valueText, fileName, kind, declFlags, context.getParent());

            context.semanticInfoChain.setASTForDecl(decl, sourceUnit);

            context.semanticInfoChain.setDeclForAST(sourceUnit, decl);

            if (!moduleElementsHasExportAssignment(sourceUnit.moduleElements) || moduleContainsExecutableCode) {
                createModuleVariableDecl(decl, sourceUnit, context);
            }

            context.pushParent(decl);
        }
    }

    function preCollectEnumDecls(enumDecl, context) {
        var declFlags = 0 /* None */;
        var enumName = enumDecl.identifier.valueText();

        if ((TypeScript.hasModifier(enumDecl.modifiers, 1 /* Exported */) || isParsingAmbientModule(enumDecl, context)) && !containingModuleHasExportAssignment(enumDecl)) {
            declFlags |= 1 /* Exported */;
        }

        if (TypeScript.hasModifier(enumDecl.modifiers, 8 /* Ambient */) || isParsingAmbientModule(enumDecl, context) || context.isDeclareFile) {
            declFlags |= 8 /* Ambient */;
        }

        declFlags |= 4096 /* Enum */;
        var kind = 64 /* Enum */;

        var enumDeclaration = new TypeScript.NormalPullDecl(enumName, enumDecl.identifier.text(), kind, declFlags, context.getParent());
        context.semanticInfoChain.setDeclForAST(enumDecl, enumDeclaration);
        context.semanticInfoChain.setASTForDecl(enumDeclaration, enumDecl);

        var valueDecl = new TypeScript.NormalPullDecl(enumDeclaration.name, enumDeclaration.getDisplayName(), 512 /* Variable */, enumDeclaration.flags, context.getParent());
        enumDeclaration.setValueDecl(valueDecl);
        context.semanticInfoChain.setASTForDecl(valueDecl, enumDecl);

        context.pushParent(enumDeclaration);
    }

    function createEnumElementDecls(propertyDecl, context) {
        var parent = context.getParent();

        var decl = new TypeScript.PullEnumElementDecl(propertyDecl.propertyName.valueText(), propertyDecl.propertyName.text(), parent);
        context.semanticInfoChain.setDeclForAST(propertyDecl, decl);
        context.semanticInfoChain.setASTForDecl(decl, propertyDecl);
    }

    function preCollectModuleDecls(moduleDecl, context) {
        var declFlags = 0 /* None */;

        var moduleContainsExecutableCode = containsExecutableCode(moduleDecl.moduleElements);

        var isDynamic = moduleDecl.stringLiteral !== null;

        if ((TypeScript.hasModifier(moduleDecl.modifiers, 1 /* Exported */) || isParsingAmbientModule(moduleDecl, context)) && !containingModuleHasExportAssignment(moduleDecl)) {
            declFlags |= 1 /* Exported */;
        }

        if (TypeScript.hasModifier(moduleDecl.modifiers, 8 /* Ambient */) || isParsingAmbientModule(moduleDecl, context) || context.isDeclareFile) {
            declFlags |= 8 /* Ambient */;
        }

        var kind = isDynamic ? 32 /* DynamicModule */ : 4 /* Container */;

        if (moduleDecl.stringLiteral) {
            var valueText = TypeScript.quoteStr(moduleDecl.stringLiteral.valueText());
            var text = moduleDecl.stringLiteral.text();

            var decl = new TypeScript.NormalPullDecl(valueText, text, kind, declFlags, context.getParent());

            context.semanticInfoChain.setDeclForAST(moduleDecl, decl);
            context.semanticInfoChain.setDeclForAST(moduleDecl.stringLiteral, decl);
            context.semanticInfoChain.setASTForDecl(decl, moduleDecl.stringLiteral);

            if (!moduleElementsHasExportAssignment(moduleDecl.moduleElements) || moduleContainsExecutableCode) {
                createModuleVariableDecl(decl, moduleDecl.stringLiteral, context);
            }

            context.pushParent(decl);
        } else {
            var moduleNames = TypeScript.ASTHelpers.getModuleNames(moduleDecl.name);
            for (var i = 0, n = moduleNames.length; i < n; i++) {
                var moduleName = moduleNames[i];

                var specificFlags = declFlags;
                if (i > 0) {
                    specificFlags |= 1 /* Exported */;
                }

                var decl = new TypeScript.NormalPullDecl(moduleName.valueText(), moduleName.text(), kind, specificFlags, context.getParent());

                context.semanticInfoChain.setDeclForAST(moduleDecl, decl);
                context.semanticInfoChain.setDeclForAST(moduleName, decl);
                context.semanticInfoChain.setASTForDecl(decl, moduleName);

                if (moduleContainsExecutableCode) {
                    createModuleVariableDecl(decl, moduleName, context);
                }

                context.pushParent(decl);
            }
        }
    }

    function createModuleVariableDecl(decl, moduleNameAST, context) {
        decl.setFlags(decl.flags | getInitializationFlag(decl));

        var valueDecl = new TypeScript.NormalPullDecl(decl.name, decl.getDisplayName(), 512 /* Variable */, decl.flags, context.getParent());
        decl.setValueDecl(valueDecl);
        context.semanticInfoChain.setASTForDecl(valueDecl, moduleNameAST);
    }

    function containsExecutableCode(members) {
        for (var i = 0, n = members.childCount(); i < n; i++) {
            var member = members.childAt(i);

            if (member.kind() === 130 /* ModuleDeclaration */) {
                var moduleDecl = member;

                if (containsExecutableCode(moduleDecl.moduleElements)) {
                    return true;
                }
            } else if (member.kind() === 133 /* ImportDeclaration */) {
                if (TypeScript.hasModifier(member.modifiers, 1 /* Exported */)) {
                    return true;
                }
            } else if (member.kind() !== 128 /* InterfaceDeclaration */ && member.kind() !== 134 /* ExportAssignment */) {
                return true;
            }
        }

        return false;
    }

    function preCollectClassDecls(classDecl, context) {
        var declFlags = 0 /* None */;

        if ((TypeScript.hasModifier(classDecl.modifiers, 1 /* Exported */) || isParsingAmbientModule(classDecl, context)) && !containingModuleHasExportAssignment(classDecl)) {
            declFlags |= 1 /* Exported */;
        }

        if (TypeScript.hasModifier(classDecl.modifiers, 8 /* Ambient */) || isParsingAmbientModule(classDecl, context) || context.isDeclareFile) {
            declFlags |= 8 /* Ambient */;
        }

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl(classDecl.identifier.valueText(), classDecl.identifier.text(), 8 /* Class */, declFlags, parent);

        var constructorDecl = new TypeScript.NormalPullDecl(classDecl.identifier.valueText(), classDecl.identifier.text(), 512 /* Variable */, declFlags | 16384 /* ClassConstructorVariable */, parent);

        decl.setValueDecl(constructorDecl);

        context.semanticInfoChain.setDeclForAST(classDecl, decl);
        context.semanticInfoChain.setASTForDecl(decl, classDecl);
        context.semanticInfoChain.setASTForDecl(constructorDecl, classDecl);

        context.pushParent(decl);
    }

    function preCollectObjectTypeDecls(objectType, context) {
        if (objectType.parent.kind() === 128 /* InterfaceDeclaration */) {
            return;
        }

        var declFlags = 0 /* None */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl("", "", 8388608 /* ObjectType */, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(objectType, decl);
        context.semanticInfoChain.setASTForDecl(decl, objectType);

        context.pushParent(decl);
    }

    function preCollectInterfaceDecls(interfaceDecl, context) {
        var declFlags = 0 /* None */;

        if ((TypeScript.hasModifier(interfaceDecl.modifiers, 1 /* Exported */) || isParsingAmbientModule(interfaceDecl, context)) && !containingModuleHasExportAssignment(interfaceDecl)) {
            declFlags |= 1 /* Exported */;
        }

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl(interfaceDecl.identifier.valueText(), interfaceDecl.identifier.text(), 16 /* Interface */, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(interfaceDecl, decl);
        context.semanticInfoChain.setASTForDecl(decl, interfaceDecl);

        context.pushParent(decl);
    }

    function preCollectParameterDecl(argDecl, context) {
        var declFlags = 0 /* None */;

        if (TypeScript.hasModifier(argDecl.modifiers, 2 /* Private */)) {
            declFlags |= 2 /* Private */;
        } else {
            declFlags |= 4 /* Public */;
        }

        if (argDecl.questionToken !== null || argDecl.equalsValueClause !== null || argDecl.dotDotDotToken !== null) {
            declFlags |= 128 /* Optional */;
        }

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(argDecl.identifier.valueText(), argDecl.identifier.text(), 2048 /* Parameter */, declFlags, parent);

        if (argDecl.equalsValueClause) {
            parent.flags |= 33554432 /* HasDefaultArgs */;
        }

        if (parent.kind === 32768 /* ConstructorMethod */) {
            decl.setFlag(67108864 /* ConstructorParameter */);
        }

        var isPublicOrPrivate = TypeScript.hasModifier(argDecl.modifiers, 4 /* Public */ | 2 /* Private */);
        var isInConstructor = parent.kind === 32768 /* ConstructorMethod */;
        if (isPublicOrPrivate && isInConstructor) {
            var parentsParent = context.parentChain[context.parentChain.length - 2];

            var propDeclFlags = declFlags & ~128 /* Optional */;
            var propDecl = new TypeScript.NormalPullDecl(argDecl.identifier.valueText(), argDecl.identifier.text(), 4096 /* Property */, propDeclFlags, parentsParent);
            propDecl.setValueDecl(decl);
            decl.setFlag(8388608 /* PropertyParameter */);
            propDecl.setFlag(8388608 /* PropertyParameter */);

            if (parent.kind === 32768 /* ConstructorMethod */) {
                propDecl.setFlag(67108864 /* ConstructorParameter */);
            }

            context.semanticInfoChain.setASTForDecl(decl, argDecl);
            context.semanticInfoChain.setASTForDecl(propDecl, argDecl);
            context.semanticInfoChain.setDeclForAST(argDecl, propDecl);
        } else {
            context.semanticInfoChain.setASTForDecl(decl, argDecl);
            context.semanticInfoChain.setDeclForAST(argDecl, decl);
        }

        parent.addVariableDeclToGroup(decl);
    }

    function preCollectTypeParameterDecl(typeParameterDecl, context) {
        var declFlags = 0 /* None */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(typeParameterDecl.identifier.valueText(), typeParameterDecl.identifier.text(), 8192 /* TypeParameter */, declFlags, parent);
        context.semanticInfoChain.setASTForDecl(decl, typeParameterDecl);
        context.semanticInfoChain.setDeclForAST(typeParameterDecl, decl);
    }

    function createPropertySignature(propertyDecl, context) {
        var declFlags = 4 /* Public */;
        var parent = context.getParent();
        var declType = 4096 /* Property */;

        if (propertyDecl.questionToken !== null) {
            declFlags |= 128 /* Optional */;
        }

        var decl = new TypeScript.NormalPullDecl(propertyDecl.propertyName.valueText(), propertyDecl.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(propertyDecl, decl);
        context.semanticInfoChain.setASTForDecl(decl, propertyDecl);
    }

    function createMemberVariableDeclaration(memberDecl, context) {
        var declFlags = 0 /* None */;
        var declType = 4096 /* Property */;

        if (TypeScript.hasModifier(memberDecl.modifiers, 2 /* Private */)) {
            declFlags |= 2 /* Private */;
        } else {
            declFlags |= 4 /* Public */;
        }

        if (TypeScript.hasModifier(memberDecl.modifiers, 16 /* Static */)) {
            declFlags |= 16 /* Static */;
        }

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl(memberDecl.variableDeclarator.propertyName.valueText(), memberDecl.variableDeclarator.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(memberDecl, decl);
        context.semanticInfoChain.setDeclForAST(memberDecl.variableDeclarator, decl);
        context.semanticInfoChain.setASTForDecl(decl, memberDecl);
    }

    function createVariableDeclaration(varDecl, context) {
        var declFlags = 0 /* None */;
        var declType = 512 /* Variable */;

        var modifiers = TypeScript.ASTHelpers.getVariableDeclaratorModifiers(varDecl);
        if ((TypeScript.hasModifier(modifiers, 1 /* Exported */) || isParsingAmbientModule(varDecl, context)) && !containingModuleHasExportAssignment(varDecl)) {
            declFlags |= 1 /* Exported */;
        }

        if (TypeScript.hasModifier(modifiers, 8 /* Ambient */) || isParsingAmbientModule(varDecl, context) || context.isDeclareFile) {
            declFlags |= 8 /* Ambient */;
        }

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(varDecl.propertyName.valueText(), varDecl.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(varDecl, decl);
        context.semanticInfoChain.setASTForDecl(decl, varDecl);

        if (parent) {
            parent.addVariableDeclToGroup(decl);
        }
    }

    function preCollectVarDecls(ast, context) {
        if (ast.parent.kind() === 136 /* MemberVariableDeclaration */) {
            return;
        }

        var varDecl = ast;
        createVariableDeclaration(varDecl, context);
    }

    function createFunctionTypeDeclaration(functionTypeDeclAST, context) {
        var declFlags = 2048 /* Signature */;
        var declType = 16777216 /* FunctionType */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(functionTypeDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, functionTypeDeclAST);

        context.pushParent(decl);
    }

    function createConstructorTypeDeclaration(constructorTypeDeclAST, context) {
        var declFlags = 0 /* None */;
        var declType = 33554432 /* ConstructorType */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(constructorTypeDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, constructorTypeDeclAST);

        context.pushParent(decl);
    }

    function createFunctionDeclaration(funcDeclAST, context) {
        var declFlags = 0 /* None */;
        var declType = 16384 /* Function */;

        if ((TypeScript.hasModifier(funcDeclAST.modifiers, 1 /* Exported */) || isParsingAmbientModule(funcDeclAST, context)) && !containingModuleHasExportAssignment(funcDeclAST)) {
            declFlags |= 1 /* Exported */;
        }

        if (TypeScript.hasModifier(funcDeclAST.modifiers, 8 /* Ambient */) || isParsingAmbientModule(funcDeclAST, context) || context.isDeclareFile) {
            declFlags |= 8 /* Ambient */;
        }

        if (!funcDeclAST.block) {
            declFlags |= 2048 /* Signature */;
        }

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(funcDeclAST.identifier.valueText(), funcDeclAST.identifier.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(funcDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, funcDeclAST);

        context.pushParent(decl);
    }

    function createAnyFunctionExpressionDeclaration(functionExpressionDeclAST, id, context, displayName) {
        if (typeof displayName === "undefined") { displayName = null; }
        var declFlags = 0 /* None */;

        if (functionExpressionDeclAST.kind() === 219 /* SimpleArrowFunctionExpression */ || functionExpressionDeclAST.kind() === 218 /* ParenthesizedArrowFunctionExpression */) {
            declFlags |= 8192 /* ArrowFunction */;
        }

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var name = id ? id.text() : "";
        var displayNameText = displayName ? displayName.text() : "";
        var decl = new TypeScript.PullFunctionExpressionDecl(name, declFlags, parent, displayNameText);
        context.semanticInfoChain.setDeclForAST(functionExpressionDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, functionExpressionDeclAST);

        context.pushParent(decl);

        if (functionExpressionDeclAST.kind() === 219 /* SimpleArrowFunctionExpression */) {
            var simpleArrow = functionExpressionDeclAST;
            var declFlags = 4 /* Public */;

            var parent = context.getParent();

            if (TypeScript.hasFlag(parent.flags, 2097152 /* DeclaredInAWithBlock */)) {
                declFlags |= 2097152 /* DeclaredInAWithBlock */;
            }

            var decl = new TypeScript.NormalPullDecl(simpleArrow.identifier.valueText(), simpleArrow.identifier.text(), 2048 /* Parameter */, declFlags, parent);

            context.semanticInfoChain.setASTForDecl(decl, simpleArrow.identifier);
            context.semanticInfoChain.setDeclForAST(simpleArrow.identifier, decl);

            parent.addVariableDeclToGroup(decl);
        }
    }

    function createMemberFunctionDeclaration(funcDecl, context) {
        var declFlags = 0 /* None */;
        var declType = 65536 /* Method */;

        if (TypeScript.hasModifier(funcDecl.modifiers, 16 /* Static */)) {
            declFlags |= 16 /* Static */;
        }

        if (TypeScript.hasModifier(funcDecl.modifiers, 2 /* Private */)) {
            declFlags |= 2 /* Private */;
        } else {
            declFlags |= 4 /* Public */;
        }

        if (!funcDecl.block) {
            declFlags |= 2048 /* Signature */;
        }

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl(funcDecl.propertyName.valueText(), funcDecl.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(funcDecl, decl);
        context.semanticInfoChain.setASTForDecl(decl, funcDecl);

        context.pushParent(decl);
    }

    function createIndexSignatureDeclaration(indexSignatureDeclAST, context) {
        var declFlags = 2048 /* Signature */;
        var declType = 4194304 /* IndexSignature */;

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(indexSignatureDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, indexSignatureDeclAST);

        context.pushParent(decl);
    }

    function createCallSignatureDeclaration(callSignature, context) {
        var isChildOfObjectType = callSignature.parent && callSignature.parent.parent && callSignature.parent.kind() === 2 /* SeparatedList */ && callSignature.parent.parent.kind() === 122 /* ObjectType */;

        if (!isChildOfObjectType) {
            return;
        }

        var declFlags = 2048 /* Signature */;
        var declType = 1048576 /* CallSignature */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(callSignature, decl);
        context.semanticInfoChain.setASTForDecl(decl, callSignature);

        context.pushParent(decl);
    }

    function createMethodSignatureDeclaration(method, context) {
        var declFlags = 0 /* None */;
        var declType = 65536 /* Method */;

        declFlags |= 4 /* Public */;
        declFlags |= 2048 /* Signature */;

        if (method.questionToken !== null) {
            declFlags |= 128 /* Optional */;
        }

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl(method.propertyName.valueText(), method.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(method, decl);
        context.semanticInfoChain.setASTForDecl(decl, method);

        context.pushParent(decl);
    }

    function createConstructSignatureDeclaration(constructSignatureDeclAST, context) {
        var declFlags = 2048 /* Signature */;
        var declType = 2097152 /* ConstructSignature */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(constructSignatureDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, constructSignatureDeclAST);

        context.pushParent(decl);
    }

    function createClassConstructorDeclaration(constructorDeclAST, context) {
        var declFlags = 0 /* None */;
        var declType = 32768 /* ConstructorMethod */;

        if (!constructorDeclAST.block) {
            declFlags |= 2048 /* Signature */;
        }

        var parent = context.getParent();

        if (parent) {
            var parentFlags = parent.flags;

            if (parentFlags & 1 /* Exported */) {
                declFlags |= 1 /* Exported */;
            }
        }

        var decl = new TypeScript.NormalPullDecl(parent.name, parent.getDisplayName(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(constructorDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, constructorDeclAST);

        context.pushParent(decl);
    }

    function createGetAccessorDeclaration(getAccessorDeclAST, context) {
        var declFlags = 4 /* Public */;
        var declType = 262144 /* GetAccessor */;

        if (TypeScript.hasModifier(getAccessorDeclAST.modifiers, 16 /* Static */)) {
            declFlags |= 16 /* Static */;
        }

        if (TypeScript.hasModifier(getAccessorDeclAST.modifiers, 2 /* Private */)) {
            declFlags |= 2 /* Private */;
        } else {
            declFlags |= 4 /* Public */;
        }

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(getAccessorDeclAST.propertyName.valueText(), getAccessorDeclAST.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(getAccessorDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, getAccessorDeclAST);

        context.pushParent(decl);
    }

    function createFunctionExpressionDeclaration(expression, context) {
        createAnyFunctionExpressionDeclaration(expression, expression.identifier, context);
    }

    function createSetAccessorDeclaration(setAccessorDeclAST, context) {
        var declFlags = 4 /* Public */;
        var declType = 524288 /* SetAccessor */;

        if (TypeScript.hasModifier(setAccessorDeclAST.modifiers, 16 /* Static */)) {
            declFlags |= 16 /* Static */;
        }

        if (TypeScript.hasModifier(setAccessorDeclAST.modifiers, 2 /* Private */)) {
            declFlags |= 2 /* Private */;
        } else {
            declFlags |= 4 /* Public */;
        }

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(setAccessorDeclAST.propertyName.valueText(), setAccessorDeclAST.propertyName.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(setAccessorDeclAST, decl);
        context.semanticInfoChain.setASTForDecl(decl, setAccessorDeclAST);

        context.pushParent(decl);
    }

    function preCollectCatchDecls(ast, context) {
        var declFlags = 0 /* None */;
        var declType = 268435456 /* CatchBlock */;

        var parent = context.getParent();

        if (parent && (parent.kind === 134217728 /* WithBlock */ || (parent.flags & 2097152 /* DeclaredInAWithBlock */))) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(ast, decl);
        context.semanticInfoChain.setASTForDecl(decl, ast);

        context.pushParent(decl);

        var declFlags = 0 /* None */;
        var declType = 1024 /* CatchVariable */;

        var parent = context.getParent();

        if (TypeScript.hasFlag(parent.flags, 2097152 /* DeclaredInAWithBlock */)) {
            declFlags |= 2097152 /* DeclaredInAWithBlock */;
        }

        var decl = new TypeScript.NormalPullDecl(ast.identifier.valueText(), ast.identifier.text(), declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(ast.identifier, decl);
        context.semanticInfoChain.setASTForDecl(decl, ast.identifier);

        if (parent) {
            parent.addVariableDeclToGroup(decl);
        }
    }

    function preCollectWithDecls(ast, context) {
        var declFlags = 0 /* None */;
        var declType = 134217728 /* WithBlock */;

        var parent = context.getParent();

        var decl = new TypeScript.NormalPullDecl("", "", declType, declFlags, parent);
        context.semanticInfoChain.setDeclForAST(ast, decl);
        context.semanticInfoChain.setASTForDecl(decl, ast);

        context.pushParent(decl);
    }

    function preCollectObjectLiteralDecls(ast, context) {
        var decl = new TypeScript.NormalPullDecl("", "", 256 /* ObjectLiteral */, 0 /* None */, context.getParent());

        context.semanticInfoChain.setDeclForAST(ast, decl);
        context.semanticInfoChain.setASTForDecl(decl, ast);

        context.pushParent(decl);
    }

    function preCollectSimplePropertyAssignmentDecls(propertyAssignment, context) {
        var assignmentText = TypeScript.getPropertyAssignmentNameTextFromIdentifier(propertyAssignment.propertyName);
        var span = TypeScript.TextSpan.fromBounds(propertyAssignment.start(), propertyAssignment.end());

        var decl = new TypeScript.NormalPullDecl(assignmentText.memberName, assignmentText.actualText, 4096 /* Property */, 4 /* Public */, context.getParent());

        context.semanticInfoChain.setDeclForAST(propertyAssignment, decl);
        context.semanticInfoChain.setASTForDecl(decl, propertyAssignment);
    }

    function preCollectFunctionPropertyAssignmentDecls(propertyAssignment, context) {
        var assignmentText = TypeScript.getPropertyAssignmentNameTextFromIdentifier(propertyAssignment.propertyName);

        var decl = new TypeScript.NormalPullDecl(assignmentText.memberName, assignmentText.actualText, 4096 /* Property */, 4 /* Public */, context.getParent());

        context.semanticInfoChain.setDeclForAST(propertyAssignment, decl);
        context.semanticInfoChain.setASTForDecl(decl, propertyAssignment);

        createAnyFunctionExpressionDeclaration(propertyAssignment, propertyAssignment.propertyName, context, propertyAssignment.propertyName);
    }

    function preCollectDecls(ast, context) {
        switch (ast.kind()) {
            case 120 /* SourceUnit */:
                preCollectScriptDecls(ast, context);
                break;
            case 132 /* EnumDeclaration */:
                preCollectEnumDecls(ast, context);
                break;
            case 243 /* EnumElement */:
                createEnumElementDecls(ast, context);
                break;
            case 130 /* ModuleDeclaration */:
                preCollectModuleDecls(ast, context);
                break;
            case 131 /* ClassDeclaration */:
                preCollectClassDecls(ast, context);
                break;
            case 128 /* InterfaceDeclaration */:
                preCollectInterfaceDecls(ast, context);
                break;
            case 122 /* ObjectType */:
                preCollectObjectTypeDecls(ast, context);
                break;
            case 242 /* Parameter */:
                preCollectParameterDecl(ast, context);
                break;
            case 136 /* MemberVariableDeclaration */:
                createMemberVariableDeclaration(ast, context);
                break;
            case 141 /* PropertySignature */:
                createPropertySignature(ast, context);
                break;
            case 225 /* VariableDeclarator */:
                preCollectVarDecls(ast, context);
                break;
            case 137 /* ConstructorDeclaration */:
                createClassConstructorDeclaration(ast, context);
                break;
            case 139 /* GetAccessor */:
                createGetAccessorDeclaration(ast, context);
                break;
            case 140 /* SetAccessor */:
                createSetAccessorDeclaration(ast, context);
                break;
            case 222 /* FunctionExpression */:
                createFunctionExpressionDeclaration(ast, context);
                break;
            case 135 /* MemberFunctionDeclaration */:
                createMemberFunctionDeclaration(ast, context);
                break;
            case 144 /* IndexSignature */:
                createIndexSignatureDeclaration(ast, context);
                break;
            case 123 /* FunctionType */:
                createFunctionTypeDeclaration(ast, context);
                break;
            case 125 /* ConstructorType */:
                createConstructorTypeDeclaration(ast, context);
                break;
            case 142 /* CallSignature */:
                createCallSignatureDeclaration(ast, context);
                break;
            case 143 /* ConstructSignature */:
                createConstructSignatureDeclaration(ast, context);
                break;
            case 145 /* MethodSignature */:
                createMethodSignatureDeclaration(ast, context);
                break;
            case 129 /* FunctionDeclaration */:
                createFunctionDeclaration(ast, context);
                break;
            case 219 /* SimpleArrowFunctionExpression */:
            case 218 /* ParenthesizedArrowFunctionExpression */:
                createAnyFunctionExpressionDeclaration(ast, null, context);
                break;
            case 133 /* ImportDeclaration */:
                preCollectImportDecls(ast, context);
                break;
            case 238 /* TypeParameter */:
                preCollectTypeParameterDecl(ast, context);
                break;
            case 236 /* CatchClause */:
                preCollectCatchDecls(ast, context);
                break;
            case 163 /* WithStatement */:
                preCollectWithDecls(ast, context);
                break;
            case 215 /* ObjectLiteralExpression */:
                preCollectObjectLiteralDecls(ast, context);
                break;
            case 240 /* SimplePropertyAssignment */:
                preCollectSimplePropertyAssignmentDecls(ast, context);
                break;
            case 241 /* FunctionPropertyAssignment */:
                preCollectFunctionPropertyAssignmentDecls(ast, context);
                break;
        }
    }

    function isContainer(decl) {
        return decl.kind === 4 /* Container */ || decl.kind === 32 /* DynamicModule */ || decl.kind === 64 /* Enum */;
    }

    function getInitializationFlag(decl) {
        if (decl.kind & 4 /* Container */) {
            return 32768 /* InitializedModule */;
        } else if (decl.kind & 32 /* DynamicModule */) {
            return 65536 /* InitializedDynamicModule */;
        }

        return 0 /* None */;
    }

    function hasInitializationFlag(decl) {
        var kind = decl.kind;

        if (kind & 4 /* Container */) {
            return (decl.flags & 32768 /* InitializedModule */) !== 0;
        } else if (kind & 32 /* DynamicModule */) {
            return (decl.flags & 65536 /* InitializedDynamicModule */) !== 0;
        }

        return false;
    }

    function postCollectDecls(ast, context) {
        var currentDecl = context.getParent();

        if (ast.kind() === 11 /* IdentifierName */ || ast.kind() === 14 /* StringLiteral */) {
            if (currentDecl.kind === 4 /* Container */ || currentDecl.kind === 32 /* DynamicModule */) {
                return;
            }
        }

        if (ast.kind() === 130 /* ModuleDeclaration */) {
            var moduleDeclaration = ast;
            if (moduleDeclaration.stringLiteral) {
                TypeScript.Debug.assert(currentDecl.ast() === moduleDeclaration.stringLiteral);
                context.popParent();
            } else {
                var moduleNames = TypeScript.ASTHelpers.getModuleNames(moduleDeclaration.name);
                for (var i = moduleNames.length - 1; i >= 0; i--) {
                    var moduleName = moduleNames[i];
                    TypeScript.Debug.assert(currentDecl.ast() === moduleName);
                    context.popParent();
                    currentDecl = context.getParent();
                }
            }
        }

        if (ast.kind() === 132 /* EnumDeclaration */) {
            computeEnumElementConstantValues(ast, currentDecl, context);
        }

        while (currentDecl.getParentDecl() && currentDecl.ast() === ast) {
            context.popParent();
            currentDecl = context.getParent();
        }
    }

    function computeEnumElementConstantValues(ast, enumDecl, context) {
        TypeScript.Debug.assert(enumDecl.kind === 64 /* Enum */);

        var isAmbientEnum = TypeScript.hasFlag(enumDecl.flags, 8 /* Ambient */);
        var inConstantSection = !isAmbientEnum;
        var currentConstantValue = 0;
        var enumMemberDecls = enumDecl.getChildDecls();

        for (var i = 0, n = ast.enumElements.nonSeparatorCount(); i < n; i++) {
            var enumElement = ast.enumElements.nonSeparatorAt(i);
            var enumElementDecl = TypeScript.ArrayUtilities.first(enumMemberDecls, function (d) {
                return context.semanticInfoChain.getASTForDecl(d) === enumElement;
            });

            TypeScript.Debug.assert(enumElementDecl.kind === 67108864 /* EnumMember */);

            if (enumElement.equalsValueClause === null) {
                if (inConstantSection) {
                    enumElementDecl.constantValue = currentConstantValue;
                    currentConstantValue++;
                }
            } else {
                enumElementDecl.constantValue = computeEnumElementConstantValue(enumElement.equalsValueClause.value, enumMemberDecls, context);
                if (enumElementDecl.constantValue !== null && !isAmbientEnum) {
                    inConstantSection = true;
                    currentConstantValue = enumElementDecl.constantValue + 1;
                } else {
                    inConstantSection = false;
                }
            }

            TypeScript.Debug.assert(enumElementDecl.constantValue !== undefined);
        }
    }

    function computeEnumElementConstantValue(expression, enumMemberDecls, context) {
        TypeScript.Debug.assert(expression);

        if (TypeScript.ASTHelpers.isIntegerLiteralAST(expression)) {
            var token;
            switch (expression.kind()) {
                case 164 /* PlusExpression */:
                case 165 /* NegateExpression */:
                    token = expression.operand;
                    break;
                default:
                    token = expression;
            }

            var value = token.value();
            return value && expression.kind() === 165 /* NegateExpression */ ? -value : value;
        } else if (context.propagateEnumConstants) {
            switch (expression.kind()) {
                case 11 /* IdentifierName */:
                    var name = expression;
                    var matchingEnumElement = TypeScript.ArrayUtilities.firstOrDefault(enumMemberDecls, function (d) {
                        return d.name === name.valueText();
                    });

                    return matchingEnumElement ? matchingEnumElement.constantValue : null;

                case 202 /* LeftShiftExpression */:
                    var binaryExpression = expression;
                    var left = computeEnumElementConstantValue(binaryExpression.left, enumMemberDecls, context);
                    var right = computeEnumElementConstantValue(binaryExpression.right, enumMemberDecls, context);
                    if (left === null || right === null) {
                        return null;
                    }

                    return left << right;

                case 189 /* BitwiseOrExpression */:
                    var binaryExpression = expression;
                    var left = computeEnumElementConstantValue(binaryExpression.left, enumMemberDecls, context);
                    var right = computeEnumElementConstantValue(binaryExpression.right, enumMemberDecls, context);
                    if (left === null || right === null) {
                        return null;
                    }

                    return left | right;
            }

            return null;
        } else {
            return null;
        }
    }

    (function (DeclarationCreator) {
        function create(document, semanticInfoChain, compilationSettings) {
            var declCollectionContext = new DeclCollectionContext(document, semanticInfoChain, compilationSettings.propagateEnumConstants());

            TypeScript.getAstWalkerFactory().simpleWalk(document.sourceUnit(), preCollectDecls, postCollectDecls, declCollectionContext);

            return declCollectionContext.getParent();
        }
        DeclarationCreator.create = create;
    })(TypeScript.DeclarationCreator || (TypeScript.DeclarationCreator = {}));
    var DeclarationCreator = TypeScript.DeclarationCreator;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var PullSymbolBinder = (function () {
        function PullSymbolBinder(semanticInfoChain) {
            this.semanticInfoChain = semanticInfoChain;
            this.declsBeingBound = [];
            this.inBindingOtherDeclsWalker = new TypeScript.PullHelpers.OtherPullDeclsWalker();
        }
        PullSymbolBinder.prototype.getParent = function (decl, returnInstanceType) {
            if (typeof returnInstanceType === "undefined") { returnInstanceType = false; }
            var parentDecl = decl.getParentDecl();

            if (parentDecl.kind === 1 /* Script */) {
                return null;
            }

            var parent = parentDecl.getSymbol();

            if (!parent && parentDecl && !parentDecl.hasBeenBound()) {
                this.bindDeclToPullSymbol(parentDecl);
            }

            parent = parentDecl.getSymbol();
            if (parent) {
                var parentDeclKind = parentDecl.kind;
                if (parentDeclKind === 262144 /* GetAccessor */) {
                    parent = parent.getGetter();
                } else if (parentDeclKind === 524288 /* SetAccessor */) {
                    parent = parent.getSetter();
                }
            }

            if (parent) {
                if (returnInstanceType && parent.isType() && parent.isContainer()) {
                    var instanceSymbol = parent.getInstanceSymbol();

                    if (instanceSymbol) {
                        return instanceSymbol.type;
                    }
                }

                return parent.type;
            }

            return null;
        };

        PullSymbolBinder.prototype.findDeclsInContext = function (startingDecl, declKind, searchGlobally) {
            if (!searchGlobally) {
                var parentDecl = startingDecl.getParentDecl();
                return parentDecl.searchChildDecls(startingDecl.name, declKind);
            }

            var contextSymbolPath = startingDecl.getParentPath();

            if (contextSymbolPath.length) {
                var copyOfContextSymbolPath = [];

                for (var i = 0; i < contextSymbolPath.length; i++) {
                    if (contextSymbolPath[i].kind & 1 /* Script */) {
                        continue;
                    }
                    copyOfContextSymbolPath[copyOfContextSymbolPath.length] = contextSymbolPath[i].name;
                }

                return this.semanticInfoChain.findDecls(copyOfContextSymbolPath, declKind);
            }
        };

        PullSymbolBinder.prototype.getExistingSymbol = function (decl, searchKind, parent) {
            var lookingForValue = (searchKind & 68147712 /* SomeValue */) !== 0;
            var lookingForType = (searchKind & 58728795 /* SomeType */) !== 0;
            var lookingForContainer = (searchKind & 164 /* SomeContainer */) !== 0;
            var name = decl.name;
            if (parent) {
                var isExported = (decl.flags & 1 /* Exported */) !== 0;

                var prevSymbol = null;
                if (lookingForValue) {
                    prevSymbol = parent.findContainedNonMember(name);
                } else if (lookingForType) {
                    prevSymbol = parent.findContainedNonMemberType(name, searchKind);
                } else if (lookingForContainer) {
                    prevSymbol = parent.findContainedNonMemberContainer(name, searchKind);
                }
                var prevIsExported = !prevSymbol;
                if (!prevSymbol) {
                    if (lookingForValue) {
                        prevSymbol = parent.findMember(name, false);
                    } else if (lookingForType) {
                        prevSymbol = parent.findNestedType(name, searchKind);
                    } else if (lookingForContainer) {
                        prevSymbol = parent.findNestedContainer(name, searchKind);
                    }
                }

                if (isExported && prevIsExported) {
                    return prevSymbol;
                }
                if (prevSymbol) {
                    var prevDecls = prevSymbol.getDeclarations();
                    var lastPrevDecl = prevDecls[prevDecls.length - 1];
                    var parentDecl = decl.getParentDecl();
                    var prevParentDecl = lastPrevDecl && lastPrevDecl.getParentDecl();
                    if (parentDecl !== prevParentDecl) {
                        return null;
                    }

                    return prevSymbol;
                }
            } else {
                var parentDecl = decl.getParentDecl();
                if (parentDecl && parentDecl.kind === 1 /* Script */) {
                    return this.semanticInfoChain.findTopLevelSymbol(name, searchKind, decl);
                } else {
                    var prevDecls = parentDecl && parentDecl.searchChildDecls(name, searchKind);
                    return prevDecls[0] && prevDecls[0].getSymbol();
                }
            }

            return null;
        };

        PullSymbolBinder.prototype.checkThatExportsMatch = function (decl, prevSymbol, reportError) {
            if (typeof reportError === "undefined") { reportError = true; }
            var isExported = (decl.flags & 1 /* Exported */) !== 0;
            var prevDecls = prevSymbol.getDeclarations();
            var prevIsExported = (prevDecls[prevDecls.length - 1].flags & 1 /* Exported */) !== 0;
            if ((isExported !== prevIsExported) && !prevSymbol.isSignature() && (decl.kind & 7340032 /* SomeSignature */) === 0) {
                if (reportError) {
                    var ast = this.semanticInfoChain.getASTForDecl(decl);
                    this.semanticInfoChain.addDiagnosticFromAST(ast, TypeScript.DiagnosticCode.All_declarations_of_merged_declaration_0_must_be_exported_or_not_exported, [decl.getDisplayName()]);
                }
                return false;
            }

            return true;
        };

        PullSymbolBinder.prototype.getIndexForInsertingSignatureAtEndOfEnclosingDeclInSignatureList = function (signature, currentSignatures) {
            var signatureDecl = signature.getDeclarations()[0];
            TypeScript.Debug.assert(signatureDecl);
            var enclosingDecl = signatureDecl.getParentDecl();
            var indexToInsert = TypeScript.ArrayUtilities.indexOf(currentSignatures, function (someSignature) {
                return someSignature.getDeclarations()[0].getParentDecl() !== enclosingDecl;
            });
            return indexToInsert < 0 ? currentSignatures.length : indexToInsert;
        };

        PullSymbolBinder.prototype.bindEnumDeclarationToPullSymbol = function (enumContainerDecl) {
            var enumName = enumContainerDecl.name;

            var enumContainerSymbol = null;
            var enumInstanceSymbol = null;
            var moduleInstanceTypeSymbol = null;

            var enumInstanceDecl = enumContainerDecl.getValueDecl();

            var enumDeclKind = enumContainerDecl.kind;

            var parent = this.getParent(enumContainerDecl);
            var parentInstanceSymbol = this.getParent(enumContainerDecl, true);
            var parentDecl = enumContainerDecl.getParentDecl();
            var enumAST = this.semanticInfoChain.getASTForDecl(enumContainerDecl);

            var isExported = enumContainerDecl.flags & 1 /* Exported */;

            var createdNewSymbol = false;

            enumContainerSymbol = this.getExistingSymbol(enumContainerDecl, 64 /* Enum */, parent);

            if (enumContainerSymbol) {
                if (enumContainerSymbol.kind !== enumDeclKind) {
                    this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(enumAST.identifier, enumContainerDecl.getDisplayName(), enumContainerSymbol.getDeclarations()[0].ast());
                    enumContainerSymbol = null;
                } else if (!this.checkThatExportsMatch(enumContainerDecl, enumContainerSymbol)) {
                    enumContainerSymbol = null;
                }
            }

            if (enumContainerSymbol) {
                enumInstanceSymbol = enumContainerSymbol.getInstanceSymbol();
            } else {
                enumContainerSymbol = new TypeScript.PullContainerSymbol(enumName, enumDeclKind);
                createdNewSymbol = true;

                if (!parent) {
                    this.semanticInfoChain.cacheGlobalSymbol(enumContainerSymbol, 64 /* Enum */);
                }
            }

            enumContainerSymbol.addDeclaration(enumContainerDecl);
            enumContainerDecl.setSymbol(enumContainerSymbol);

            this.semanticInfoChain.setSymbolForAST(enumAST.identifier, enumContainerSymbol);
            this.semanticInfoChain.setSymbolForAST(enumAST, enumContainerSymbol);

            if (!enumInstanceSymbol) {
                var variableSymbol = null;
                if (parentInstanceSymbol) {
                    if (isExported) {
                        variableSymbol = parentInstanceSymbol.findMember(enumName, false);

                        if (!variableSymbol) {
                            variableSymbol = parentInstanceSymbol.findContainedNonMember(enumName);
                        }
                    } else {
                        variableSymbol = parentInstanceSymbol.findContainedNonMember(enumName);

                        if (!variableSymbol) {
                            variableSymbol = parentInstanceSymbol.findMember(enumName, false);
                        }
                    }

                    if (variableSymbol) {
                        var declarations = variableSymbol.getDeclarations();

                        if (declarations.length) {
                            var variableSymbolParentDecl = declarations[0].getParentDecl();

                            if (parentDecl !== variableSymbolParentDecl) {
                                variableSymbol = null;
                            }
                        }
                    }
                } else if (!(enumContainerDecl.flags & 1 /* Exported */)) {
                    var siblingDecls = parentDecl.getChildDecls();
                    var augmentedDecl = null;

                    for (var i = 0; i < siblingDecls.length; i++) {
                        if (siblingDecls[i] === enumContainerDecl) {
                            break;
                        }

                        if ((siblingDecls[i].name === enumName) && (siblingDecls[i].kind & 68147712 /* SomeValue */)) {
                            augmentedDecl = siblingDecls[i];
                            break;
                        }
                    }

                    if (augmentedDecl) {
                        variableSymbol = augmentedDecl.getSymbol();

                        if (variableSymbol) {
                            if (variableSymbol.isContainer()) {
                                variableSymbol = variableSymbol.getInstanceSymbol();
                            } else if (variableSymbol && variableSymbol.isType()) {
                                variableSymbol = variableSymbol.getConstructorMethod();
                            }
                        }
                    }
                }

                if (variableSymbol) {
                    enumInstanceSymbol = variableSymbol;
                    moduleInstanceTypeSymbol = variableSymbol.type;
                } else {
                    enumInstanceSymbol = new TypeScript.PullSymbol(enumName, 512 /* Variable */);
                }

                enumContainerSymbol.setInstanceSymbol(enumInstanceSymbol);

                if (!moduleInstanceTypeSymbol) {
                    moduleInstanceTypeSymbol = new TypeScript.PullTypeSymbol("", 8388608 /* ObjectType */);
                    enumInstanceSymbol.type = moduleInstanceTypeSymbol;
                }

                moduleInstanceTypeSymbol.addDeclaration(enumContainerDecl);

                if (!moduleInstanceTypeSymbol.getAssociatedContainerType()) {
                    moduleInstanceTypeSymbol.setAssociatedContainerType(enumContainerSymbol);
                }
            }

            if (createdNewSymbol && parent) {
                if (enumContainerDecl.flags & 1 /* Exported */) {
                    parent.addEnclosedMemberType(enumContainerSymbol);
                } else {
                    parent.addEnclosedNonMemberType(enumContainerSymbol);
                }
            }

            if (createdNewSymbol) {
                this.bindEnumIndexerDeclsToPullSymbols(enumContainerSymbol);
            }
            var valueDecl = enumContainerDecl.getValueDecl();

            if (valueDecl) {
                valueDecl.ensureSymbolIsBound();
            }
        };

        PullSymbolBinder.prototype.bindEnumIndexerDeclsToPullSymbols = function (enumContainerSymbol) {
            var enumContainerInstanceTypeSymbol = enumContainerSymbol.getInstanceSymbol().type;

            var syntheticIndexerParameterSymbol = new TypeScript.PullSymbol("x", 2048 /* Parameter */);
            syntheticIndexerParameterSymbol.type = this.semanticInfoChain.numberTypeSymbol;
            syntheticIndexerParameterSymbol.setResolved();
            syntheticIndexerParameterSymbol.setIsSynthesized();

            var syntheticIndexerSignatureSymbol = new TypeScript.PullSignatureSymbol(4194304 /* IndexSignature */);
            syntheticIndexerSignatureSymbol.addParameter(syntheticIndexerParameterSymbol);
            syntheticIndexerSignatureSymbol.returnType = this.semanticInfoChain.stringTypeSymbol;
            syntheticIndexerSignatureSymbol.setResolved();
            syntheticIndexerSignatureSymbol.setIsSynthesized();

            enumContainerInstanceTypeSymbol.addIndexSignature(syntheticIndexerSignatureSymbol);
        };

        PullSymbolBinder.prototype.findExistingVariableSymbolForModuleValueDecl = function (decl) {
            var isExported = TypeScript.hasFlag(decl.flags, 1 /* Exported */);
            var modName = decl.name;
            var parentInstanceSymbol = this.getParent(decl, true);
            var parentDecl = decl.getParentDecl();

            var variableSymbol = null;

            if (parentInstanceSymbol) {
                if (isExported) {
                    variableSymbol = parentInstanceSymbol.findMember(modName, false);

                    if (!variableSymbol) {
                        variableSymbol = parentInstanceSymbol.findContainedNonMember(modName);
                    }
                } else {
                    variableSymbol = parentInstanceSymbol.findContainedNonMember(modName);

                    if (!variableSymbol) {
                        variableSymbol = parentInstanceSymbol.findMember(modName, false);
                    }
                }

                if (variableSymbol) {
                    var declarations = variableSymbol.getDeclarations();

                    if (declarations.length) {
                        var variableSymbolParentDecl = declarations[0].getParentDecl();
                        var isExportedOrHasTheSameParent = isExported || (parentDecl === variableSymbolParentDecl);

                        var canReuseVariableSymbol = isExportedOrHasTheSameParent && this.checkThatExportsMatch(decl, variableSymbol, false);

                        if (!canReuseVariableSymbol) {
                            variableSymbol = null;
                        }
                    }
                }
            } else if (!isExported) {
                var siblingDecls = parentDecl.getChildDecls();

                for (var i = 0; i < siblingDecls.length; i++) {
                    var sibling = siblingDecls[i];

                    var siblingIsSomeValue = TypeScript.hasFlag(sibling.kind, 68147712 /* SomeValue */);
                    var siblingIsFunctionOrHasImplictVarFlag = TypeScript.hasFlag(sibling.kind, 1032192 /* SomeFunction */) || TypeScript.hasFlag(sibling.flags, 118784 /* ImplicitVariable */);

                    var isSiblingAnAugmentableVariable = sibling !== decl && sibling !== decl.getValueDecl() && sibling.name === modName && siblingIsSomeValue && siblingIsFunctionOrHasImplictVarFlag;

                    if (isSiblingAnAugmentableVariable) {
                        if (sibling.hasSymbol()) {
                            variableSymbol = sibling.getSymbol();
                            if (variableSymbol.isContainer()) {
                                variableSymbol = variableSymbol.getInstanceSymbol();
                            } else if (variableSymbol && variableSymbol.isType()) {
                                variableSymbol = variableSymbol.getConstructorMethod();
                            }

                            break;
                        }
                    }
                }
            }
            return variableSymbol;
        };

        PullSymbolBinder.prototype.bindModuleDeclarationToPullSymbol = function (moduleContainerDecl) {
            var modName = moduleContainerDecl.name;

            var moduleContainerTypeSymbol = null;
            var moduleKind = moduleContainerDecl.kind;

            var parent = this.getParent(moduleContainerDecl);
            var parentInstanceSymbol = this.getParent(moduleContainerDecl, true);
            var parentDecl = moduleContainerDecl.getParentDecl();
            var moduleNameAST = this.semanticInfoChain.getASTForDecl(moduleContainerDecl);
            var moduleDeclAST = TypeScript.ASTHelpers.getEnclosingModuleDeclaration(moduleNameAST);
            if (!moduleDeclAST) {
                TypeScript.Debug.assert(moduleKind === 32 /* DynamicModule */);
                TypeScript.Debug.assert(moduleNameAST.kind() === 120 /* SourceUnit */);

                moduleDeclAST = moduleNameAST;
            }

            var isExported = TypeScript.hasFlag(moduleContainerDecl.flags, 1 /* Exported */);
            var searchKind = 164 /* SomeContainer */;
            var isInitializedModule = (moduleContainerDecl.flags & 102400 /* SomeInitializedModule */) !== 0;

            if (parent && moduleKind === 32 /* DynamicModule */) {
                this.semanticInfoChain.addDiagnosticFromAST(moduleNameAST, TypeScript.DiagnosticCode.Ambient_external_module_declaration_must_be_defined_in_global_context, null);
            }

            var createdNewSymbol = false;

            moduleContainerTypeSymbol = this.getExistingSymbol(moduleContainerDecl, searchKind, parent);

            if (moduleContainerTypeSymbol) {
                if (moduleContainerTypeSymbol.kind !== moduleKind) {
                    if (isInitializedModule) {
                        this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(moduleNameAST, moduleContainerDecl.getDisplayName(), moduleContainerTypeSymbol.getDeclarations()[0].ast());
                    }

                    moduleContainerTypeSymbol = null;
                } else if (moduleKind === 32 /* DynamicModule */) {
                    this.semanticInfoChain.addDiagnosticFromAST(moduleNameAST, TypeScript.DiagnosticCode.Ambient_external_module_declaration_cannot_be_reopened);
                } else if (!this.checkThatExportsMatch(moduleContainerDecl, moduleContainerTypeSymbol)) {
                    moduleContainerTypeSymbol = null;
                }
            }

            if (!moduleContainerTypeSymbol) {
                moduleContainerTypeSymbol = new TypeScript.PullContainerSymbol(modName, moduleKind);
                createdNewSymbol = true;

                if (!parent) {
                    this.semanticInfoChain.cacheGlobalSymbol(moduleContainerTypeSymbol, searchKind);
                }
            }

            moduleContainerTypeSymbol.addDeclaration(moduleContainerDecl);
            moduleContainerDecl.setSymbol(moduleContainerTypeSymbol);

            this.semanticInfoChain.setSymbolForAST(moduleNameAST, moduleContainerTypeSymbol);
            this.semanticInfoChain.setSymbolForAST(moduleDeclAST, moduleContainerTypeSymbol);

            var currentModuleValueDecl = moduleContainerDecl.getValueDecl();

            var moduleDeclarations = moduleContainerTypeSymbol.getDeclarations();

            if (createdNewSymbol) {
                if (parent) {
                    if (moduleContainerDecl.flags & 1 /* Exported */) {
                        parent.addEnclosedMemberContainer(moduleContainerTypeSymbol);
                    } else {
                        parent.addEnclosedNonMemberContainer(moduleContainerTypeSymbol);
                    }
                }
            }

            if (currentModuleValueDecl) {
                currentModuleValueDecl.ensureSymbolIsBound();

                var instanceSymbol = null;
                var instanceTypeSymbol = null;
                if (currentModuleValueDecl.hasSymbol()) {
                    instanceSymbol = currentModuleValueDecl.getSymbol();
                } else {
                    instanceSymbol = new TypeScript.PullSymbol(modName, 512 /* Variable */);
                    currentModuleValueDecl.setSymbol(instanceSymbol);
                    if (!instanceSymbol.hasDeclaration(currentModuleValueDecl)) {
                        instanceSymbol.addDeclaration(currentModuleValueDecl);
                    }
                }

                if (!instanceSymbol.type) {
                    instanceSymbol.type = new TypeScript.PullTypeSymbol("", 8388608 /* ObjectType */);
                }

                moduleContainerTypeSymbol.setInstanceSymbol(instanceSymbol);

                if (!instanceSymbol.type.getAssociatedContainerType()) {
                    instanceSymbol.type.setAssociatedContainerType(moduleContainerTypeSymbol);
                }
            }
        };

        PullSymbolBinder.prototype.bindImportDeclaration = function (importDeclaration) {
            var declFlags = importDeclaration.flags;
            var declKind = importDeclaration.kind;
            var importDeclAST = this.semanticInfoChain.getASTForDecl(importDeclaration);

            var isExported = false;
            var importSymbol = null;
            var declName = importDeclaration.name;
            var parentHadSymbol = false;
            var parent = this.getParent(importDeclaration);

            importSymbol = this.getExistingSymbol(importDeclaration, 164 /* SomeContainer */, parent);

            if (importSymbol) {
                parentHadSymbol = true;
            }

            if (importSymbol) {
                this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(importDeclAST, importDeclaration.getDisplayName(), importSymbol.getDeclarations()[0].ast());
                importSymbol = null;
            }

            if (!importSymbol) {
                importSymbol = new TypeScript.PullTypeAliasSymbol(declName);

                if (!parent) {
                    this.semanticInfoChain.cacheGlobalSymbol(importSymbol, 164 /* SomeContainer */);
                }
            }

            importSymbol.addDeclaration(importDeclaration);
            importDeclaration.setSymbol(importSymbol);

            this.semanticInfoChain.setSymbolForAST(importDeclAST, importSymbol);

            if (parent && !parentHadSymbol) {
                if (declFlags & 1 /* Exported */) {
                    parent.addEnclosedMemberContainer(importSymbol);
                } else {
                    parent.addEnclosedNonMemberContainer(importSymbol);
                }
            }
        };

        PullSymbolBinder.prototype.ensurePriorDeclarationsAreBound = function (container, currentDecl) {
            if (!container) {
                return;
            }

            var parentDecls = container.getDeclarations();
            for (var i = 0; i < parentDecls.length; ++i) {
                var parentDecl = parentDecls[i];
                var childDecls = parentDecl.getChildDecls();
                for (var j = 0; j < childDecls.length; ++j) {
                    var childDecl = childDecls[j];
                    if (childDecl === currentDecl) {
                        return;
                    }

                    if (childDecl.name === currentDecl.name) {
                        childDecl.ensureSymbolIsBound();
                    }
                }
            }
        };

        PullSymbolBinder.prototype.bindClassDeclarationToPullSymbol = function (classDecl) {
            var className = classDecl.name;
            var classSymbol = null;

            var constructorSymbol = null;
            var constructorTypeSymbol = null;

            var classAST = this.semanticInfoChain.getASTForDecl(classDecl);

            var parent = this.getParent(classDecl);

            this.ensurePriorDeclarationsAreBound(parent, classDecl);

            var parentDecl = classDecl.getParentDecl();
            var isExported = classDecl.flags & 1 /* Exported */;
            var isGeneric = false;

            classSymbol = this.getExistingSymbol(classDecl, 58728795 /* SomeType */, parent);

            if (classSymbol && classSymbol.kind === 16 /* Interface */) {
                this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(classAST.identifier, classDecl.getDisplayName(), classSymbol.getDeclarations()[0].ast());
                classSymbol = null;
            }

            classSymbol = new TypeScript.PullTypeSymbol(className, 8 /* Class */);

            if (!parent) {
                this.semanticInfoChain.cacheGlobalSymbol(classSymbol, 8 /* Class */);
            }

            classSymbol.addDeclaration(classDecl);

            classDecl.setSymbol(classSymbol);

            this.semanticInfoChain.setSymbolForAST(classAST.identifier, classSymbol);
            this.semanticInfoChain.setSymbolForAST(classAST, classSymbol);

            if (parent) {
                if (classDecl.flags & 1 /* Exported */) {
                    parent.addEnclosedMemberType(classSymbol);
                } else {
                    parent.addEnclosedNonMemberType(classSymbol);
                }
            }

            var typeParameterDecls = classDecl.getTypeParameters();

            for (var i = 0; i < typeParameterDecls.length; i++) {
                var typeParameterSymbol = classSymbol.findTypeParameter(typeParameterDecls[i].name);

                if (typeParameterSymbol) {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameterSymbol.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameterSymbol.getName()]);
                }

                typeParameterSymbol = new TypeScript.PullTypeParameterSymbol(typeParameterDecls[i].name);

                classSymbol.addTypeParameter(typeParameterSymbol);
                typeParameterSymbol.addDeclaration(typeParameterDecls[i]);
                typeParameterDecls[i].setSymbol(typeParameterSymbol);
            }

            constructorSymbol = classSymbol.getConstructorMethod();
            constructorTypeSymbol = constructorSymbol ? constructorSymbol.type : null;

            if (!constructorSymbol) {
                var siblingValueDecls = null;
                if (parentDecl) {
                    siblingValueDecls = parentDecl.searchChildDecls(className, 68147712 /* SomeValue */);

                    if (siblingValueDecls && siblingValueDecls[0] && siblingValueDecls[0].hasSymbol()) {
                        constructorSymbol = siblingValueDecls[0].getSymbol();
                    }
                }

                if (constructorSymbol) {
                    constructorTypeSymbol = constructorSymbol.type;
                } else {
                    constructorSymbol = new TypeScript.PullSymbol(className, 32768 /* ConstructorMethod */);
                    constructorTypeSymbol = new TypeScript.PullTypeSymbol("", 33554432 /* ConstructorType */);
                    constructorSymbol.setIsSynthesized();
                    constructorSymbol.type = constructorTypeSymbol;
                }

                classSymbol.setConstructorMethod(constructorSymbol);
                classSymbol.setHasDefaultConstructor();
            }

            if (constructorSymbol.getIsSynthesized()) {
                constructorSymbol.addDeclaration(classDecl.getValueDecl());
                constructorTypeSymbol.addDeclaration(classDecl);
            } else {
                classSymbol.setHasDefaultConstructor(false);
            }

            constructorTypeSymbol.setAssociatedContainerType(classSymbol);

            var valueDecl = classDecl.getValueDecl();

            if (valueDecl) {
                valueDecl.ensureSymbolIsBound();
            }

            this.bindStaticPrototypePropertyOfClass(classAST, classSymbol, constructorTypeSymbol);
        };

        PullSymbolBinder.prototype.bindInterfaceDeclarationToPullSymbol = function (interfaceDecl) {
            var interfaceName = interfaceDecl.name;
            var interfaceSymbol = null;

            var interfaceAST = this.semanticInfoChain.getASTForDecl(interfaceDecl);
            var createdNewSymbol = false;
            var parent = this.getParent(interfaceDecl);

            var acceptableSharedKind = 16 /* Interface */;

            interfaceSymbol = this.getExistingSymbol(interfaceDecl, 58728795 /* SomeType */, parent);

            if (interfaceSymbol) {
                if (!(interfaceSymbol.kind & acceptableSharedKind)) {
                    this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(interfaceAST.identifier, interfaceDecl.getDisplayName(), interfaceSymbol.getDeclarations()[0].ast());
                    interfaceSymbol = null;
                } else if (!this.checkThatExportsMatch(interfaceDecl, interfaceSymbol)) {
                    interfaceSymbol = null;
                }
            }

            if (!interfaceSymbol) {
                interfaceSymbol = new TypeScript.PullTypeSymbol(interfaceName, 16 /* Interface */);
                createdNewSymbol = true;

                if (!parent) {
                    this.semanticInfoChain.cacheGlobalSymbol(interfaceSymbol, acceptableSharedKind);
                }
            }

            interfaceSymbol.addDeclaration(interfaceDecl);
            interfaceDecl.setSymbol(interfaceSymbol);

            if (createdNewSymbol) {
                if (parent) {
                    if (interfaceDecl.flags & 1 /* Exported */) {
                        parent.addEnclosedMemberType(interfaceSymbol);
                    } else {
                        parent.addEnclosedNonMemberType(interfaceSymbol);
                    }
                }
            }

            var typeParameters = interfaceDecl.getTypeParameters();
            var typeParameter;
            var typeParameterDecls = null;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = interfaceSymbol.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    interfaceSymbol.addTypeParameter(typeParameter);
                } else {
                    typeParameterDecls = typeParameter.getDeclarations();

                    for (var j = 0; j < typeParameterDecls.length; j++) {
                        var typeParameterDeclParent = typeParameterDecls[j].getParentDecl();

                        if (typeParameterDeclParent && typeParameterDeclParent === interfaceDecl) {
                            var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameterDecls[0]);
                            this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.getName()]);

                            break;
                        }
                    }
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }
        };

        PullSymbolBinder.prototype.bindObjectTypeDeclarationToPullSymbol = function (objectDecl) {
            var objectSymbolAST = this.semanticInfoChain.getASTForDecl(objectDecl);

            var objectSymbol = new TypeScript.PullTypeSymbol("", 8388608 /* ObjectType */);

            objectSymbol.addDeclaration(objectDecl);
            objectDecl.setSymbol(objectSymbol);

            this.semanticInfoChain.setSymbolForAST(objectSymbolAST, objectSymbol);

            var childDecls = objectDecl.getChildDecls();

            for (var i = 0; i < childDecls.length; i++) {
                this.bindDeclToPullSymbol(childDecls[i]);
            }
        };

        PullSymbolBinder.prototype.bindConstructorTypeDeclarationToPullSymbol = function (constructorTypeDeclaration) {
            var declKind = constructorTypeDeclaration.kind;
            var declFlags = constructorTypeDeclaration.flags;
            var constructorTypeAST = this.semanticInfoChain.getASTForDecl(constructorTypeDeclaration);

            var constructorTypeSymbol = new TypeScript.PullTypeSymbol("", 33554432 /* ConstructorType */);

            constructorTypeDeclaration.setSymbol(constructorTypeSymbol);
            constructorTypeSymbol.addDeclaration(constructorTypeDeclaration);
            this.semanticInfoChain.setSymbolForAST(constructorTypeAST, constructorTypeSymbol);

            var signature = new TypeScript.PullSignatureSymbol(2097152 /* ConstructSignature */);

            var funcDecl = this.semanticInfoChain.getASTForDecl(constructorTypeDeclaration);
            if (TypeScript.lastParameterIsRest(funcDecl.parameterList)) {
                signature.hasVarArgs = true;
            }

            signature.addDeclaration(constructorTypeDeclaration);
            constructorTypeDeclaration.setSignatureSymbol(signature);

            this.bindParameterSymbols(funcDecl, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.parameterList), constructorTypeSymbol, signature);

            var typeParameters = constructorTypeDeclaration.getTypeParameters();
            var typeParameter;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = constructorTypeSymbol.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    signature.addTypeParameter(typeParameter);
                } else {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.name]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            constructorTypeSymbol.appendConstructSignature(signature);
        };

        PullSymbolBinder.prototype.bindVariableDeclarationToPullSymbol = function (variableDeclaration) {
            var declFlags = variableDeclaration.flags;
            var declKind = variableDeclaration.kind;
            var varDeclAST = this.semanticInfoChain.getASTForDecl(variableDeclaration);
            var nameAST = varDeclAST.kind() === 131 /* ClassDeclaration */ ? varDeclAST.identifier : varDeclAST.kind() === 225 /* VariableDeclarator */ ? varDeclAST.propertyName : varDeclAST.kind() === 132 /* EnumDeclaration */ ? varDeclAST.identifier : varDeclAST;

            var isExported = (declFlags & 1 /* Exported */) !== 0;

            var variableSymbol = null;

            var declName = variableDeclaration.name;

            var parentHadSymbol = false;

            var parent = this.getParent(variableDeclaration, true);

            var parentDecl = variableDeclaration.getParentDecl();

            var isImplicit = (declFlags & 118784 /* ImplicitVariable */) !== 0;
            var isModuleValue = (declFlags & (32768 /* InitializedModule */)) !== 0;
            var isEnumValue = (declFlags & 4096 /* Enum */) !== 0;
            var isClassConstructorVariable = (declFlags & 16384 /* ClassConstructorVariable */) !== 0;
            variableSymbol = this.getExistingSymbol(variableDeclaration, 68147712 /* SomeValue */, parent);

            if (!variableSymbol && isModuleValue) {
                variableSymbol = this.findExistingVariableSymbolForModuleValueDecl(variableDeclaration.getContainerDecl());
            }

            if (variableSymbol && !variableSymbol.isType()) {
                parentHadSymbol = true;
            }

            var decl;
            var decls;
            var ast;
            var members;

            if (variableSymbol) {
                var prevKind = variableSymbol.kind;
                var prevIsEnum = variableSymbol.anyDeclHasFlag(4096 /* Enum */);
                var prevIsClassConstructorVariable = variableSymbol.anyDeclHasFlag(16384 /* ClassConstructorVariable */);
                var prevIsModuleValue = variableSymbol.allDeclsHaveFlag(32768 /* InitializedModule */);
                var prevIsImplicit = variableSymbol.anyDeclHasFlag(118784 /* ImplicitVariable */);
                var prevIsFunction = TypeScript.ArrayUtilities.any(variableSymbol.getDeclarations(), function (decl) {
                    return decl.kind === 16384 /* Function */;
                });
                var prevIsAmbient = variableSymbol.allDeclsHaveFlag(8 /* Ambient */);
                var isAmbientOrPrevIsAmbient = prevIsAmbient || (variableDeclaration.flags & 8 /* Ambient */) !== 0;
                var prevDecl = variableSymbol.getDeclarations()[0];
                var prevParentDecl = prevDecl.getParentDecl();
                var bothAreGlobal = parentDecl && (parentDecl.kind === 1 /* Script */) && (prevParentDecl.kind === 1 /* Script */);
                var shareParent = bothAreGlobal || prevDecl.getParentDecl() === variableDeclaration.getParentDecl();
                var prevIsParam = shareParent && prevKind === 2048 /* Parameter */ && declKind == 512 /* Variable */;

                var acceptableRedeclaration = prevIsParam || (isImplicit && ((!isEnumValue && !isClassConstructorVariable && prevIsFunction) || ((isModuleValue || isEnumValue) && (prevIsModuleValue || prevIsEnum)) || (isClassConstructorVariable && prevIsModuleValue && isAmbientOrPrevIsAmbient) || (isModuleValue && prevIsClassConstructorVariable)));

                if (acceptableRedeclaration && (prevIsClassConstructorVariable || prevIsFunction) && !isAmbientOrPrevIsAmbient) {
                    if (prevDecl.fileName() !== variableDeclaration.fileName()) {
                        this.semanticInfoChain.addDiagnostic(TypeScript.PullHelpers.diagnosticFromDecl(variableDeclaration, TypeScript.DiagnosticCode.Module_0_cannot_merge_with_previous_declaration_of_1_in_a_different_file_2, [declName, declName, prevDecl.fileName()]));
                        variableSymbol.type = this.semanticInfoChain.getResolver().getNewErrorTypeSymbol(declName);
                    }
                }

                if (!acceptableRedeclaration || prevIsParam) {
                    if (!prevIsParam && (isImplicit || prevIsImplicit || TypeScript.hasFlag(prevKind, 1032192 /* SomeFunction */)) || !shareParent) {
                        this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(nameAST, variableDeclaration.getDisplayName(), variableSymbol.getDeclarations()[0].ast());
                        variableSymbol.type = this.semanticInfoChain.getResolver().getNewErrorTypeSymbol(declName);
                    } else {
                        this.checkThatExportsMatch(variableDeclaration, variableSymbol);
                        variableSymbol = null;
                        parentHadSymbol = false;
                    }
                }

                if (variableSymbol && !(variableSymbol.type && variableSymbol.type.isError()) && !this.checkThatExportsMatch(variableDeclaration, variableSymbol, !(isModuleValue && prevIsModuleValue))) {
                    variableSymbol.type = this.semanticInfoChain.getResolver().getNewErrorTypeSymbol(declName);
                }
            }

            if ((declFlags & 118784 /* ImplicitVariable */) === 0) {
                if (!variableSymbol) {
                    variableSymbol = new TypeScript.PullSymbol(declName, declKind);
                    if (!parent && parentDecl.kind === 1 /* Script */) {
                        this.semanticInfoChain.cacheGlobalSymbol(variableSymbol, declKind);
                    }
                }

                variableSymbol.addDeclaration(variableDeclaration);
                variableDeclaration.setSymbol(variableSymbol);

                this.semanticInfoChain.setSymbolForAST(nameAST, variableSymbol);
                this.semanticInfoChain.setSymbolForAST(varDeclAST, variableSymbol);
            } else if (!parentHadSymbol) {
                if (isClassConstructorVariable) {
                    var classTypeSymbol = variableSymbol;

                    if (parent) {
                        members = parent.getMembers();

                        for (var i = 0; i < members.length; i++) {
                            if ((members[i].name === declName) && (members[i].kind === 8 /* Class */)) {
                                classTypeSymbol = members[i];
                                break;
                            }
                        }
                    }

                    if (!classTypeSymbol) {
                        var containerDecl = variableDeclaration.getContainerDecl();
                        classTypeSymbol = containerDecl.getSymbol();
                        if (!classTypeSymbol) {
                            classTypeSymbol = this.semanticInfoChain.findTopLevelSymbol(declName, 58728795 /* SomeType */, variableDeclaration);
                        }
                    }

                    if (classTypeSymbol && (classTypeSymbol.kind !== 8 /* Class */)) {
                        classTypeSymbol = null;
                    }

                    if (classTypeSymbol && classTypeSymbol.isClass()) {
                        variableSymbol = classTypeSymbol.getConstructorMethod();
                        variableDeclaration.setSymbol(variableSymbol);

                        decls = classTypeSymbol.getDeclarations();

                        if (decls.length) {
                            decl = decls[decls.length - 1];
                            ast = this.semanticInfoChain.getASTForDecl(decl);
                        }
                    } else {
                        if (!variableSymbol) {
                            variableSymbol = new TypeScript.PullSymbol(declName, declKind);
                        }

                        variableSymbol.addDeclaration(variableDeclaration);
                        variableDeclaration.setSymbol(variableSymbol);

                        variableSymbol.type = this.semanticInfoChain.anyTypeSymbol;
                    }
                } else if (declFlags & 102400 /* SomeInitializedModule */) {
                    var moduleContainerTypeSymbol = null;
                    var moduleParent = this.getParent(variableDeclaration);

                    if (moduleParent) {
                        members = moduleParent.getMembers();

                        for (var i = 0; i < members.length; i++) {
                            if ((members[i].name === declName) && (members[i].isContainer())) {
                                moduleContainerTypeSymbol = members[i];
                                break;
                            }
                        }
                    }

                    if (!moduleContainerTypeSymbol) {
                        var containerDecl = variableDeclaration.getContainerDecl();
                        moduleContainerTypeSymbol = containerDecl.getSymbol();
                        if (!moduleContainerTypeSymbol) {
                            moduleContainerTypeSymbol = this.semanticInfoChain.findTopLevelSymbol(declName, 164 /* SomeContainer */, variableDeclaration);

                            if (!moduleContainerTypeSymbol) {
                                moduleContainerTypeSymbol = this.semanticInfoChain.findTopLevelSymbol(declName, 64 /* Enum */, variableDeclaration);
                            }
                        }
                    }

                    if (moduleContainerTypeSymbol && (!moduleContainerTypeSymbol.isContainer())) {
                        moduleContainerTypeSymbol = null;
                    }

                    if (moduleContainerTypeSymbol) {
                        variableSymbol = moduleContainerTypeSymbol.getInstanceSymbol();
                        if (!variableSymbol) {
                            variableSymbol = new TypeScript.PullSymbol(declName, declKind);
                            variableSymbol.type = new TypeScript.PullTypeSymbol("", 8388608 /* ObjectType */);
                        }

                        if (!variableSymbol.hasDeclaration(variableDeclaration)) {
                            variableSymbol.addDeclaration(variableDeclaration);
                        }
                        variableDeclaration.setSymbol(variableSymbol);
                    } else {
                        TypeScript.Debug.assert(false, "Attempted to bind invalid implicit variable symbol");
                    }
                }
            } else {
                if (!variableSymbol.hasDeclaration(variableDeclaration)) {
                    variableSymbol.addDeclaration(variableDeclaration);
                }
                variableDeclaration.setSymbol(variableSymbol);
            }

            var containerDecl = variableDeclaration.getContainerDecl();
            if (variableSymbol && variableSymbol.type && containerDecl && !variableSymbol.type.hasDeclaration(containerDecl)) {
                variableSymbol.type.addDeclaration(containerDecl);
            }

            if (parent && !parentHadSymbol) {
                if (declFlags & 1 /* Exported */) {
                    parent.addMember(variableSymbol);
                } else {
                    parent.addEnclosedNonMember(variableSymbol);
                }
            }
        };

        PullSymbolBinder.prototype.bindCatchVariableToPullSymbol = function (variableDeclaration) {
            var declFlags = variableDeclaration.flags;
            var declKind = variableDeclaration.kind;
            var identifier = this.semanticInfoChain.getASTForDecl(variableDeclaration);

            var declName = variableDeclaration.name;

            var variableSymbol = new TypeScript.PullSymbol(declName, declKind);

            variableSymbol.addDeclaration(variableDeclaration);
            variableDeclaration.setSymbol(variableSymbol);

            variableSymbol.type = this.semanticInfoChain.anyTypeSymbol;

            this.semanticInfoChain.setSymbolForAST(identifier, variableSymbol);
        };

        PullSymbolBinder.prototype.bindEnumMemberDeclarationToPullSymbol = function (propertyDeclaration) {
            var declFlags = propertyDeclaration.flags;
            var declKind = propertyDeclaration.kind;
            var propDeclAST = this.semanticInfoChain.getASTForDecl(propertyDeclaration);

            var declName = propertyDeclaration.name;

            var parentHadSymbol = false;

            var parent = this.getParent(propertyDeclaration, true);

            var propertySymbol = parent.findMember(declName, false);

            if (propertySymbol) {
                this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(propDeclAST.propertyName, propertyDeclaration.getDisplayName(), propertySymbol.getDeclarations()[0].ast());
            }

            if (propertySymbol) {
                parentHadSymbol = true;
            }

            if (!parentHadSymbol) {
                propertySymbol = new TypeScript.PullSymbol(declName, declKind);
            }

            propertySymbol.addDeclaration(propertyDeclaration);
            propertyDeclaration.setSymbol(propertySymbol);

            this.semanticInfoChain.setSymbolForAST(propDeclAST.propertyName, propertySymbol);
            this.semanticInfoChain.setSymbolForAST(propDeclAST, propertySymbol);

            if (parent && !parentHadSymbol) {
                parent.addMember(propertySymbol);
            }
        };

        PullSymbolBinder.prototype.bindPropertyDeclarationToPullSymbol = function (propertyDeclaration) {
            var declFlags = propertyDeclaration.flags;
            var declKind = propertyDeclaration.kind;

            var ast = this.semanticInfoChain.getASTForDecl(propertyDeclaration);
            var astName = ast.kind() === 136 /* MemberVariableDeclaration */ ? ast.variableDeclarator.propertyName : ast.kind() === 141 /* PropertySignature */ ? ast.propertyName : ast.kind() === 242 /* Parameter */ ? ast.identifier : ast.propertyName;

            var isStatic = false;
            var isOptional = false;

            var propertySymbol = null;

            if (TypeScript.hasFlag(declFlags, 16 /* Static */)) {
                isStatic = true;
            }

            if (TypeScript.hasFlag(declFlags, 128 /* Optional */)) {
                isOptional = true;
            }

            var declName = propertyDeclaration.name;

            var parentHadSymbol = false;

            var parent = this.getParent(propertyDeclaration, true);

            if (parent.isClass() && isStatic) {
                parent = parent.getConstructorMethod().type;
            }

            propertySymbol = parent.findMember(declName, false);

            if (propertySymbol) {
                this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(astName, propertyDeclaration.getDisplayName(), propertySymbol.getDeclarations()[0].ast());
            }

            if (propertySymbol) {
                parentHadSymbol = true;
            }

            var classTypeSymbol;

            if (!parentHadSymbol) {
                propertySymbol = new TypeScript.PullSymbol(declName, declKind);
            }

            propertySymbol.addDeclaration(propertyDeclaration);
            propertyDeclaration.setSymbol(propertySymbol);

            this.semanticInfoChain.setSymbolForAST(astName, propertySymbol);
            this.semanticInfoChain.setSymbolForAST(ast, propertySymbol);

            if (isOptional) {
                propertySymbol.isOptional = true;
            }

            if (parent && !parentHadSymbol) {
                parent.addMember(propertySymbol);
            }
        };

        PullSymbolBinder.prototype.bindParameterSymbols = function (functionDeclaration, parameterList, funcType, signatureSymbol) {
            var parameters = [];
            var params = TypeScript.createIntrinsicsObject();
            var funcDecl = this.semanticInfoChain.getDeclForAST(functionDeclaration);

            if (parameterList) {
                for (var i = 0, n = parameterList.length; i < n; i++) {
                    var argDecl = parameterList.astAt(i);
                    var id = parameterList.identifierAt(i);
                    var decl = this.semanticInfoChain.getDeclForAST(argDecl);
                    var isProperty = TypeScript.hasFlag(decl.flags, 8388608 /* PropertyParameter */);
                    var parameterSymbol = new TypeScript.PullSymbol(id.valueText(), 2048 /* Parameter */);

                    if ((i === (n - 1)) && parameterList.lastParameterIsRest()) {
                        parameterSymbol.isVarArg = true;
                    }

                    if (params[id.valueText()]) {
                        this.semanticInfoChain.addDiagnosticFromAST(argDecl, TypeScript.DiagnosticCode.Duplicate_identifier_0, [id.text()]);
                    } else {
                        params[id.valueText()] = true;
                    }

                    if (decl) {
                        var isParameterOptional = false;

                        if (isProperty) {
                            decl.ensureSymbolIsBound();
                            var valDecl = decl.getValueDecl();

                            if (valDecl) {
                                isParameterOptional = TypeScript.hasFlag(valDecl.flags, 128 /* Optional */);

                                valDecl.setSymbol(parameterSymbol);
                                parameterSymbol.addDeclaration(valDecl);
                            }
                        } else {
                            isParameterOptional = TypeScript.hasFlag(decl.flags, 128 /* Optional */);

                            parameterSymbol.addDeclaration(decl);
                            decl.setSymbol(parameterSymbol);
                        }

                        parameterSymbol.isOptional = isParameterOptional;
                    }

                    signatureSymbol.addParameter(parameterSymbol, parameterSymbol.isOptional);

                    if (signatureSymbol.isDefinition()) {
                        funcType.addEnclosedNonMember(parameterSymbol);
                    }
                }
            }
        };

        PullSymbolBinder.prototype.bindFunctionDeclarationToPullSymbol = function (functionDeclaration) {
            var declKind = functionDeclaration.kind;
            var declFlags = functionDeclaration.flags;
            var funcDeclAST = this.semanticInfoChain.getASTForDecl(functionDeclaration);

            var isExported = (declFlags & 1 /* Exported */) !== 0;

            var funcName = functionDeclaration.name;

            var isSignature = (declFlags & 2048 /* Signature */) !== 0;

            var parent = this.getParent(functionDeclaration, true);

            var parentDecl = functionDeclaration.getParentDecl();
            var parentHadSymbol = false;

            var functionSymbol = null;
            var functionTypeSymbol = null;

            functionSymbol = this.getExistingSymbol(functionDeclaration, 68147712 /* SomeValue */, parent);

            if (functionSymbol) {
                var acceptableRedeclaration;

                if (functionSymbol.kind === 16384 /* Function */) {
                    acceptableRedeclaration = isSignature || functionSymbol.allDeclsHaveFlag(2048 /* Signature */);
                } else {
                    var isCurrentDeclAmbient = TypeScript.hasFlag(functionDeclaration.flags, 8 /* Ambient */);
                    acceptableRedeclaration = TypeScript.ArrayUtilities.all(functionSymbol.getDeclarations(), function (decl) {
                        var isInitializedModuleOrAmbientDecl = TypeScript.hasFlag(decl.flags, 32768 /* InitializedModule */) && (isCurrentDeclAmbient || TypeScript.hasFlag(decl.flags, 8 /* Ambient */));
                        var isSignature = TypeScript.hasFlag(decl.flags, 2048 /* Signature */);
                        return isInitializedModuleOrAmbientDecl || isSignature;
                    });
                }

                if (!acceptableRedeclaration) {
                    this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(funcDeclAST.identifier, functionDeclaration.getDisplayName(), functionSymbol.getDeclarations()[0].ast());
                    functionSymbol.type = this.semanticInfoChain.getResolver().getNewErrorTypeSymbol(funcName);
                }
            }

            if (functionSymbol) {
                functionTypeSymbol = functionSymbol.type;
                parentHadSymbol = true;
            }

            if (!functionSymbol) {
                functionSymbol = new TypeScript.PullSymbol(funcName, 16384 /* Function */);
            }

            if (!functionTypeSymbol) {
                functionTypeSymbol = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);
                functionSymbol.type = functionTypeSymbol;
                functionTypeSymbol.setFunctionSymbol(functionSymbol);
            }

            functionDeclaration.setSymbol(functionSymbol);
            functionSymbol.addDeclaration(functionDeclaration);
            functionTypeSymbol.addDeclaration(functionDeclaration);

            this.semanticInfoChain.setSymbolForAST(funcDeclAST.identifier, functionSymbol);
            this.semanticInfoChain.setSymbolForAST(funcDeclAST, functionSymbol);

            if (parent && !parentHadSymbol) {
                if (isExported) {
                    parent.addMember(functionSymbol);
                } else {
                    parent.addEnclosedNonMember(functionSymbol);
                }
            }

            var signature = new TypeScript.PullSignatureSymbol(1048576 /* CallSignature */, !isSignature);

            signature.addDeclaration(functionDeclaration);
            functionDeclaration.setSignatureSymbol(signature);

            if (TypeScript.lastParameterIsRest(funcDeclAST.callSignature.parameterList)) {
                signature.hasVarArgs = true;
            }

            var funcDecl = this.semanticInfoChain.getASTForDecl(functionDeclaration);
            this.bindParameterSymbols(funcDecl, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.callSignature.parameterList), functionTypeSymbol, signature);

            var typeParameters = functionDeclaration.getTypeParameters();
            var typeParameter;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = signature.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    signature.addTypeParameter(typeParameter);
                } else {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.name]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            functionTypeSymbol.appendCallSignature(signature);
        };

        PullSymbolBinder.prototype.bindFunctionExpressionToPullSymbol = function (functionExpressionDeclaration) {
            var declKind = functionExpressionDeclaration.kind;
            var declFlags = functionExpressionDeclaration.flags;
            var ast = this.semanticInfoChain.getASTForDecl(functionExpressionDeclaration);

            var parameters = ast.kind() === 219 /* SimpleArrowFunctionExpression */ ? TypeScript.ASTHelpers.parametersFromIdentifier(ast.identifier) : TypeScript.ASTHelpers.parametersFromParameterList(TypeScript.ASTHelpers.getParameterList(ast));
            var funcExpAST = ast;

            var functionName = declKind === 131072 /* FunctionExpression */ ? functionExpressionDeclaration.getFunctionExpressionName() : functionExpressionDeclaration.name;
            var functionSymbol = new TypeScript.PullSymbol(functionName, declKind);
            var functionTypeSymbol = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);
            functionTypeSymbol.setFunctionSymbol(functionSymbol);

            functionSymbol.type = functionTypeSymbol;

            functionExpressionDeclaration.setSymbol(functionSymbol);
            functionSymbol.addDeclaration(functionExpressionDeclaration);
            functionTypeSymbol.addDeclaration(functionExpressionDeclaration);

            var name = funcExpAST.kind() === 222 /* FunctionExpression */ ? funcExpAST.identifier : funcExpAST.kind() === 241 /* FunctionPropertyAssignment */ ? funcExpAST.propertyName : null;
            if (name) {
                this.semanticInfoChain.setSymbolForAST(name, functionSymbol);
            }

            this.semanticInfoChain.setSymbolForAST(funcExpAST, functionSymbol);

            var signature = new TypeScript.PullSignatureSymbol(1048576 /* CallSignature */, true);

            if (parameters.lastParameterIsRest()) {
                signature.hasVarArgs = true;
            }

            var typeParameters = functionExpressionDeclaration.getTypeParameters();
            var typeParameter;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = signature.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    signature.addTypeParameter(typeParameter);
                } else {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.getName()]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            signature.addDeclaration(functionExpressionDeclaration);
            functionExpressionDeclaration.setSignatureSymbol(signature);

            this.bindParameterSymbols(funcExpAST, parameters, functionTypeSymbol, signature);

            functionTypeSymbol.appendCallSignature(signature);
        };

        PullSymbolBinder.prototype.bindFunctionTypeDeclarationToPullSymbol = function (functionTypeDeclaration) {
            var declKind = functionTypeDeclaration.kind;
            var declFlags = functionTypeDeclaration.flags;
            var funcTypeAST = this.semanticInfoChain.getASTForDecl(functionTypeDeclaration);

            var functionTypeSymbol = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);

            functionTypeDeclaration.setSymbol(functionTypeSymbol);
            functionTypeSymbol.addDeclaration(functionTypeDeclaration);
            this.semanticInfoChain.setSymbolForAST(funcTypeAST, functionTypeSymbol);

            var isSignature = (declFlags & 2048 /* Signature */) !== 0;
            var signature = new TypeScript.PullSignatureSymbol(1048576 /* CallSignature */, !isSignature);

            if (TypeScript.lastParameterIsRest(funcTypeAST.parameterList)) {
                signature.hasVarArgs = true;
            }

            var typeParameters = functionTypeDeclaration.getTypeParameters();
            var typeParameter;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = signature.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    signature.addTypeParameter(typeParameter);
                } else {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.name]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            signature.addDeclaration(functionTypeDeclaration);
            functionTypeDeclaration.setSignatureSymbol(signature);

            this.bindParameterSymbols(funcTypeAST, TypeScript.ASTHelpers.parametersFromParameterList(funcTypeAST.parameterList), functionTypeSymbol, signature);

            functionTypeSymbol.appendCallSignature(signature);
        };

        PullSymbolBinder.prototype.bindMethodDeclarationToPullSymbol = function (methodDeclaration) {
            var declKind = methodDeclaration.kind;
            var declFlags = methodDeclaration.flags;
            var methodAST = this.semanticInfoChain.getASTForDecl(methodDeclaration);

            var isPrivate = (declFlags & 2 /* Private */) !== 0;
            var isStatic = (declFlags & 16 /* Static */) !== 0;
            var isOptional = (declFlags & 128 /* Optional */) !== 0;

            var methodName = methodDeclaration.name;

            var isSignature = (declFlags & 2048 /* Signature */) !== 0;

            var parent = this.getParent(methodDeclaration, true);
            var parentHadSymbol = false;

            var methodSymbol = null;
            var methodTypeSymbol = null;

            if (parent.isClass() && isStatic) {
                parent = parent.getConstructorMethod().type;
            }

            methodSymbol = parent.findMember(methodName, false);

            if (methodSymbol && (methodSymbol.kind !== 65536 /* Method */ || (!isSignature && !methodSymbol.allDeclsHaveFlag(2048 /* Signature */)))) {
                this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(methodAST, methodDeclaration.getDisplayName(), methodSymbol.getDeclarations()[0].ast());
                methodSymbol = null;
            }

            if (methodSymbol) {
                methodTypeSymbol = methodSymbol.type;
                parentHadSymbol = true;
            }

            if (!methodSymbol) {
                methodSymbol = new TypeScript.PullSymbol(methodName, 65536 /* Method */);
            }

            if (!methodTypeSymbol) {
                methodTypeSymbol = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);
                methodSymbol.type = methodTypeSymbol;
                methodTypeSymbol.setFunctionSymbol(methodSymbol);
            }

            methodDeclaration.setSymbol(methodSymbol);
            methodSymbol.addDeclaration(methodDeclaration);
            methodTypeSymbol.addDeclaration(methodDeclaration);

            var nameAST = methodAST.kind() === 135 /* MemberFunctionDeclaration */ ? methodAST.propertyName : methodAST.propertyName;

            TypeScript.Debug.assert(nameAST);

            this.semanticInfoChain.setSymbolForAST(nameAST, methodSymbol);
            this.semanticInfoChain.setSymbolForAST(methodAST, methodSymbol);

            if (isOptional) {
                methodSymbol.isOptional = true;
            }

            if (!parentHadSymbol) {
                parent.addMember(methodSymbol);
            }

            var sigKind = 1048576 /* CallSignature */;

            var signature = new TypeScript.PullSignatureSymbol(sigKind, !isSignature);

            var parameterList = TypeScript.ASTHelpers.getParameterList(methodAST);
            if (TypeScript.lastParameterIsRest(parameterList)) {
                signature.hasVarArgs = true;
            }

            var typeParameters = methodDeclaration.getTypeParameters();
            var typeParameter;
            var typeParameterName;
            var typeParameterAST;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameterName = typeParameters[i].name;
                typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameters[i]);

                typeParameter = signature.findTypeParameter(typeParameterName);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameterName);
                    signature.addTypeParameter(typeParameter);
                } else {
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.getName()]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            signature.addDeclaration(methodDeclaration);
            methodDeclaration.setSignatureSymbol(signature);

            var funcDecl = this.semanticInfoChain.getASTForDecl(methodDeclaration);
            this.bindParameterSymbols(funcDecl, TypeScript.ASTHelpers.parametersFromParameterList(TypeScript.ASTHelpers.getParameterList(funcDecl)), methodTypeSymbol, signature);

            var signatureIndex = this.getIndexForInsertingSignatureAtEndOfEnclosingDeclInSignatureList(signature, methodTypeSymbol.getOwnCallSignatures());
            methodTypeSymbol.insertCallSignatureAtIndex(signature, signatureIndex);
        };

        PullSymbolBinder.prototype.bindStaticPrototypePropertyOfClass = function (classAST, classTypeSymbol, constructorTypeSymbol) {
            var prototypeStr = "prototype";

            var prototypeSymbol = constructorTypeSymbol.findMember(prototypeStr, false);
            if (prototypeSymbol && !prototypeSymbol.getIsSynthesized()) {
                this.semanticInfoChain.addDiagnostic(TypeScript.PullHelpers.diagnosticFromDecl(prototypeSymbol.getDeclarations()[0], TypeScript.DiagnosticCode.Duplicate_identifier_0, [prototypeSymbol.getDisplayName()]));
            }

            if (!prototypeSymbol || !prototypeSymbol.getIsSynthesized()) {
                var prototypeDecl = new TypeScript.PullSynthesizedDecl(prototypeStr, prototypeStr, 4096 /* Property */, 4 /* Public */ | 16 /* Static */, constructorTypeSymbol.getDeclarations()[0], this.semanticInfoChain);

                prototypeSymbol = new TypeScript.PullSymbol(prototypeStr, 4096 /* Property */);
                prototypeSymbol.setIsSynthesized();
                prototypeSymbol.addDeclaration(prototypeDecl);
                prototypeSymbol.type = classTypeSymbol;
                constructorTypeSymbol.addMember(prototypeSymbol);

                if (prototypeSymbol.type && prototypeSymbol.type.isGeneric()) {
                    var resolver = this.semanticInfoChain.getResolver();
                    prototypeSymbol.type = resolver.instantiateTypeToAny(prototypeSymbol.type, new TypeScript.PullTypeResolutionContext(resolver));
                }
                prototypeSymbol.setResolved();
            }
        };

        PullSymbolBinder.prototype.bindConstructorDeclarationToPullSymbol = function (constructorDeclaration) {
            var declKind = constructorDeclaration.kind;
            var declFlags = constructorDeclaration.flags;
            var constructorAST = this.semanticInfoChain.getASTForDecl(constructorDeclaration);

            var constructorName = constructorDeclaration.name;

            var isSignature = (declFlags & 2048 /* Signature */) !== 0;

            var parent = this.getParent(constructorDeclaration, true);

            var parentHadSymbol = false;

            var constructorSymbol = parent.getConstructorMethod();
            var constructorTypeSymbol = null;

            if (constructorSymbol && (constructorSymbol.kind !== 32768 /* ConstructorMethod */ || (!isSignature && constructorSymbol.type && constructorSymbol.type.hasOwnConstructSignatures()))) {
                var hasDefinitionSignature = false;
                var constructorSigs = constructorSymbol.type.getOwnDeclaredConstructSignatures();

                for (var i = 0; i < constructorSigs.length; i++) {
                    if (!constructorSigs[i].anyDeclHasFlag(2048 /* Signature */)) {
                        hasDefinitionSignature = true;
                        break;
                    }
                }

                if (hasDefinitionSignature) {
                    this.semanticInfoChain.addDiagnosticFromAST(constructorAST, TypeScript.DiagnosticCode.Multiple_constructor_implementations_are_not_allowed);

                    constructorSymbol = null;
                }
            }

            if (constructorSymbol) {
                constructorTypeSymbol = constructorSymbol.type;
            } else {
                constructorSymbol = new TypeScript.PullSymbol(constructorName, 32768 /* ConstructorMethod */);
                constructorTypeSymbol = new TypeScript.PullTypeSymbol("", 33554432 /* ConstructorType */);
            }

            parent.setConstructorMethod(constructorSymbol);
            constructorSymbol.type = constructorTypeSymbol;

            constructorDeclaration.setSymbol(constructorSymbol);
            constructorSymbol.addDeclaration(constructorDeclaration);
            constructorTypeSymbol.addDeclaration(constructorDeclaration);
            constructorSymbol.setIsSynthesized(false);
            this.semanticInfoChain.setSymbolForAST(constructorAST, constructorSymbol);

            var constructSignature = new TypeScript.PullSignatureSymbol(2097152 /* ConstructSignature */, !isSignature);
            constructSignature.returnType = parent;
            constructSignature.addTypeParametersFromReturnType();

            constructSignature.addDeclaration(constructorDeclaration);
            constructorDeclaration.setSignatureSymbol(constructSignature);

            this.bindParameterSymbols(constructorAST, TypeScript.ASTHelpers.parametersFromParameterList(constructorAST.callSignature.parameterList), constructorTypeSymbol, constructSignature);

            if (TypeScript.lastParameterIsRest(constructorAST.callSignature.parameterList)) {
                constructSignature.hasVarArgs = true;
            }

            constructorTypeSymbol.appendConstructSignature(constructSignature);
        };

        PullSymbolBinder.prototype.bindConstructSignatureDeclarationToPullSymbol = function (constructSignatureDeclaration) {
            var parent = this.getParent(constructSignatureDeclaration, true);
            var constructorAST = this.semanticInfoChain.getASTForDecl(constructSignatureDeclaration);

            var constructSignature = new TypeScript.PullSignatureSymbol(2097152 /* ConstructSignature */);

            if (TypeScript.lastParameterIsRest(constructorAST.callSignature.parameterList)) {
                constructSignature.hasVarArgs = true;
            }

            var typeParameters = constructSignatureDeclaration.getTypeParameters();
            var typeParameter;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = constructSignature.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    constructSignature.addTypeParameter(typeParameter);
                } else {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.getName()]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            constructSignature.addDeclaration(constructSignatureDeclaration);
            constructSignatureDeclaration.setSignatureSymbol(constructSignature);

            var funcDecl = this.semanticInfoChain.getASTForDecl(constructSignatureDeclaration);
            this.bindParameterSymbols(funcDecl, TypeScript.ASTHelpers.parametersFromParameterList(TypeScript.ASTHelpers.getParameterList(funcDecl)), null, constructSignature);

            this.semanticInfoChain.setSymbolForAST(this.semanticInfoChain.getASTForDecl(constructSignatureDeclaration), constructSignature);

            var signatureIndex = this.getIndexForInsertingSignatureAtEndOfEnclosingDeclInSignatureList(constructSignature, parent.getOwnDeclaredConstructSignatures());
            parent.insertConstructSignatureAtIndex(constructSignature, signatureIndex);
        };

        PullSymbolBinder.prototype.bindCallSignatureDeclarationToPullSymbol = function (callSignatureDeclaration) {
            var parent = this.getParent(callSignatureDeclaration, true);
            var callSignatureAST = this.semanticInfoChain.getASTForDecl(callSignatureDeclaration);

            var callSignature = new TypeScript.PullSignatureSymbol(1048576 /* CallSignature */);

            if (TypeScript.lastParameterIsRest(callSignatureAST.parameterList)) {
                callSignature.hasVarArgs = true;
            }

            var typeParameters = callSignatureDeclaration.getTypeParameters();
            var typeParameter;

            for (var i = 0; i < typeParameters.length; i++) {
                typeParameter = callSignature.findTypeParameter(typeParameters[i].name);

                if (!typeParameter) {
                    typeParameter = new TypeScript.PullTypeParameterSymbol(typeParameters[i].name);

                    callSignature.addTypeParameter(typeParameter);
                } else {
                    var typeParameterAST = this.semanticInfoChain.getASTForDecl(typeParameter.getDeclarations()[0]);
                    this.semanticInfoChain.addDiagnosticFromAST(typeParameterAST, TypeScript.DiagnosticCode.Duplicate_identifier_0, [typeParameter.getName()]);
                }

                typeParameter.addDeclaration(typeParameters[i]);
                typeParameters[i].setSymbol(typeParameter);
            }

            callSignature.addDeclaration(callSignatureDeclaration);
            callSignatureDeclaration.setSignatureSymbol(callSignature);

            var funcDecl = this.semanticInfoChain.getASTForDecl(callSignatureDeclaration);
            this.bindParameterSymbols(funcDecl, TypeScript.ASTHelpers.parametersFromParameterList(funcDecl.parameterList), null, callSignature);

            this.semanticInfoChain.setSymbolForAST(this.semanticInfoChain.getASTForDecl(callSignatureDeclaration), callSignature);

            var signatureIndex = this.getIndexForInsertingSignatureAtEndOfEnclosingDeclInSignatureList(callSignature, parent.getOwnCallSignatures());
            parent.insertCallSignatureAtIndex(callSignature, signatureIndex);
        };

        PullSymbolBinder.prototype.bindIndexSignatureDeclarationToPullSymbol = function (indexSignatureDeclaration) {
            var indexSignature = new TypeScript.PullSignatureSymbol(4194304 /* IndexSignature */);

            indexSignature.addDeclaration(indexSignatureDeclaration);
            indexSignatureDeclaration.setSignatureSymbol(indexSignature);

            var funcDecl = this.semanticInfoChain.getASTForDecl(indexSignatureDeclaration);
            this.bindParameterSymbols(funcDecl, TypeScript.ASTHelpers.parametersFromParameter(funcDecl.parameter), null, indexSignature);

            this.semanticInfoChain.setSymbolForAST(this.semanticInfoChain.getASTForDecl(indexSignatureDeclaration), indexSignature);

            var parent = this.getParent(indexSignatureDeclaration);
            parent.addIndexSignature(indexSignature);
            indexSignature.setContainer(parent);
        };

        PullSymbolBinder.prototype.bindGetAccessorDeclarationToPullSymbol = function (getAccessorDeclaration) {
            var declKind = getAccessorDeclaration.kind;
            var declFlags = getAccessorDeclaration.flags;
            var funcDeclAST = this.semanticInfoChain.getASTForDecl(getAccessorDeclaration);

            var isExported = (declFlags & 1 /* Exported */) !== 0;

            var funcName = getAccessorDeclaration.name;

            var isSignature = (declFlags & 2048 /* Signature */) !== 0;
            var isStatic = false;

            if (TypeScript.hasFlag(declFlags, 16 /* Static */)) {
                isStatic = true;
            }

            var parent = this.getParent(getAccessorDeclaration, true);
            var parentHadSymbol = false;

            var accessorSymbol = null;
            var getterSymbol = null;
            var getterTypeSymbol = null;

            if (isStatic) {
                parent = parent.getConstructorMethod().type;
            }

            accessorSymbol = parent.findMember(funcName, false);

            if (accessorSymbol) {
                if (!accessorSymbol.isAccessor()) {
                    this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(funcDeclAST.propertyName, getAccessorDeclaration.getDisplayName(), accessorSymbol.getDeclarations()[0].ast());
                    accessorSymbol = null;
                } else {
                    getterSymbol = accessorSymbol.getGetter();

                    if (getterSymbol) {
                        this.semanticInfoChain.addDiagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Getter_0_already_declared, [getAccessorDeclaration.getDisplayName()]);
                        accessorSymbol = null;
                        getterSymbol = null;
                    }
                }
            }

            if (accessorSymbol) {
                parentHadSymbol = true;
            }

            if (accessorSymbol && getterSymbol) {
                getterTypeSymbol = getterSymbol.type;
            }

            if (!accessorSymbol) {
                accessorSymbol = new TypeScript.PullAccessorSymbol(funcName);
            }

            if (!getterSymbol) {
                getterSymbol = new TypeScript.PullSymbol(funcName, 16384 /* Function */);
                getterTypeSymbol = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);
                getterTypeSymbol.setFunctionSymbol(getterSymbol);

                getterSymbol.type = getterTypeSymbol;

                accessorSymbol.setGetter(getterSymbol);
            }

            getAccessorDeclaration.setSymbol(accessorSymbol);
            accessorSymbol.addDeclaration(getAccessorDeclaration);
            getterSymbol.addDeclaration(getAccessorDeclaration);

            var nameAST = funcDeclAST.propertyName;
            this.semanticInfoChain.setSymbolForAST(nameAST, accessorSymbol);
            this.semanticInfoChain.setSymbolForAST(funcDeclAST, getterSymbol);

            if (!parentHadSymbol) {
                parent.addMember(accessorSymbol);
            }

            var signature = new TypeScript.PullSignatureSymbol(1048576 /* CallSignature */, !isSignature);

            signature.addDeclaration(getAccessorDeclaration);
            getAccessorDeclaration.setSignatureSymbol(signature);

            this.bindParameterSymbols(funcDeclAST, TypeScript.ASTHelpers.parametersFromParameterList(funcDeclAST.parameterList), getterTypeSymbol, signature);

            getterTypeSymbol.appendCallSignature(signature);
        };

        PullSymbolBinder.prototype.bindSetAccessorDeclarationToPullSymbol = function (setAccessorDeclaration) {
            var declKind = setAccessorDeclaration.kind;
            var declFlags = setAccessorDeclaration.flags;
            var funcDeclAST = this.semanticInfoChain.getASTForDecl(setAccessorDeclaration);

            var isExported = (declFlags & 1 /* Exported */) !== 0;

            var funcName = setAccessorDeclaration.name;

            var isSignature = (declFlags & 2048 /* Signature */) !== 0;
            var isStatic = false;

            if (TypeScript.hasFlag(declFlags, 16 /* Static */)) {
                isStatic = true;
            }

            var parent = this.getParent(setAccessorDeclaration, true);
            var parentHadSymbol = false;

            var accessorSymbol = null;
            var setterSymbol = null;
            var setterTypeSymbol = null;

            if (isStatic) {
                parent = parent.getConstructorMethod().type;
            }

            accessorSymbol = parent.findMember(funcName, false);

            if (accessorSymbol) {
                if (!accessorSymbol.isAccessor()) {
                    this.semanticInfoChain.addDuplicateIdentifierDiagnosticFromAST(funcDeclAST.propertyName, setAccessorDeclaration.getDisplayName(), accessorSymbol.getDeclarations()[0].ast());
                    accessorSymbol = null;
                } else {
                    setterSymbol = accessorSymbol.getSetter();

                    if (setterSymbol) {
                        this.semanticInfoChain.addDiagnosticFromAST(funcDeclAST, TypeScript.DiagnosticCode.Setter_0_already_declared, [setAccessorDeclaration.getDisplayName()]);
                        accessorSymbol = null;
                        setterSymbol = null;
                    }
                }
            }

            if (accessorSymbol) {
                parentHadSymbol = true;

                if (setterSymbol) {
                    setterTypeSymbol = setterSymbol.type;
                }
            }

            if (!accessorSymbol) {
                accessorSymbol = new TypeScript.PullAccessorSymbol(funcName);
            }

            if (!setterSymbol) {
                setterSymbol = new TypeScript.PullSymbol(funcName, 16384 /* Function */);
                setterTypeSymbol = new TypeScript.PullTypeSymbol("", 16777216 /* FunctionType */);
                setterTypeSymbol.setFunctionSymbol(setterSymbol);

                setterSymbol.type = setterTypeSymbol;

                accessorSymbol.setSetter(setterSymbol);
            }

            setAccessorDeclaration.setSymbol(accessorSymbol);
            accessorSymbol.addDeclaration(setAccessorDeclaration);
            setterSymbol.addDeclaration(setAccessorDeclaration);

            var nameAST = funcDeclAST.propertyName;
            this.semanticInfoChain.setSymbolForAST(nameAST, accessorSymbol);
            this.semanticInfoChain.setSymbolForAST(funcDeclAST, setterSymbol);

            if (!parentHadSymbol) {
                parent.addMember(accessorSymbol);
            }

            var signature = new TypeScript.PullSignatureSymbol(1048576 /* CallSignature */, !isSignature);

            signature.addDeclaration(setAccessorDeclaration);
            setAccessorDeclaration.setSignatureSymbol(signature);

            this.bindParameterSymbols(funcDeclAST, TypeScript.ASTHelpers.parametersFromParameterList(funcDeclAST.parameterList), setterTypeSymbol, signature);

            setterTypeSymbol.appendCallSignature(signature);
        };

        PullSymbolBinder.prototype.getDeclsToBind = function (decl) {
            var decls;
            switch (decl.kind) {
                case 64 /* Enum */:
                case 32 /* DynamicModule */:
                case 4 /* Container */:
                case 16 /* Interface */:
                    decls = this.findDeclsInContext(decl, decl.kind, true);
                    break;

                case 512 /* Variable */:
                case 16384 /* Function */:
                case 65536 /* Method */:
                case 32768 /* ConstructorMethod */:
                    decls = this.findDeclsInContext(decl, decl.kind, false);
                    break;

                default:
                    decls = [decl];
            }
            TypeScript.Debug.assert(decls && decls.length > 0);
            TypeScript.Debug.assert(TypeScript.ArrayUtilities.contains(decls, decl));
            return decls;
        };

        PullSymbolBinder.prototype.shouldBindDeclaration = function (decl) {
            return !decl.hasBeenBound() && this.declsBeingBound.indexOf(decl.declID) < 0;
        };

        PullSymbolBinder.prototype.bindDeclToPullSymbol = function (decl) {
            if (this.shouldBindDeclaration(decl)) {
                this.bindAllDeclsToPullSymbol(decl);
            }
        };

        PullSymbolBinder.prototype.bindAllDeclsToPullSymbol = function (askedDecl) {
            var allDecls = this.getDeclsToBind(askedDecl);
            for (var i = 0; i < allDecls.length; i++) {
                var decl = allDecls[i];

                if (this.shouldBindDeclaration(decl)) {
                    this.bindSingleDeclToPullSymbol(decl);
                }
            }
        };

        PullSymbolBinder.prototype.bindSingleDeclToPullSymbol = function (decl) {
            this.declsBeingBound.push(decl.declID);

            switch (decl.kind) {
                case 1 /* Script */:
                    var childDecls = decl.getChildDecls();
                    for (var i = 0; i < childDecls.length; i++) {
                        this.bindDeclToPullSymbol(childDecls[i]);
                    }
                    break;

                case 64 /* Enum */:
                    this.bindEnumDeclarationToPullSymbol(decl);
                    break;

                case 32 /* DynamicModule */:
                case 4 /* Container */:
                    this.bindModuleDeclarationToPullSymbol(decl);
                    break;

                case 16 /* Interface */:
                    this.bindInterfaceDeclarationToPullSymbol(decl);
                    break;

                case 8 /* Class */:
                    this.bindClassDeclarationToPullSymbol(decl);
                    break;

                case 16384 /* Function */:
                    this.bindFunctionDeclarationToPullSymbol(decl);
                    break;

                case 512 /* Variable */:
                    this.bindVariableDeclarationToPullSymbol(decl);
                    break;

                case 1024 /* CatchVariable */:
                    this.bindCatchVariableToPullSymbol(decl);
                    break;

                case 67108864 /* EnumMember */:
                    this.bindEnumMemberDeclarationToPullSymbol(decl);
                    break;

                case 4096 /* Property */:
                    this.bindPropertyDeclarationToPullSymbol(decl);
                    break;

                case 65536 /* Method */:
                    this.bindMethodDeclarationToPullSymbol(decl);
                    break;

                case 32768 /* ConstructorMethod */:
                    this.bindConstructorDeclarationToPullSymbol(decl);
                    break;

                case 1048576 /* CallSignature */:
                    this.bindCallSignatureDeclarationToPullSymbol(decl);
                    break;

                case 2097152 /* ConstructSignature */:
                    this.bindConstructSignatureDeclarationToPullSymbol(decl);
                    break;

                case 4194304 /* IndexSignature */:
                    this.bindIndexSignatureDeclarationToPullSymbol(decl);
                    break;

                case 262144 /* GetAccessor */:
                    this.bindGetAccessorDeclarationToPullSymbol(decl);
                    break;

                case 524288 /* SetAccessor */:
                    this.bindSetAccessorDeclarationToPullSymbol(decl);
                    break;

                case 8388608 /* ObjectType */:
                    this.bindObjectTypeDeclarationToPullSymbol(decl);
                    break;

                case 16777216 /* FunctionType */:
                    this.bindFunctionTypeDeclarationToPullSymbol(decl);
                    break;

                case 33554432 /* ConstructorType */:
                    this.bindConstructorTypeDeclarationToPullSymbol(decl);
                    break;

                case 131072 /* FunctionExpression */:
                    this.bindFunctionExpressionToPullSymbol(decl);
                    break;

                case 128 /* TypeAlias */:
                    this.bindImportDeclaration(decl);
                    break;

                case 2048 /* Parameter */:
                case 8192 /* TypeParameter */:
                    decl.getParentDecl().getSymbol();
                    break;

                case 268435456 /* CatchBlock */:
                case 134217728 /* WithBlock */:
                    break;

                default:
                    TypeScript.CompilerDiagnostics.assert(false, "Unrecognized type declaration");
            }

            TypeScript.Debug.assert(TypeScript.ArrayUtilities.last(this.declsBeingBound) === decl.declID);
            this.declsBeingBound.pop();
        };
        return PullSymbolBinder;
    })();
    TypeScript.PullSymbolBinder = PullSymbolBinder;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (PullHelpers) {
        function diagnosticFromDecl(decl, diagnosticKey, _arguments, additionalLocations) {
            if (typeof _arguments === "undefined") { _arguments = null; }
            if (typeof additionalLocations === "undefined") { additionalLocations = null; }
            var ast = decl.ast();
            return decl.semanticInfoChain.diagnosticFromAST(ast, diagnosticKey, _arguments, additionalLocations);
        }
        PullHelpers.diagnosticFromDecl = diagnosticFromDecl;

        function resolveDeclaredSymbolToUseType(symbol) {
            if (symbol.isSignature()) {
                if (!symbol.returnType) {
                    symbol._resolveDeclaredSymbol();
                }
            } else if (!symbol.type) {
                symbol._resolveDeclaredSymbol();
            }
        }
        PullHelpers.resolveDeclaredSymbolToUseType = resolveDeclaredSymbolToUseType;

        function getSignatureForFuncDecl(functionDecl) {
            var funcDecl = functionDecl.ast();
            var funcSymbol = functionDecl.getSymbol();

            if (!funcSymbol) {
                funcSymbol = functionDecl.getSignatureSymbol();
            }

            var functionSignature = null;
            var typeSymbolWithAllSignatures = null;
            if (funcSymbol.isSignature()) {
                functionSignature = funcSymbol;
                var parent = functionDecl.getParentDecl();
                typeSymbolWithAllSignatures = parent.getSymbol().type;
            } else {
                functionSignature = functionDecl.getSignatureSymbol();
                typeSymbolWithAllSignatures = funcSymbol.type;
            }
            var signatures;

            if (funcDecl.kind() === 137 /* ConstructorDeclaration */ || functionDecl.kind === 2097152 /* ConstructSignature */) {
                signatures = typeSymbolWithAllSignatures.getConstructSignatures();
            } else if (functionDecl.kind === 4194304 /* IndexSignature */) {
                signatures = typeSymbolWithAllSignatures.getIndexSignatures();
            } else {
                signatures = typeSymbolWithAllSignatures.getCallSignatures();
            }

            return {
                signature: functionSignature,
                allSignatures: signatures
            };
        }
        PullHelpers.getSignatureForFuncDecl = getSignatureForFuncDecl;

        function getAccessorSymbol(getterOrSetter, semanticInfoChain) {
            var functionDecl = semanticInfoChain.getDeclForAST(getterOrSetter);
            var getterOrSetterSymbol = functionDecl.getSymbol();

            return getterOrSetterSymbol;
        }
        PullHelpers.getAccessorSymbol = getAccessorSymbol;

        function getGetterAndSetterFunction(funcDecl, semanticInfoChain) {
            var accessorSymbol = PullHelpers.getAccessorSymbol(funcDecl, semanticInfoChain);
            var result = {
                getter: null,
                setter: null
            };
            var getter = accessorSymbol.getGetter();
            if (getter) {
                var getterDecl = getter.getDeclarations()[0];
                result.getter = semanticInfoChain.getASTForDecl(getterDecl);
            }
            var setter = accessorSymbol.getSetter();
            if (setter) {
                var setterDecl = setter.getDeclarations()[0];
                result.setter = semanticInfoChain.getASTForDecl(setterDecl);
            }

            return result;
        }
        PullHelpers.getGetterAndSetterFunction = getGetterAndSetterFunction;

        function symbolIsEnum(source) {
            return source && (source.kind & (64 /* Enum */ | 67108864 /* EnumMember */)) !== 0;
        }
        PullHelpers.symbolIsEnum = symbolIsEnum;

        function symbolIsModule(symbol) {
            return symbol && (symbol.kind === 4 /* Container */ || isOneDeclarationOfKind(symbol, 4 /* Container */));
        }
        PullHelpers.symbolIsModule = symbolIsModule;

        function isOneDeclarationOfKind(symbol, kind) {
            var decls = symbol.getDeclarations();
            for (var i = 0; i < decls.length; i++) {
                if (decls[i].kind === kind) {
                    return true;
                }
            }

            return false;
        }

        function isNameNumeric(name) {
            return isFinite(+name);
        }
        PullHelpers.isNameNumeric = isNameNumeric;

        function typeSymbolsAreIdentical(a, b) {
            if (a.isTypeReference() && !a.getIsSpecialized()) {
                a = a.referencedTypeSymbol;
            }

            if (b.isTypeReference() && !b.getIsSpecialized()) {
                b = b.referencedTypeSymbol;
            }

            return a === b;
        }
        PullHelpers.typeSymbolsAreIdentical = typeSymbolsAreIdentical;

        function getRootType(type) {
            var rootType = type.getRootSymbol();

            while (true) {
                if (type === rootType) {
                    return type;
                }

                type = rootType;
                rootType = type.getRootSymbol();
            }
        }
        PullHelpers.getRootType = getRootType;

        function isSymbolLocal(symbol) {
            var container = symbol.getContainer();
            if (container) {
                var containerKind = container.kind;
                if (containerKind & (1032192 /* SomeFunction */ | 16777216 /* FunctionType */)) {
                    return true;
                }

                if (containerKind === 33554432 /* ConstructorType */ && !symbol.anyDeclHasFlag(16 /* Static */ | 1 /* Exported */)) {
                    return true;
                }
            }

            return false;
        }
        PullHelpers.isSymbolLocal = isSymbolLocal;

        function isExportedSymbolInClodule(symbol) {
            var container = symbol.getContainer();
            return container && container.kind === 33554432 /* ConstructorType */ && symbolIsModule(container) && symbol.anyDeclHasFlag(1 /* Exported */);
        }
        PullHelpers.isExportedSymbolInClodule = isExportedSymbolInClodule;

        function isSymbolDeclaredInScopeChain(symbol, scopeSymbol) {
            TypeScript.Debug.assert(symbol);
            var symbolDeclarationScope = symbol.getContainer();

            while (scopeSymbol) {
                if (scopeSymbol === symbolDeclarationScope) {
                    return true;
                }

                scopeSymbol = scopeSymbol.getContainer();
            }

            if (scopeSymbol === null && symbolDeclarationScope === null) {
                return true;
            }

            return false;
        }
        PullHelpers.isSymbolDeclaredInScopeChain = isSymbolDeclaredInScopeChain;

        

        function walkSignatureSymbol(signatureSymbol, walker) {
            var continueWalk = true;
            var parameters = signatureSymbol.parameters;
            if (parameters) {
                for (var i = 0; continueWalk && i < parameters.length; i++) {
                    continueWalk = walker.signatureParameterWalk(parameters[i]);
                }
            }

            if (continueWalk) {
                continueWalk = walker.signatureReturnTypeWalk(signatureSymbol.returnType);
            }

            return continueWalk;
        }

        function walkPullTypeSymbolStructure(typeSymbol, walker) {
            var continueWalk = true;

            var members = typeSymbol.getMembers();
            for (var i = 0; continueWalk && i < members.length; i++) {
                continueWalk = walker.memberSymbolWalk(members[i]);
            }

            if (continueWalk) {
                var callSigantures = typeSymbol.getCallSignatures();
                for (var i = 0; continueWalk && i < callSigantures.length; i++) {
                    continueWalk = walker.callSignatureWalk(callSigantures[i]);
                    if (continueWalk) {
                        continueWalk = walkSignatureSymbol(callSigantures[i], walker);
                    }
                }
            }

            if (continueWalk) {
                var constructSignatures = typeSymbol.getConstructSignatures();
                for (var i = 0; continueWalk && i < constructSignatures.length; i++) {
                    continueWalk = walker.constructSignatureWalk(constructSignatures[i]);
                    if (continueWalk) {
                        continueWalk = walkSignatureSymbol(constructSignatures[i], walker);
                    }
                }
            }

            if (continueWalk) {
                var indexSignatures = typeSymbol.getIndexSignatures();
                for (var i = 0; continueWalk && i < indexSignatures.length; i++) {
                    continueWalk = walker.indexSignatureWalk(indexSignatures[i]);
                    if (continueWalk) {
                        continueWalk = walkSignatureSymbol(indexSignatures[i], walker);
                    }
                }
            }
        }
        PullHelpers.walkPullTypeSymbolStructure = walkPullTypeSymbolStructure;

        var OtherPullDeclsWalker = (function () {
            function OtherPullDeclsWalker() {
                this.currentlyWalkingOtherDecls = [];
            }
            OtherPullDeclsWalker.prototype.walkOtherPullDecls = function (currentDecl, otherDecls, callBack) {
                if (otherDecls) {
                    var isAlreadyWalkingOtherDecl = TypeScript.ArrayUtilities.any(this.currentlyWalkingOtherDecls, function (inWalkingOtherDecl) {
                        return TypeScript.ArrayUtilities.contains(otherDecls, inWalkingOtherDecl);
                    });

                    if (!isAlreadyWalkingOtherDecl) {
                        this.currentlyWalkingOtherDecls.push(currentDecl);
                        for (var i = 0; i < otherDecls.length; i++) {
                            if (otherDecls[i] !== currentDecl) {
                                callBack(otherDecls[i]);
                            }
                        }
                        var currentlyWalkingOtherDeclsDecl = this.currentlyWalkingOtherDecls.pop();
                        TypeScript.Debug.assert(currentlyWalkingOtherDeclsDecl == currentDecl);
                    }
                }
            };
            return OtherPullDeclsWalker;
        })();
        PullHelpers.OtherPullDeclsWalker = OtherPullDeclsWalker;
    })(TypeScript.PullHelpers || (TypeScript.PullHelpers = {}));
    var PullHelpers = TypeScript.PullHelpers;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var WrapsTypeParameterCache = (function () {
        function WrapsTypeParameterCache() {
            this._wrapsTypeParameterCache = TypeScript.BitVector.getBitVector(true);
        }
        WrapsTypeParameterCache.prototype.getWrapsTypeParameter = function (typeParameterArgumentMap) {
            var mapHasTypeParameterNotCached = false;
            for (var typeParameterID in typeParameterArgumentMap) {
                if (typeParameterArgumentMap.hasOwnProperty(typeParameterID)) {
                    var cachedValue = this._wrapsTypeParameterCache.valueAt(typeParameterID);
                    if (cachedValue) {
                        return typeParameterID;
                    }
                    mapHasTypeParameterNotCached = mapHasTypeParameterNotCached || cachedValue === undefined;
                }
            }

            if (!mapHasTypeParameterNotCached) {
                return 0;
            }

            return undefined;
        };

        WrapsTypeParameterCache.prototype.setWrapsTypeParameter = function (typeParameterArgumentMap, wrappingTypeParameterID) {
            if (wrappingTypeParameterID) {
                this._wrapsTypeParameterCache.setValueAt(wrappingTypeParameterID, true);
            } else {
                for (var typeParameterID in typeParameterArgumentMap) {
                    if (typeParameterArgumentMap.hasOwnProperty(typeParameterID)) {
                        this._wrapsTypeParameterCache.setValueAt(typeParameterID, false);
                    }
                }
            }
        };
        return WrapsTypeParameterCache;
    })();
    TypeScript.WrapsTypeParameterCache = WrapsTypeParameterCache;

    (function (PullInstantiationHelpers) {
        var MutableTypeArgumentMap = (function () {
            function MutableTypeArgumentMap(typeParameterArgumentMap) {
                this.typeParameterArgumentMap = typeParameterArgumentMap;
                this.createdDuplicateTypeArgumentMap = false;
            }
            MutableTypeArgumentMap.prototype.ensureTypeArgumentCopy = function () {
                if (!this.createdDuplicateTypeArgumentMap) {
                    var passedInTypeArgumentMap = this.typeParameterArgumentMap;
                    this.typeParameterArgumentMap = [];
                    for (var typeParameterID in passedInTypeArgumentMap) {
                        if (passedInTypeArgumentMap.hasOwnProperty(typeParameterID)) {
                            this.typeParameterArgumentMap[typeParameterID] = passedInTypeArgumentMap[typeParameterID];
                        }
                    }
                    this.createdDuplicateTypeArgumentMap = true;
                }
            };
            return MutableTypeArgumentMap;
        })();
        PullInstantiationHelpers.MutableTypeArgumentMap = MutableTypeArgumentMap;

        function instantiateTypeArgument(resolver, symbol, mutableTypeParameterMap) {
            if (symbol.getIsSpecialized()) {
                var rootTypeArgumentMap = symbol.getTypeParameterArgumentMap();
                var newTypeArgumentMap = [];
                var allowedTypeParameters = symbol.getAllowedToReferenceTypeParameters();
                for (var i = 0; i < allowedTypeParameters.length; i++) {
                    var typeParameterID = allowedTypeParameters[i].pullSymbolID;
                    var typeArg = rootTypeArgumentMap[typeParameterID];
                    if (typeArg) {
                        newTypeArgumentMap[typeParameterID] = resolver.instantiateType(typeArg, mutableTypeParameterMap.typeParameterArgumentMap);
                    }
                }

                for (var i = 0; i < allowedTypeParameters.length; i++) {
                    var typeParameterID = allowedTypeParameters[i].pullSymbolID;
                    if (newTypeArgumentMap[typeParameterID] && mutableTypeParameterMap.typeParameterArgumentMap[typeParameterID] != newTypeArgumentMap[typeParameterID]) {
                        mutableTypeParameterMap.ensureTypeArgumentCopy();
                        mutableTypeParameterMap.typeParameterArgumentMap[typeParameterID] = newTypeArgumentMap[typeParameterID];
                    }
                }
            }
        }
        PullInstantiationHelpers.instantiateTypeArgument = instantiateTypeArgument;

        function cleanUpTypeArgumentMap(symbol, mutableTypeArgumentMap) {
            var allowedToReferenceTypeParameters = symbol.getAllowedToReferenceTypeParameters();
            for (var typeParameterID in mutableTypeArgumentMap.typeParameterArgumentMap) {
                if (mutableTypeArgumentMap.typeParameterArgumentMap.hasOwnProperty(typeParameterID)) {
                    if (!TypeScript.ArrayUtilities.any(allowedToReferenceTypeParameters, function (typeParameter) {
                        return typeParameter.pullSymbolID == typeParameterID;
                    })) {
                        mutableTypeArgumentMap.ensureTypeArgumentCopy();
                        delete mutableTypeArgumentMap.typeParameterArgumentMap[typeParameterID];
                    }
                }
            }
        }
        PullInstantiationHelpers.cleanUpTypeArgumentMap = cleanUpTypeArgumentMap;

        function getAllowedToReferenceTypeParametersFromDecl(decl) {
            var allowedToReferenceTypeParameters = [];

            var allowedToUseDeclTypeParameters = false;
            var getTypeParametersFromParentDecl = false;

            switch (decl.kind) {
                case 65536 /* Method */:
                    if (TypeScript.hasFlag(decl.flags, 16 /* Static */)) {
                        allowedToUseDeclTypeParameters = true;
                        break;
                    }

                case 16777216 /* FunctionType */:
                case 33554432 /* ConstructorType */:
                case 2097152 /* ConstructSignature */:
                case 1048576 /* CallSignature */:
                case 131072 /* FunctionExpression */:
                case 16384 /* Function */:
                    allowedToUseDeclTypeParameters = true;
                    getTypeParametersFromParentDecl = true;
                    break;

                case 4096 /* Property */:
                    if (TypeScript.hasFlag(decl.flags, 16 /* Static */)) {
                        break;
                    }

                case 2048 /* Parameter */:
                case 262144 /* GetAccessor */:
                case 524288 /* SetAccessor */:
                case 32768 /* ConstructorMethod */:
                case 4194304 /* IndexSignature */:
                case 8388608 /* ObjectType */:
                case 256 /* ObjectLiteral */:
                case 8192 /* TypeParameter */:
                    getTypeParametersFromParentDecl = true;
                    break;

                case 8 /* Class */:
                case 16 /* Interface */:
                    allowedToUseDeclTypeParameters = true;
                    break;
            }

            if (getTypeParametersFromParentDecl) {
                allowedToReferenceTypeParameters = allowedToReferenceTypeParameters.concat(getAllowedToReferenceTypeParametersFromDecl(decl.getParentDecl()));
            }

            if (allowedToUseDeclTypeParameters) {
                var typeParameterDecls = decl.getTypeParameters();
                for (var i = 0; i < typeParameterDecls.length; i++) {
                    allowedToReferenceTypeParameters.push(typeParameterDecls[i].getSymbol());
                }
            }

            return allowedToReferenceTypeParameters;
        }
        PullInstantiationHelpers.getAllowedToReferenceTypeParametersFromDecl = getAllowedToReferenceTypeParametersFromDecl;

        function createTypeParameterArgumentMap(typeParameters, typeArguments) {
            return updateTypeParameterArgumentMap(typeParameters, typeArguments, {});
        }
        PullInstantiationHelpers.createTypeParameterArgumentMap = createTypeParameterArgumentMap;

        function updateTypeParameterArgumentMap(typeParameters, typeArguments, typeParameterArgumentMap) {
            for (var i = 0; i < typeParameters.length; i++) {
                typeParameterArgumentMap[typeParameters[i].getRootSymbol().pullSymbolID] = typeArguments[i];
            }
            return typeParameterArgumentMap;
        }
        PullInstantiationHelpers.updateTypeParameterArgumentMap = updateTypeParameterArgumentMap;

        function updateMutableTypeParameterArgumentMap(typeParameters, typeArguments, mutableMap) {
            for (var i = 0; i < typeParameters.length; i++) {
                var typeParameterId = typeParameters[i].getRootSymbol().pullSymbolID;
                if (mutableMap.typeParameterArgumentMap[typeParameterId] !== typeArguments[i]) {
                    mutableMap.ensureTypeArgumentCopy();
                    mutableMap.typeParameterArgumentMap[typeParameterId] = typeArguments[i];
                }
            }
        }
        PullInstantiationHelpers.updateMutableTypeParameterArgumentMap = updateMutableTypeParameterArgumentMap;

        function twoTypesAreInstantiationsOfSameNamedGenericType(type1, type2) {
            var type1IsGeneric = type1.isGeneric() && type1.getTypeArguments() !== null;
            var type2IsGeneric = type2.isGeneric() && type2.getTypeArguments() !== null;

            if (type1IsGeneric && type2IsGeneric) {
                var type1Root = TypeScript.PullHelpers.getRootType(type1);
                var type2Root = TypeScript.PullHelpers.getRootType(type2);
                return type1Root === type2Root;
            }

            return false;
        }
        PullInstantiationHelpers.twoTypesAreInstantiationsOfSameNamedGenericType = twoTypesAreInstantiationsOfSameNamedGenericType;
    })(TypeScript.PullInstantiationHelpers || (TypeScript.PullInstantiationHelpers = {}));
    var PullInstantiationHelpers = TypeScript.PullInstantiationHelpers;
})(TypeScript || (TypeScript = {}));
if (Error)
    Error.stackTraceLimit = 1000;

var TypeScript;
(function (TypeScript) {
    TypeScript.fileResolutionTime = 0;
    TypeScript.fileResolutionIOTime = 0;
    TypeScript.fileResolutionScanImportsTime = 0;
    TypeScript.fileResolutionImportFileSearchTime = 0;
    TypeScript.fileResolutionGetDefaultLibraryTime = 0;
    TypeScript.sourceCharactersCompiled = 0;
    TypeScript.syntaxTreeParseTime = 0;
    TypeScript.syntaxDiagnosticsTime = 0;
    TypeScript.astTranslationTime = 0;
    TypeScript.typeCheckTime = 0;

    TypeScript.compilerResolvePathTime = 0;
    TypeScript.compilerDirectoryNameTime = 0;
    TypeScript.compilerDirectoryExistsTime = 0;
    TypeScript.compilerFileExistsTime = 0;

    TypeScript.emitTime = 0;
    TypeScript.emitWriteFileTime = 0;

    TypeScript.declarationEmitTime = 0;
    TypeScript.declarationEmitIsExternallyVisibleTime = 0;
    TypeScript.declarationEmitTypeSignatureTime = 0;
    TypeScript.declarationEmitGetBoundDeclTypeTime = 0;
    TypeScript.declarationEmitIsOverloadedCallSignatureTime = 0;
    TypeScript.declarationEmitFunctionDeclarationGetSymbolTime = 0;
    TypeScript.declarationEmitGetBaseTypeTime = 0;
    TypeScript.declarationEmitGetAccessorFunctionTime = 0;
    TypeScript.declarationEmitGetTypeParameterSymbolTime = 0;
    TypeScript.declarationEmitGetImportDeclarationSymbolTime = 0;

    TypeScript.ioHostResolvePathTime = 0;
    TypeScript.ioHostDirectoryNameTime = 0;
    TypeScript.ioHostCreateDirectoryStructureTime = 0;
    TypeScript.ioHostWriteFileTime = 0;

    (function (EmitOutputResult) {
        EmitOutputResult[EmitOutputResult["Succeeded"] = 0] = "Succeeded";
        EmitOutputResult[EmitOutputResult["FailedBecauseOfSyntaxErrors"] = 1] = "FailedBecauseOfSyntaxErrors";
        EmitOutputResult[EmitOutputResult["FailedBecauseOfCompilerOptionsErrors"] = 2] = "FailedBecauseOfCompilerOptionsErrors";
        EmitOutputResult[EmitOutputResult["FailedToGenerateDeclarationsBecauseOfSemanticErrors"] = 3] = "FailedToGenerateDeclarationsBecauseOfSemanticErrors";
    })(TypeScript.EmitOutputResult || (TypeScript.EmitOutputResult = {}));
    var EmitOutputResult = TypeScript.EmitOutputResult;

    var EmitOutput = (function () {
        function EmitOutput(emitOutputResult) {
            if (typeof emitOutputResult === "undefined") { emitOutputResult = 0 /* Succeeded */; }
            this.outputFiles = [];
            this.emitOutputResult = emitOutputResult;
        }
        return EmitOutput;
    })();
    TypeScript.EmitOutput = EmitOutput;

    (function (OutputFileType) {
        OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
        OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
        OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
    })(TypeScript.OutputFileType || (TypeScript.OutputFileType = {}));
    var OutputFileType = TypeScript.OutputFileType;

    var OutputFile = (function () {
        function OutputFile(name, writeByteOrderMark, text, fileType, sourceMapEntries) {
            if (typeof sourceMapEntries === "undefined") { sourceMapEntries = []; }
            this.name = name;
            this.writeByteOrderMark = writeByteOrderMark;
            this.text = text;
            this.fileType = fileType;
            this.sourceMapEntries = sourceMapEntries;
        }
        return OutputFile;
    })();
    TypeScript.OutputFile = OutputFile;

    var CompileResult = (function () {
        function CompileResult() {
            this.diagnostics = [];
            this.outputFiles = [];
        }
        CompileResult.fromDiagnostics = function (diagnostics) {
            var result = new CompileResult();
            result.diagnostics = diagnostics;
            return result;
        };

        CompileResult.fromOutputFiles = function (outputFiles) {
            var result = new CompileResult();
            result.outputFiles = outputFiles;
            return result;
        };
        return CompileResult;
    })();
    TypeScript.CompileResult = CompileResult;

    var TypeScriptCompiler = (function () {
        function TypeScriptCompiler(logger, _settings) {
            if (typeof logger === "undefined") { logger = new TypeScript.NullLogger(); }
            if (typeof _settings === "undefined") { _settings = TypeScript.ImmutableCompilationSettings.defaultSettings(); }
            this.logger = logger;
            this._settings = _settings;
            this.semanticInfoChain = null;
            this.semanticInfoChain = new TypeScript.SemanticInfoChain(this, logger);
        }
        TypeScriptCompiler.prototype.compilationSettings = function () {
            return this._settings;
        };

        TypeScriptCompiler.prototype.setCompilationSettings = function (newSettings) {
            var oldSettings = this._settings;
            this._settings = newSettings;

            if (!compareDataObjects(oldSettings, newSettings)) {
                this.semanticInfoChain.invalidate(oldSettings, newSettings);
            }
        };

        TypeScriptCompiler.prototype.getDocument = function (fileName) {
            fileName = TypeScript.switchToForwardSlashes(fileName);
            return this.semanticInfoChain.getDocument(fileName);
        };

        TypeScriptCompiler.prototype.cleanupSemanticCache = function () {
            this.semanticInfoChain.invalidate();
        };

        TypeScriptCompiler.prototype.addFile = function (fileName, scriptSnapshot, byteOrderMark, version, isOpen, referencedFiles) {
            if (typeof referencedFiles === "undefined") { referencedFiles = []; }
            fileName = TypeScript.switchToForwardSlashes(fileName);

            TypeScript.sourceCharactersCompiled += scriptSnapshot.getLength();

            var document = TypeScript.Document.create(this, this.semanticInfoChain, fileName, scriptSnapshot, byteOrderMark, version, isOpen, referencedFiles);

            this.semanticInfoChain.addDocument(document);
        };

        TypeScriptCompiler.prototype.updateFile = function (fileName, scriptSnapshot, version, isOpen, textChangeRange) {
            fileName = TypeScript.switchToForwardSlashes(fileName);

            var document = this.getDocument(fileName);
            var updatedDocument = document.update(scriptSnapshot, version, isOpen, textChangeRange);

            this.semanticInfoChain.addDocument(updatedDocument);
        };

        TypeScriptCompiler.prototype.removeFile = function (fileName) {
            fileName = TypeScript.switchToForwardSlashes(fileName);
            this.semanticInfoChain.removeDocument(fileName);
        };

        TypeScriptCompiler.prototype.mapOutputFileName = function (document, emitOptions, extensionChanger) {
            if (document.emitToOwnOutputFile()) {
                var updatedFileName = document.fileName;
                if (emitOptions.outputDirectory() !== "") {
                    updatedFileName = document.fileName.replace(emitOptions.commonDirectoryPath(), "");
                    updatedFileName = emitOptions.outputDirectory() + updatedFileName;
                }
                return extensionChanger(updatedFileName, false);
            } else {
                return extensionChanger(emitOptions.sharedOutputFile(), true);
            }
        };

        TypeScriptCompiler.prototype.writeByteOrderMarkForDocument = function (document) {
            var printReason = false;

            if (document.emitToOwnOutputFile()) {
                var result = document.byteOrderMark !== 0 /* None */;
                if (printReason) {
                    TypeScript.Environment.standardOut.WriteLine("Emitting byte order mark because of: " + document.fileName);
                }
                return result;
            } else {
                var fileNames = this.fileNames();

                var result = false;
                for (var i = 0, n = fileNames.length; i < n; i++) {
                    var document = this.getDocument(fileNames[i]);

                    if (document.isExternalModule()) {
                        continue;
                    }

                    if (document.byteOrderMark !== 0 /* None */) {
                        if (printReason) {
                            TypeScript.Environment.standardOut.WriteLine("Emitting byte order mark because of: " + document.fileName);
                            result = true;
                        } else {
                            return true;
                        }
                    }
                }

                return result;
            }
        };

        TypeScriptCompiler.mapToDTSFileName = function (fileName, wholeFileNameReplaced) {
            return TypeScript.getDeclareFilePath(fileName);
        };

        TypeScriptCompiler.prototype._shouldEmit = function (document) {
            return !document.isDeclareFile();
        };

        TypeScriptCompiler.prototype._shouldEmitDeclarations = function (document) {
            if (!this.compilationSettings().generateDeclarationFiles()) {
                return false;
            }

            return this._shouldEmit(document);
        };

        TypeScriptCompiler.prototype.emitDocumentDeclarationsWorker = function (document, emitOptions, declarationEmitter) {
            var sourceUnit = document.sourceUnit();
            TypeScript.Debug.assert(this._shouldEmitDeclarations(document));

            if (declarationEmitter) {
                declarationEmitter.document = document;
            } else {
                var declareFileName = this.mapOutputFileName(document, emitOptions, TypeScriptCompiler.mapToDTSFileName);
                declarationEmitter = new TypeScript.DeclarationEmitter(declareFileName, document, this, emitOptions, this.semanticInfoChain);
            }

            declarationEmitter.emitDeclarations(sourceUnit);
            return declarationEmitter;
        };

        TypeScriptCompiler.prototype._emitDocumentDeclarations = function (document, emitOptions, onSingleFileEmitComplete, sharedEmitter) {
            if (this._shouldEmitDeclarations(document)) {
                if (document.emitToOwnOutputFile()) {
                    var singleEmitter = this.emitDocumentDeclarationsWorker(document, emitOptions);
                    if (singleEmitter) {
                        onSingleFileEmitComplete(singleEmitter.getOutputFile());
                    }
                } else {
                    sharedEmitter = this.emitDocumentDeclarationsWorker(document, emitOptions, sharedEmitter);
                }
            }

            return sharedEmitter;
        };

        TypeScriptCompiler.prototype.emitAllDeclarations = function (resolvePath) {
            var start = new Date().getTime();
            var emitOutput = new EmitOutput();

            var emitOptions = new TypeScript.EmitOptions(this, resolvePath);
            if (emitOptions.diagnostic()) {
                emitOutput.emitOutputResult = 2 /* FailedBecauseOfCompilerOptionsErrors */;
                return emitOutput;
            }

            var sharedEmitter = null;
            var fileNames = this.fileNames();

            for (var i = 0, n = fileNames.length; i < n; i++) {
                var fileName = fileNames[i];

                var document = this.getDocument(fileNames[i]);

                sharedEmitter = this._emitDocumentDeclarations(document, emitOptions, function (file) {
                    return emitOutput.outputFiles.push(file);
                }, sharedEmitter);
            }

            if (sharedEmitter) {
                emitOutput.outputFiles.push(sharedEmitter.getOutputFile());
            }

            TypeScript.declarationEmitTime += new Date().getTime() - start;

            return emitOutput;
        };

        TypeScriptCompiler.prototype.emitDeclarations = function (fileName, resolvePath) {
            fileName = TypeScript.switchToForwardSlashes(fileName);
            var emitOutput = new EmitOutput();

            var emitOptions = new TypeScript.EmitOptions(this, resolvePath);
            if (emitOptions.diagnostic()) {
                emitOutput.emitOutputResult = 2 /* FailedBecauseOfCompilerOptionsErrors */;
                return emitOutput;
            }

            var document = this.getDocument(fileName);

            if (document.emitToOwnOutputFile()) {
                this._emitDocumentDeclarations(document, emitOptions, function (file) {
                    return emitOutput.outputFiles.push(file);
                }, null);
                return emitOutput;
            } else {
                return this.emitAllDeclarations(resolvePath);
            }
        };

        TypeScriptCompiler.prototype.canEmitDeclarations = function (fileName) {
            fileName = TypeScript.switchToForwardSlashes(fileName);
            var document = this.getDocument(fileName);
            return this._shouldEmitDeclarations(document);
        };

        TypeScriptCompiler.mapToFileNameExtension = function (extension, fileName, wholeFileNameReplaced) {
            if (wholeFileNameReplaced) {
                return fileName;
            } else {
                var splitFname = fileName.split(".");
                splitFname.pop();
                return splitFname.join(".") + extension;
            }
        };

        TypeScriptCompiler.mapToJSFileName = function (fileName, wholeFileNameReplaced) {
            return TypeScriptCompiler.mapToFileNameExtension(".js", fileName, wholeFileNameReplaced);
        };

        TypeScriptCompiler.prototype.emitDocumentWorker = function (document, emitOptions, emitter) {
            var sourceUnit = document.sourceUnit();
            TypeScript.Debug.assert(this._shouldEmit(document));

            var typeScriptFileName = document.fileName;
            if (!emitter) {
                var javaScriptFileName = this.mapOutputFileName(document, emitOptions, TypeScriptCompiler.mapToJSFileName);
                var outFile = new TypeScript.TextWriter(javaScriptFileName, this.writeByteOrderMarkForDocument(document), 0 /* JavaScript */);

                emitter = new TypeScript.Emitter(javaScriptFileName, outFile, emitOptions, this.semanticInfoChain);

                if (this.compilationSettings().mapSourceFiles()) {
                    var sourceMapFile = new TypeScript.TextWriter(javaScriptFileName + TypeScript.SourceMapper.MapFileExtension, false, 1 /* SourceMap */);
                    emitter.createSourceMapper(document, javaScriptFileName, outFile, sourceMapFile, emitOptions.resolvePath);
                }
            } else if (this.compilationSettings().mapSourceFiles()) {
                emitter.setSourceMapperNewSourceFile(document);
            }

            emitter.setDocument(document);
            emitter.emitJavascript(sourceUnit, false);

            return emitter;
        };

        TypeScriptCompiler.prototype._emitDocument = function (document, emitOptions, onSingleFileEmitComplete, sharedEmitter) {
            if (this._shouldEmit(document)) {
                if (document.emitToOwnOutputFile()) {
                    var singleEmitter = this.emitDocumentWorker(document, emitOptions);
                    if (singleEmitter) {
                        onSingleFileEmitComplete(singleEmitter.getOutputFiles());
                    }
                } else {
                    sharedEmitter = this.emitDocumentWorker(document, emitOptions, sharedEmitter);
                }
            }

            return sharedEmitter;
        };

        TypeScriptCompiler.prototype.emitAll = function (resolvePath) {
            var start = new Date().getTime();
            var emitOutput = new EmitOutput();

            var emitOptions = new TypeScript.EmitOptions(this, resolvePath);
            if (emitOptions.diagnostic()) {
                emitOutput.emitOutputResult = 2 /* FailedBecauseOfCompilerOptionsErrors */;
                return emitOutput;
            }

            var fileNames = this.fileNames();
            var sharedEmitter = null;

            for (var i = 0, n = fileNames.length; i < n; i++) {
                var fileName = fileNames[i];

                var document = this.getDocument(fileName);

                sharedEmitter = this._emitDocument(document, emitOptions, function (files) {
                    return emitOutput.outputFiles.push.apply(emitOutput.outputFiles, files);
                }, sharedEmitter);
            }

            if (sharedEmitter) {
                emitOutput.outputFiles.push.apply(emitOutput.outputFiles, sharedEmitter.getOutputFiles());
            }

            TypeScript.emitTime += new Date().getTime() - start;
            return emitOutput;
        };

        TypeScriptCompiler.prototype.emit = function (fileName, resolvePath) {
            fileName = TypeScript.switchToForwardSlashes(fileName);
            var emitOutput = new EmitOutput();

            var emitOptions = new TypeScript.EmitOptions(this, resolvePath);
            if (emitOptions.diagnostic()) {
                emitOutput.emitOutputResult = 2 /* FailedBecauseOfCompilerOptionsErrors */;
                return emitOutput;
            }

            var document = this.getDocument(fileName);

            if (document.emitToOwnOutputFile()) {
                this._emitDocument(document, emitOptions, function (files) {
                    return emitOutput.outputFiles.push.apply(emitOutput.outputFiles, files);
                }, null);
                return emitOutput;
            } else {
                return this.emitAll(resolvePath);
            }
        };

        TypeScriptCompiler.prototype.compile = function (resolvePath, continueOnDiagnostics) {
            if (typeof continueOnDiagnostics === "undefined") { continueOnDiagnostics = false; }
            return new CompilerIterator(this, resolvePath, continueOnDiagnostics);
        };

        TypeScriptCompiler.prototype.getSyntacticDiagnostics = function (fileName) {
            fileName = TypeScript.switchToForwardSlashes(fileName);
            return this.getDocument(fileName).diagnostics();
        };

        TypeScriptCompiler.prototype.getSyntaxTree = function (fileName) {
            return this.getDocument(fileName).syntaxTree();
        };

        TypeScriptCompiler.prototype.getSourceUnit = function (fileName) {
            return this.getDocument(fileName).sourceUnit();
        };

        TypeScriptCompiler.prototype.getSemanticDiagnostics = function (fileName) {
            fileName = TypeScript.switchToForwardSlashes(fileName);

            var document = this.getDocument(fileName);

            var startTime = (new Date()).getTime();
            TypeScript.PullTypeResolver.typeCheck(this.compilationSettings(), this.semanticInfoChain, document);
            var endTime = (new Date()).getTime();

            TypeScript.typeCheckTime += endTime - startTime;

            var errors = this.semanticInfoChain.getDiagnostics(fileName);

            errors = TypeScript.ArrayUtilities.distinct(errors, TypeScript.Diagnostic.equals);
            errors.sort(function (d1, d2) {
                if (d1.fileName() < d2.fileName()) {
                    return -1;
                } else if (d1.fileName() > d2.fileName()) {
                    return 1;
                }

                if (d1.start() < d2.start()) {
                    return -1;
                } else if (d1.start() > d2.start()) {
                    return 1;
                }

                var code1 = TypeScript.diagnosticInformationMap[d1.diagnosticKey()].code;
                var code2 = TypeScript.diagnosticInformationMap[d2.diagnosticKey()].code;
                if (code1 < code2) {
                    return -1;
                } else if (code1 > code2) {
                    return 1;
                }

                return 0;
            });

            return errors;
        };

        TypeScriptCompiler.prototype.getCompilerOptionsDiagnostics = function (resolvePath) {
            var emitOptions = new TypeScript.EmitOptions(this, resolvePath);
            var emitDiagnostic = emitOptions.diagnostic();
            if (emitDiagnostic) {
                return [emitDiagnostic];
            }
            return TypeScript.sentinelEmptyArray;
        };

        TypeScriptCompiler.prototype.resolveAllFiles = function () {
            var fileNames = this.fileNames();
            for (var i = 0, n = fileNames.length; i < n; i++) {
                this.getSemanticDiagnostics(fileNames[i]);
            }
        };

        TypeScriptCompiler.prototype.getSymbolOfDeclaration = function (decl) {
            if (!decl) {
                return null;
            }

            var resolver = this.semanticInfoChain.getResolver();
            var ast = this.semanticInfoChain.getASTForDecl(decl);
            if (!ast) {
                return null;
            }

            var enclosingDecl = resolver.getEnclosingDecl(decl);
            if (ast.kind() === 139 /* GetAccessor */ || ast.kind() === 140 /* SetAccessor */) {
                return this.getSymbolOfDeclaration(enclosingDecl);
            }

            return resolver.resolveAST(ast, false, new TypeScript.PullTypeResolutionContext(resolver));
        };

        TypeScriptCompiler.prototype.extractResolutionContextFromAST = function (resolver, ast, document, propagateContextualTypes) {
            var scriptName = document.fileName;

            var enclosingDecl = null;
            var enclosingDeclAST = null;
            var inContextuallyTypedAssignment = false;
            var inWithBlock = false;

            var resolutionContext = new TypeScript.PullTypeResolutionContext(resolver);

            if (!ast) {
                return null;
            }

            var path = this.getASTPath(ast);

            for (var i = 0, n = path.length; i < n; i++) {
                var current = path[i];

                switch (current.kind()) {
                    case 222 /* FunctionExpression */:
                    case 219 /* SimpleArrowFunctionExpression */:
                    case 218 /* ParenthesizedArrowFunctionExpression */:
                        if (propagateContextualTypes) {
                            resolver.resolveAST(current, true, resolutionContext);
                        }
                        break;

                    case 136 /* MemberVariableDeclaration */:
                        var memberVariable = current;
                        inContextuallyTypedAssignment = memberVariable.variableDeclarator.typeAnnotation !== null;

                        this.extractResolutionContextForVariable(inContextuallyTypedAssignment, propagateContextualTypes, resolver, resolutionContext, enclosingDecl, memberVariable, memberVariable.variableDeclarator.equalsValueClause);
                        break;

                    case 225 /* VariableDeclarator */:
                        var variableDeclarator = current;
                        inContextuallyTypedAssignment = variableDeclarator.typeAnnotation !== null;

                        this.extractResolutionContextForVariable(inContextuallyTypedAssignment, propagateContextualTypes, resolver, resolutionContext, enclosingDecl, variableDeclarator, variableDeclarator.equalsValueClause);
                        break;

                    case 213 /* InvocationExpression */:
                    case 216 /* ObjectCreationExpression */:
                        if (propagateContextualTypes) {
                            var isNew = current.kind() === 216 /* ObjectCreationExpression */;
                            var callExpression = current;
                            var contextualType = null;

                            if ((i + 2 < n) && callExpression.argumentList === path[i + 1] && callExpression.argumentList.arguments === path[i + 2]) {
                                var callResolutionResults = new TypeScript.PullAdditionalCallResolutionData();
                                if (isNew) {
                                    resolver.resolveObjectCreationExpression(callExpression, resolutionContext, callResolutionResults);
                                } else {
                                    resolver.resolveInvocationExpression(callExpression, resolutionContext, callResolutionResults);
                                }

                                if (callResolutionResults.actualParametersContextTypeSymbols) {
                                    var argExpression = path[i + 3];
                                    if (argExpression) {
                                        for (var j = 0, m = callExpression.argumentList.arguments.nonSeparatorCount(); j < m; j++) {
                                            if (callExpression.argumentList.arguments.nonSeparatorAt(j) === argExpression) {
                                                var callContextualType = callResolutionResults.actualParametersContextTypeSymbols[j];
                                                if (callContextualType) {
                                                    contextualType = callContextualType;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                if (isNew) {
                                    resolver.resolveObjectCreationExpression(callExpression, resolutionContext);
                                } else {
                                    resolver.resolveInvocationExpression(callExpression, resolutionContext);
                                }
                            }

                            resolutionContext.pushNewContextualType(contextualType);
                        }

                        break;

                    case 214 /* ArrayLiteralExpression */:
                        if (propagateContextualTypes) {
                            var contextualType = null;
                            var currentContextualType = resolutionContext.getContextualType();
                            if (currentContextualType && currentContextualType.isArrayNamedTypeReference()) {
                                contextualType = currentContextualType.getElementType();
                            }

                            resolutionContext.pushNewContextualType(contextualType);
                        }

                        break;

                    case 215 /* ObjectLiteralExpression */:
                        if (propagateContextualTypes) {
                            var objectLiteralExpression = current;
                            var objectLiteralResolutionContext = new TypeScript.PullAdditionalObjectLiteralResolutionData();
                            resolver.resolveObjectLiteralExpression(objectLiteralExpression, inContextuallyTypedAssignment, resolutionContext, objectLiteralResolutionContext);

                            var memeberAST = (path[i + 1] && path[i + 1].kind() === 2 /* SeparatedList */) ? path[i + 2] : path[i + 1];
                            if (memeberAST) {
                                var contextualType = null;
                                var memberDecls = objectLiteralExpression.propertyAssignments;
                                if (memberDecls && objectLiteralResolutionContext.membersContextTypeSymbols) {
                                    for (var j = 0, m = memberDecls.nonSeparatorCount(); j < m; j++) {
                                        if (memberDecls.nonSeparatorAt(j) === memeberAST) {
                                            var memberContextualType = objectLiteralResolutionContext.membersContextTypeSymbols[j];
                                            if (memberContextualType) {
                                                contextualType = memberContextualType;
                                                break;
                                            }
                                        }
                                    }
                                }

                                resolutionContext.pushNewContextualType(contextualType);
                            }
                        }

                        break;

                    case 174 /* AssignmentExpression */:
                        if (propagateContextualTypes) {
                            var assignmentExpression = current;
                            var contextualType = null;

                            if (path[i + 1] && path[i + 1] === assignmentExpression.right) {
                                var leftType = resolver.resolveAST(assignmentExpression.left, inContextuallyTypedAssignment, resolutionContext).type;
                                if (leftType) {
                                    inContextuallyTypedAssignment = true;
                                    contextualType = leftType;
                                }
                            }

                            resolutionContext.pushNewContextualType(contextualType);
                        }

                        break;

                    case 220 /* CastExpression */:
                        var castExpression = current;
                        if (!(i + 1 < n && path[i + 1] === castExpression.type)) {
                            if (propagateContextualTypes) {
                                var contextualType = null;
                                var typeSymbol = resolver.resolveAST(castExpression, inContextuallyTypedAssignment, resolutionContext).type;

                                if (typeSymbol) {
                                    inContextuallyTypedAssignment = true;
                                    contextualType = typeSymbol;
                                }

                                resolutionContext.pushNewContextualType(contextualType);
                            }
                        }

                        break;

                    case 150 /* ReturnStatement */:
                        if (propagateContextualTypes) {
                            var returnStatement = current;
                            var contextualType = null;

                            if (enclosingDecl && (enclosingDecl.kind & 1032192 /* SomeFunction */)) {
                                var typeAnnotation = TypeScript.ASTHelpers.getType(enclosingDeclAST);
                                if (typeAnnotation) {
                                    var returnTypeSymbol = resolver.resolveTypeReference(typeAnnotation, resolutionContext);
                                    if (returnTypeSymbol) {
                                        inContextuallyTypedAssignment = true;
                                        contextualType = returnTypeSymbol;
                                    }
                                } else {
                                    var currentContextualType = resolutionContext.getContextualType();
                                    if (currentContextualType && currentContextualType.isFunction()) {
                                        var contextualSignatures = currentContextualType.kind == 33554432 /* ConstructorType */ ? currentContextualType.getConstructSignatures() : currentContextualType.getCallSignatures();
                                        var currentContextualTypeSignatureSymbol = contextualSignatures[0];
                                        var currentContextualTypeReturnTypeSymbol = currentContextualTypeSignatureSymbol.returnType;
                                        if (currentContextualTypeReturnTypeSymbol) {
                                            inContextuallyTypedAssignment = true;
                                            contextualType = currentContextualTypeReturnTypeSymbol;
                                        }
                                    }
                                }
                            }

                            resolutionContext.pushNewContextualType(contextualType);
                        }

                        break;

                    case 122 /* ObjectType */:
                        if (propagateContextualTypes && TypeScript.isTypesOnlyLocation(current)) {
                            resolver.resolveAST(current, false, resolutionContext);
                        }

                        break;

                    case 163 /* WithStatement */:
                        inWithBlock = true;
                        break;

                    case 146 /* Block */:
                        inContextuallyTypedAssignment = false;
                        break;
                }

                var decl = this.semanticInfoChain.getDeclForAST(current);
                if (decl) {
                    enclosingDecl = decl;
                    enclosingDeclAST = current;
                }
            }

            if (ast && ast.parent && ast.kind() === 11 /* IdentifierName */) {
                if (ast.parent.kind() === 212 /* MemberAccessExpression */) {
                    if (ast.parent.name === ast) {
                        ast = ast.parent;
                    }
                } else if (ast.parent.kind() === 121 /* QualifiedName */) {
                    if (ast.parent.right === ast) {
                        ast = ast.parent;
                    }
                }
            }

            return {
                ast: ast,
                enclosingDecl: enclosingDecl,
                resolutionContext: resolutionContext,
                inContextuallyTypedAssignment: inContextuallyTypedAssignment,
                inWithBlock: inWithBlock
            };
        };

        TypeScriptCompiler.prototype.extractResolutionContextForVariable = function (inContextuallyTypedAssignment, propagateContextualTypes, resolver, resolutionContext, enclosingDecl, assigningAST, init) {
            if (inContextuallyTypedAssignment) {
                if (propagateContextualTypes) {
                    resolver.resolveAST(assigningAST, false, resolutionContext);
                    var varSymbol = this.semanticInfoChain.getSymbolForAST(assigningAST);

                    var contextualType = null;
                    if (varSymbol && inContextuallyTypedAssignment) {
                        contextualType = varSymbol.type;
                    }

                    resolutionContext.pushNewContextualType(contextualType);

                    if (init) {
                        resolver.resolveAST(init, inContextuallyTypedAssignment, resolutionContext);
                    }
                }
            }
        };

        TypeScriptCompiler.prototype.getASTPath = function (ast) {
            var result = [];

            while (ast) {
                result.unshift(ast);
                ast = ast.parent;
            }

            return result;
        };

        TypeScriptCompiler.prototype.pullGetSymbolInformationFromAST = function (ast, document) {
            var resolver = this.semanticInfoChain.getResolver();
            var context = this.extractResolutionContextFromAST(resolver, ast, document, true);
            if (!context || context.inWithBlock) {
                return null;
            }

            ast = context.ast;
            var symbol = resolver.resolveAST(ast, context.inContextuallyTypedAssignment, context.resolutionContext);

            if (!symbol) {
                TypeScript.Debug.assert(ast.kind() === 120 /* SourceUnit */, "No symbol was found for ast and ast was not source unit. Ast Kind: " + TypeScript.SyntaxKind[ast.kind()]);
                return null;
            }

            if (symbol.isTypeReference()) {
                symbol = symbol.getReferencedTypeSymbol();
            }

            var aliasSymbol = this.semanticInfoChain.getAliasSymbolForAST(ast);

            return {
                symbol: symbol,
                aliasSymbol: aliasSymbol,
                ast: ast,
                enclosingScopeSymbol: this.getSymbolOfDeclaration(context.enclosingDecl)
            };
        };

        TypeScriptCompiler.prototype.pullGetCallInformationFromAST = function (ast, document) {
            if (ast.kind() !== 213 /* InvocationExpression */ && ast.kind() !== 216 /* ObjectCreationExpression */) {
                return null;
            }

            var isNew = ast.kind() === 216 /* ObjectCreationExpression */;

            var resolver = this.semanticInfoChain.getResolver();
            var context = this.extractResolutionContextFromAST(resolver, ast, document, true);
            if (!context || context.inWithBlock) {
                return null;
            }

            var callResolutionResults = new TypeScript.PullAdditionalCallResolutionData();

            if (isNew) {
                resolver.resolveObjectCreationExpression(ast, context.resolutionContext, callResolutionResults);
            } else {
                resolver.resolveInvocationExpression(ast, context.resolutionContext, callResolutionResults);
            }

            return {
                targetSymbol: callResolutionResults.targetSymbol,
                resolvedSignatures: callResolutionResults.resolvedSignatures,
                candidateSignature: callResolutionResults.candidateSignature,
                ast: ast,
                enclosingScopeSymbol: this.getSymbolOfDeclaration(context.enclosingDecl),
                isConstructorCall: isNew
            };
        };

        TypeScriptCompiler.prototype.pullGetVisibleMemberSymbolsFromAST = function (ast, document) {
            var resolver = this.semanticInfoChain.getResolver();
            var context = this.extractResolutionContextFromAST(resolver, ast, document, true);
            if (!context || context.inWithBlock) {
                return null;
            }

            var symbols = resolver.getVisibleMembersFromExpression(ast, context.enclosingDecl, context.resolutionContext);
            if (!symbols) {
                return null;
            }

            return {
                symbols: symbols,
                enclosingScopeSymbol: this.getSymbolOfDeclaration(context.enclosingDecl)
            };
        };

        TypeScriptCompiler.prototype.pullGetVisibleDeclsFromAST = function (ast, document) {
            var resolver = this.semanticInfoChain.getResolver();
            var context = this.extractResolutionContextFromAST(resolver, ast, document, false);
            if (!context || context.inWithBlock) {
                return null;
            }

            return resolver.getVisibleDecls(context.enclosingDecl);
        };

        TypeScriptCompiler.prototype.pullGetContextualMembersFromAST = function (ast, document) {
            if (ast.kind() !== 215 /* ObjectLiteralExpression */) {
                return null;
            }

            var resolver = this.semanticInfoChain.getResolver();
            var context = this.extractResolutionContextFromAST(resolver, ast, document, true);
            if (!context || context.inWithBlock) {
                return null;
            }

            var members = resolver.getVisibleContextSymbols(context.enclosingDecl, context.resolutionContext);

            return {
                symbols: members,
                enclosingScopeSymbol: this.getSymbolOfDeclaration(context.enclosingDecl)
            };
        };

        TypeScriptCompiler.prototype.pullGetDeclInformation = function (decl, ast, document) {
            var resolver = this.semanticInfoChain.getResolver();

            var context = this.extractResolutionContextFromAST(resolver, ast, document, true);
            if (!context || context.inWithBlock) {
                return null;
            }

            var astForDecl = decl.ast();
            if (!astForDecl) {
                return null;
            }

            var astForDeclContext = this.extractResolutionContextFromAST(resolver, astForDecl, this.getDocument(astForDecl.fileName()), true);
            if (!astForDeclContext) {
                return null;
            }

            var symbol = decl.getSymbol();
            resolver.resolveDeclaredSymbol(symbol, context.resolutionContext);
            symbol.setUnresolved();

            return {
                symbol: symbol,
                aliasSymbol: null,
                ast: ast,
                enclosingScopeSymbol: this.getSymbolOfDeclaration(context.enclosingDecl)
            };
        };

        TypeScriptCompiler.prototype.topLevelDeclaration = function (fileName) {
            return this.semanticInfoChain.topLevelDecl(fileName);
        };

        TypeScriptCompiler.prototype.getDeclForAST = function (ast) {
            return this.semanticInfoChain.getDeclForAST(ast);
        };

        TypeScriptCompiler.prototype.fileNames = function () {
            return this.semanticInfoChain.fileNames();
        };

        TypeScriptCompiler.prototype.topLevelDecl = function (fileName) {
            return this.semanticInfoChain.topLevelDecl(fileName);
        };

        TypeScriptCompiler.getLocationText = function (location, resolvePath) {
            return resolvePath(location.fileName()) + "(" + (location.line() + 1) + "," + (location.character() + 1) + ")";
        };

        TypeScriptCompiler.getFullDiagnosticText = function (diagnostic, resolvePath) {
            var result = "";
            if (diagnostic.fileName()) {
                result += this.getLocationText(diagnostic, resolvePath) + ": ";
            }

            result += diagnostic.message();

            var additionalLocations = diagnostic.additionalLocations();
            if (additionalLocations.length > 0) {
                result += " " + TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Additional_locations, null) + TypeScript.Environment.newLine;

                for (var i = 0, n = additionalLocations.length; i < n; i++) {
                    result += "\t" + this.getLocationText(additionalLocations[i], resolvePath) + TypeScript.Environment.newLine;
                }
            } else {
                result += TypeScript.Environment.newLine;
            }

            return result;
        };
        return TypeScriptCompiler;
    })();
    TypeScript.TypeScriptCompiler = TypeScriptCompiler;

    var CompilerPhase;
    (function (CompilerPhase) {
        CompilerPhase[CompilerPhase["Syntax"] = 0] = "Syntax";
        CompilerPhase[CompilerPhase["Semantics"] = 1] = "Semantics";
        CompilerPhase[CompilerPhase["EmitOptionsValidation"] = 2] = "EmitOptionsValidation";
        CompilerPhase[CompilerPhase["Emit"] = 3] = "Emit";
        CompilerPhase[CompilerPhase["DeclarationEmit"] = 4] = "DeclarationEmit";
    })(CompilerPhase || (CompilerPhase = {}));

    var CompilerIterator = (function () {
        function CompilerIterator(compiler, resolvePath, continueOnDiagnostics, startingPhase) {
            if (typeof startingPhase === "undefined") { startingPhase = 0 /* Syntax */; }
            this.compiler = compiler;
            this.resolvePath = resolvePath;
            this.continueOnDiagnostics = continueOnDiagnostics;
            this.index = -1;
            this.fileNames = null;
            this._current = null;
            this._emitOptions = null;
            this._sharedEmitter = null;
            this._sharedDeclarationEmitter = null;
            this.hadSyntacticDiagnostics = false;
            this.hadSemanticDiagnostics = false;
            this.hadEmitDiagnostics = false;
            this.fileNames = compiler.fileNames();
            this.compilerPhase = startingPhase;
        }
        CompilerIterator.prototype.current = function () {
            return this._current;
        };

        CompilerIterator.prototype.moveNext = function () {
            this._current = null;

            while (this.moveNextInternal()) {
                if (this._current) {
                    return true;
                }
            }

            return false;
        };

        CompilerIterator.prototype.moveNextInternal = function () {
            this.index++;

            while (this.shouldMoveToNextPhase()) {
                this.index = 0;
                this.compilerPhase++;
            }

            if (this.compilerPhase > 4 /* DeclarationEmit */) {
                return false;
            }

            switch (this.compilerPhase) {
                case 0 /* Syntax */:
                    return this.moveNextSyntaxPhase();
                case 1 /* Semantics */:
                    return this.moveNextSemanticsPhase();
                case 2 /* EmitOptionsValidation */:
                    return this.moveNextEmitOptionsValidationPhase();
                case 3 /* Emit */:
                    return this.moveNextEmitPhase();
                case 4 /* DeclarationEmit */:
                    return this.moveNextDeclarationEmitPhase();
            }
        };

        CompilerIterator.prototype.shouldMoveToNextPhase = function () {
            switch (this.compilerPhase) {
                case 2 /* EmitOptionsValidation */:
                    return this.index === 1;

                case 0 /* Syntax */:
                case 1 /* Semantics */:
                    return this.index === this.fileNames.length;

                case 3 /* Emit */:
                case 4 /* DeclarationEmit */:
                    return this.index === (this.fileNames.length + 1);
            }

            return false;
        };

        CompilerIterator.prototype.moveNextSyntaxPhase = function () {
            TypeScript.Debug.assert(this.index >= 0 && this.index < this.fileNames.length);
            var fileName = this.fileNames[this.index];

            var diagnostics = this.compiler.getSyntacticDiagnostics(fileName);
            if (diagnostics.length) {
                if (!this.continueOnDiagnostics) {
                    this.hadSyntacticDiagnostics = true;
                }

                this._current = CompileResult.fromDiagnostics(diagnostics);
            }

            return true;
        };

        CompilerIterator.prototype.moveNextSemanticsPhase = function () {
            if (this.hadSyntacticDiagnostics) {
                return false;
            }

            TypeScript.Debug.assert(this.index >= 0 && this.index < this.fileNames.length);
            var fileName = this.fileNames[this.index];
            var diagnostics = this.compiler.getSemanticDiagnostics(fileName);
            if (diagnostics.length) {
                if (!this.continueOnDiagnostics) {
                    this.hadSemanticDiagnostics = true;
                }

                this._current = CompileResult.fromDiagnostics(diagnostics);
            }

            return true;
        };

        CompilerIterator.prototype.moveNextEmitOptionsValidationPhase = function () {
            TypeScript.Debug.assert(!this.hadSyntacticDiagnostics);

            if (!this._emitOptions) {
                this._emitOptions = new TypeScript.EmitOptions(this.compiler, this.resolvePath);
            }

            if (this._emitOptions.diagnostic()) {
                if (!this.continueOnDiagnostics) {
                    this.hadEmitDiagnostics = true;
                }

                this._current = CompileResult.fromDiagnostics([this._emitOptions.diagnostic()]);
            }

            return true;
        };

        CompilerIterator.prototype.moveNextEmitPhase = function () {
            var _this = this;
            TypeScript.Debug.assert(!this.hadSyntacticDiagnostics);
            TypeScript.Debug.assert(this._emitOptions);

            if (this.hadEmitDiagnostics) {
                return false;
            }

            TypeScript.Debug.assert(this.index >= 0 && this.index <= this.fileNames.length);
            if (this.index < this.fileNames.length) {
                var fileName = this.fileNames[this.index];
                var document = this.compiler.getDocument(fileName);

                this._sharedEmitter = this.compiler._emitDocument(document, this._emitOptions, function (outputFiles) {
                    _this._current = CompileResult.fromOutputFiles(outputFiles);
                }, this._sharedEmitter);
                return true;
            }

            if (this.index === this.fileNames.length && this._sharedEmitter) {
                this._current = CompileResult.fromOutputFiles(this._sharedEmitter.getOutputFiles());
            }

            return true;
        };

        CompilerIterator.prototype.moveNextDeclarationEmitPhase = function () {
            var _this = this;
            TypeScript.Debug.assert(!this.hadSyntacticDiagnostics);
            TypeScript.Debug.assert(!this.hadEmitDiagnostics);
            if (this.hadSemanticDiagnostics) {
                return false;
            }

            if (!this.compiler.compilationSettings().generateDeclarationFiles()) {
                return false;
            }

            TypeScript.Debug.assert(this.index >= 0 && this.index <= this.fileNames.length);
            if (this.index < this.fileNames.length) {
                var fileName = this.fileNames[this.index];
                var document = this.compiler.getDocument(fileName);

                this._sharedDeclarationEmitter = this.compiler._emitDocumentDeclarations(document, this._emitOptions, function (file) {
                    _this._current = CompileResult.fromOutputFiles([file]);
                }, this._sharedDeclarationEmitter);
                return true;
            }

            if (this.index === this.fileNames.length && this._sharedDeclarationEmitter) {
                this._current = CompileResult.fromOutputFiles([this._sharedDeclarationEmitter.getOutputFile()]);
            }

            return true;
        };
        return CompilerIterator;
    })();

    function compareDataObjects(dst, src) {
        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;
    }
    TypeScript.compareDataObjects = compareDataObjects;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (GenerativeTypeClassification) {
        GenerativeTypeClassification[GenerativeTypeClassification["Unknown"] = 0] = "Unknown";
        GenerativeTypeClassification[GenerativeTypeClassification["Open"] = 1] = "Open";
        GenerativeTypeClassification[GenerativeTypeClassification["Closed"] = 2] = "Closed";
        GenerativeTypeClassification[GenerativeTypeClassification["InfinitelyExpanding"] = 3] = "InfinitelyExpanding";
    })(TypeScript.GenerativeTypeClassification || (TypeScript.GenerativeTypeClassification = {}));
    var GenerativeTypeClassification = TypeScript.GenerativeTypeClassification;

    var PullTypeReferenceSymbol = (function (_super) {
        __extends(PullTypeReferenceSymbol, _super);
        function PullTypeReferenceSymbol(referencedTypeSymbol) {
            _super.call(this, referencedTypeSymbol.name, referencedTypeSymbol.kind);
            this.referencedTypeSymbol = referencedTypeSymbol;
            this.isResolved = true;

            TypeScript.Debug.assert(referencedTypeSymbol !== null, "Type root symbol may not be null");

            this.setRootSymbol(referencedTypeSymbol);

            this.typeReference = this;
        }
        PullTypeReferenceSymbol.createTypeReference = function (type) {
            if (type.isTypeReference()) {
                return type;
            }

            var typeReference = type.typeReference;

            if (!typeReference) {
                typeReference = new PullTypeReferenceSymbol(type);
                type.typeReference = typeReference;
            }

            return typeReference;
        };

        PullTypeReferenceSymbol.prototype.isTypeReference = function () {
            return true;
        };

        PullTypeReferenceSymbol.prototype.setResolved = function () {
        };

        PullTypeReferenceSymbol.prototype.setUnresolved = function () {
        };
        PullTypeReferenceSymbol.prototype.invalidate = function () {
        };

        PullTypeReferenceSymbol.prototype.ensureReferencedTypeIsResolved = function () {
            this._getResolver().resolveDeclaredSymbol(this.referencedTypeSymbol);
        };

        PullTypeReferenceSymbol.prototype.getReferencedTypeSymbol = function () {
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol;
        };

        PullTypeReferenceSymbol.prototype._getResolver = function () {
            return this.referencedTypeSymbol._getResolver();
        };

        PullTypeReferenceSymbol.prototype.hasMembers = function () {
            return this.referencedTypeSymbol.hasMembers();
        };

        PullTypeReferenceSymbol.prototype.setAssociatedContainerType = function (type) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": setAssociatedContainerType");
        };

        PullTypeReferenceSymbol.prototype.getAssociatedContainerType = function () {
            return this.referencedTypeSymbol.getAssociatedContainerType();
        };

        PullTypeReferenceSymbol.prototype.getFunctionSymbol = function () {
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.getFunctionSymbol();
        };
        PullTypeReferenceSymbol.prototype.setFunctionSymbol = function (symbol) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": setFunctionSymbol");
        };

        PullTypeReferenceSymbol.prototype.addContainedNonMember = function (nonMember) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addContainedNonMember");
        };
        PullTypeReferenceSymbol.prototype.findContainedNonMemberContainer = function (containerName, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.findContainedNonMemberContainer(containerName, kind);
        };

        PullTypeReferenceSymbol.prototype.addMember = function (memberSymbol) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addMember");
        };
        PullTypeReferenceSymbol.prototype.addEnclosedMemberType = function (enclosedType) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addEnclosedMemberType");
        };
        PullTypeReferenceSymbol.prototype.addEnclosedMemberContainer = function (enclosedContainer) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addEnclosedMemberContainer");
        };
        PullTypeReferenceSymbol.prototype.addEnclosedNonMember = function (enclosedNonMember) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addEnclosedNonMember");
        };
        PullTypeReferenceSymbol.prototype.addEnclosedNonMemberType = function (enclosedNonMemberType) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addEnclosedNonMemberType");
        };
        PullTypeReferenceSymbol.prototype.addEnclosedNonMemberContainer = function (enclosedNonMemberContainer) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addEnclosedNonMemberContainer");
        };
        PullTypeReferenceSymbol.prototype.addTypeParameter = function (typeParameter) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addTypeParameter");
        };
        PullTypeReferenceSymbol.prototype.addConstructorTypeParameter = function (typeParameter) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addConstructorTypeParameter");
        };

        PullTypeReferenceSymbol.prototype.findContainedNonMember = function (name) {
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.findContainedNonMember(name);
        };

        PullTypeReferenceSymbol.prototype.findContainedNonMemberType = function (typeName, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.findContainedNonMemberType(typeName, kind);
        };

        PullTypeReferenceSymbol.prototype.getMembers = function () {
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.getMembers();
        };

        PullTypeReferenceSymbol.prototype.setHasDefaultConstructor = function (hasOne) {
            if (typeof hasOne === "undefined") { hasOne = true; }
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ":setHasDefaultConstructor");
        };
        PullTypeReferenceSymbol.prototype.getHasDefaultConstructor = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getHasDefaultConstructor();
        };
        PullTypeReferenceSymbol.prototype.getConstructorMethod = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getConstructorMethod();
        };
        PullTypeReferenceSymbol.prototype.setConstructorMethod = function (constructorMethod) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": setConstructorMethod");
        };
        PullTypeReferenceSymbol.prototype.getTypeParameters = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getTypeParameters();
        };

        PullTypeReferenceSymbol.prototype.isGeneric = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.isGeneric();
        };

        PullTypeReferenceSymbol.prototype.addSpecialization = function (specializedVersionOfThisType, substitutingTypes) {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.addSpecialization(specializedVersionOfThisType, substitutingTypes);
        };
        PullTypeReferenceSymbol.prototype.getSpecialization = function (substitutingTypes) {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getSpecialization(substitutingTypes);
        };
        PullTypeReferenceSymbol.prototype.getKnownSpecializations = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getKnownSpecializations();
        };
        PullTypeReferenceSymbol.prototype.getTypeArguments = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getTypeArguments();
        };
        PullTypeReferenceSymbol.prototype.getTypeArgumentsOrTypeParameters = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getTypeArgumentsOrTypeParameters();
        };

        PullTypeReferenceSymbol.prototype.appendCallSignature = function (callSignature) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": appendCallSignature");
        };
        PullTypeReferenceSymbol.prototype.insertCallSignatureAtIndex = function (callSignature, index) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": insertCallSignatureAtIndex");
        };
        PullTypeReferenceSymbol.prototype.appendConstructSignature = function (callSignature) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": appendConstructSignature");
        };
        PullTypeReferenceSymbol.prototype.insertConstructSignatureAtIndex = function (callSignature, index) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": insertConstructSignatureAtIndex");
        };
        PullTypeReferenceSymbol.prototype.addIndexSignature = function (indexSignature) {
            TypeScript.Debug.fail("Reference symbol " + this.pullSymbolID + ": addIndexSignature");
        };

        PullTypeReferenceSymbol.prototype.hasOwnCallSignatures = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.hasOwnCallSignatures();
        };
        PullTypeReferenceSymbol.prototype.getCallSignatures = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getCallSignatures();
        };
        PullTypeReferenceSymbol.prototype.hasOwnConstructSignatures = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.hasOwnConstructSignatures();
        };
        PullTypeReferenceSymbol.prototype.getConstructSignatures = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getConstructSignatures();
        };
        PullTypeReferenceSymbol.prototype.hasOwnIndexSignatures = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.hasOwnIndexSignatures();
        };
        PullTypeReferenceSymbol.prototype.getIndexSignatures = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getIndexSignatures();
        };

        PullTypeReferenceSymbol.prototype.addImplementedType = function (implementedType) {
            this.referencedTypeSymbol.addImplementedType(implementedType);
        };
        PullTypeReferenceSymbol.prototype.getImplementedTypes = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getImplementedTypes();
        };
        PullTypeReferenceSymbol.prototype.addExtendedType = function (extendedType) {
            this.referencedTypeSymbol.addExtendedType(extendedType);
        };
        PullTypeReferenceSymbol.prototype.getExtendedTypes = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getExtendedTypes();
        };
        PullTypeReferenceSymbol.prototype.addTypeThatExtendsThisType = function (type) {
            this.referencedTypeSymbol.addTypeThatExtendsThisType(type);
        };
        PullTypeReferenceSymbol.prototype.getTypesThatExtendThisType = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getTypesThatExtendThisType();
        };
        PullTypeReferenceSymbol.prototype.addTypeThatExplicitlyImplementsThisType = function (type) {
            this.referencedTypeSymbol.addTypeThatExplicitlyImplementsThisType(type);
        };
        PullTypeReferenceSymbol.prototype.getTypesThatExplicitlyImplementThisType = function () {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.getTypesThatExplicitlyImplementThisType();
        };

        PullTypeReferenceSymbol.prototype.isValidBaseKind = function (baseType, isExtendedType) {
            this.ensureReferencedTypeIsResolved();
            return this.referencedTypeSymbol.isValidBaseKind(baseType, isExtendedType);
        };

        PullTypeReferenceSymbol.prototype.findMember = function (name, lookInParent) {
            if (typeof lookInParent === "undefined") { lookInParent = true; }
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.findMember(name, lookInParent);
        };
        PullTypeReferenceSymbol.prototype.findNestedType = function (name, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.findNestedType(name, kind);
        };
        PullTypeReferenceSymbol.prototype.findNestedContainer = function (name, kind) {
            if (typeof kind === "undefined") { kind = 0 /* None */; }
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.findNestedContainer(name, kind);
        };
        PullTypeReferenceSymbol.prototype.getAllMembers = function (searchDeclKind, memberVisiblity) {
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.getAllMembers(searchDeclKind, memberVisiblity);
        };

        PullTypeReferenceSymbol.prototype.findTypeParameter = function (name) {
            this.ensureReferencedTypeIsResolved();

            return this.referencedTypeSymbol.findTypeParameter(name);
        };

        PullTypeReferenceSymbol.prototype.hasOnlyOverloadCallSignatures = function () {
            return this.referencedTypeSymbol.hasOnlyOverloadCallSignatures();
        };
        return PullTypeReferenceSymbol;
    })(TypeScript.PullTypeSymbol);
    TypeScript.PullTypeReferenceSymbol = PullTypeReferenceSymbol;

    TypeScript.nSpecializationsCreated = 0;
    TypeScript.nSpecializedSignaturesCreated = 0;
    TypeScript.nSpecializedTypeParameterCreated = 0;

    var PullInstantiatedTypeReferenceSymbol = (function (_super) {
        __extends(PullInstantiatedTypeReferenceSymbol, _super);
        function PullInstantiatedTypeReferenceSymbol(referencedTypeSymbol, _typeParameterArgumentMap, isInstanceReferenceType) {
            _super.call(this, referencedTypeSymbol);
            this.referencedTypeSymbol = referencedTypeSymbol;
            this._typeParameterArgumentMap = _typeParameterArgumentMap;
            this.isInstanceReferenceType = isInstanceReferenceType;
            this._instantiatedMembers = null;
            this._allInstantiatedMemberNameCache = null;
            this._instantiatedMemberNameCache = TypeScript.createIntrinsicsObject();
            this._instantiatedCallSignatures = null;
            this._instantiatedConstructSignatures = null;
            this._instantiatedIndexSignatures = null;
            this._typeArgumentReferences = undefined;
            this._instantiatedConstructorMethod = null;
            this._instantiatedAssociatedContainerType = null;
            this._isArray = undefined;
            this._generativeTypeClassification = [];

            TypeScript.nSpecializationsCreated++;
        }
        PullInstantiatedTypeReferenceSymbol.prototype.getIsSpecialized = function () {
            return !this.isInstanceReferenceType;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getGenerativeTypeClassification = function (enclosingType) {
            if (!this.isNamedTypeSymbol()) {
                return 0 /* Unknown */;
            }

            var generativeTypeClassification = this._generativeTypeClassification[enclosingType.pullSymbolID] || 0 /* Unknown */;
            if (generativeTypeClassification === 0 /* Unknown */) {
                var typeParameters = enclosingType.getTypeParameters();
                var enclosingTypeParameterMap = [];
                for (var i = 0; i < typeParameters.length; i++) {
                    enclosingTypeParameterMap[typeParameters[i].pullSymbolID] = typeParameters[i];
                }

                var typeArguments = this.getTypeArguments();
                for (var i = 0; i < typeArguments.length; i++) {
                    if (typeArguments[i].wrapsSomeTypeParameter(enclosingTypeParameterMap, true)) {
                        generativeTypeClassification = 1 /* Open */;
                        break;
                    }
                }

                if (generativeTypeClassification === 1 /* Open */) {
                    if (this.wrapsSomeTypeParameterIntoInfinitelyExpandingTypeReference(enclosingType)) {
                        generativeTypeClassification = 3 /* InfinitelyExpanding */;
                    }
                } else {
                    generativeTypeClassification = 2 /* Closed */;
                }

                this._generativeTypeClassification[enclosingType.pullSymbolID] = generativeTypeClassification;
            }

            return generativeTypeClassification;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.isArrayNamedTypeReference = function () {
            if (this._isArray === undefined) {
                this._isArray = this.getRootSymbol().isArrayNamedTypeReference() || (this.getRootSymbol() === this._getResolver().getArrayNamedType());
            }
            return this._isArray;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getElementType = function () {
            if (!this.isArrayNamedTypeReference()) {
                return null;
            }

            var typeArguments = this.getTypeArguments();
            return typeArguments ? typeArguments[0] : null;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getReferencedTypeSymbol = function () {
            this.ensureReferencedTypeIsResolved();

            if (this.getIsSpecialized()) {
                return this;
            }

            return this.referencedTypeSymbol;
        };

        PullInstantiatedTypeReferenceSymbol.create = function (resolver, type, typeParameterArgumentMap) {
            TypeScript.Debug.assert(resolver);

            var mutableTypeParameterMap = new TypeScript.PullInstantiationHelpers.MutableTypeArgumentMap(typeParameterArgumentMap);

            TypeScript.PullInstantiationHelpers.instantiateTypeArgument(resolver, type, mutableTypeParameterMap);

            var rootType = type.getRootSymbol();
            var instantiation = rootType.getSpecialization(mutableTypeParameterMap.typeParameterArgumentMap);
            if (instantiation) {
                return instantiation;
            }

            TypeScript.PullInstantiationHelpers.cleanUpTypeArgumentMap(type, mutableTypeParameterMap);
            typeParameterArgumentMap = mutableTypeParameterMap.typeParameterArgumentMap;

            var isInstanceReferenceType = (type.kind & 8216 /* SomeInstantiatableType */) != 0;
            var resolvedTypeParameterArgumentMap = typeParameterArgumentMap;
            if (isInstanceReferenceType) {
                var typeParameters = rootType.getTypeParameters();
                for (var i = 0; i < typeParameters.length; i++) {
                    if (!TypeScript.PullHelpers.typeSymbolsAreIdentical(typeParameters[i], typeParameterArgumentMap[typeParameters[i].pullSymbolID])) {
                        isInstanceReferenceType = false;
                        break;
                    }
                }

                if (isInstanceReferenceType) {
                    typeParameterArgumentMap = [];
                }
            }

            instantiation = new PullInstantiatedTypeReferenceSymbol(rootType, typeParameterArgumentMap, isInstanceReferenceType);

            rootType.addSpecialization(instantiation, resolvedTypeParameterArgumentMap);

            return instantiation;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.isGeneric = function () {
            return this.getRootSymbol().isGeneric();
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getTypeParameterArgumentMap = function () {
            return this._typeParameterArgumentMap;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getTypeArguments = function () {
            if (this.isInstanceReferenceType) {
                return this.getTypeParameters();
            }

            if (this._typeArgumentReferences === undefined) {
                var typeParameters = this.referencedTypeSymbol.getTypeParameters();

                if (typeParameters.length) {
                    var typeArgument = null;
                    var typeArguments = [];

                    for (var i = 0; i < typeParameters.length; i++) {
                        typeArgument = this._typeParameterArgumentMap[typeParameters[i].pullSymbolID];

                        if (!typeArgument) {
                            TypeScript.Debug.fail("type argument count mismatch");
                        }

                        if (typeArgument) {
                            typeArguments[typeArguments.length] = typeArgument;
                        }
                    }

                    this._typeArgumentReferences = typeArguments;
                } else {
                    this._typeArgumentReferences = null;
                }
            }

            return this._typeArgumentReferences;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getTypeArgumentsOrTypeParameters = function () {
            return this.getTypeArguments();
        };

        PullInstantiatedTypeReferenceSymbol.prototype.populateInstantiatedMemberFromReferencedMember = function (referencedMember) {
            var instantiatedMember;
            TypeScript.PullHelpers.resolveDeclaredSymbolToUseType(referencedMember);

            if (!referencedMember.type.wrapsSomeTypeParameter(this._typeParameterArgumentMap)) {
                instantiatedMember = referencedMember;
            } else {
                instantiatedMember = new TypeScript.PullSymbol(referencedMember.name, referencedMember.kind);
                instantiatedMember.setRootSymbol(referencedMember);
                instantiatedMember.type = this._getResolver().instantiateType(referencedMember.type, this._typeParameterArgumentMap);
                instantiatedMember.isOptional = referencedMember.isOptional;
            }
            this._instantiatedMemberNameCache[instantiatedMember.name] = instantiatedMember;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getMembers = function () {
            this.ensureReferencedTypeIsResolved();

            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getMembers();
            }

            if (!this._instantiatedMembers) {
                var referencedMembers = this.referencedTypeSymbol.getMembers();
                var referencedMember = null;
                var instantiatedMember = null;

                this._instantiatedMembers = [];

                for (var i = 0; i < referencedMembers.length; i++) {
                    referencedMember = referencedMembers[i];

                    this._getResolver().resolveDeclaredSymbol(referencedMember);

                    if (!this._instantiatedMemberNameCache[referencedMember.name]) {
                        this.populateInstantiatedMemberFromReferencedMember(referencedMember);
                    }

                    this._instantiatedMembers[this._instantiatedMembers.length] = this._instantiatedMemberNameCache[referencedMember.name];
                }
            }

            return this._instantiatedMembers;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.findMember = function (name, lookInParent) {
            if (typeof lookInParent === "undefined") { lookInParent = true; }
            this.ensureReferencedTypeIsResolved();

            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.findMember(name, lookInParent);
            }

            var memberSymbol = this._instantiatedMemberNameCache[name];

            if (!memberSymbol) {
                var referencedMemberSymbol = this.referencedTypeSymbol.findMember(name, lookInParent);

                if (referencedMemberSymbol) {
                    this.populateInstantiatedMemberFromReferencedMember(referencedMemberSymbol);
                    memberSymbol = this._instantiatedMemberNameCache[name];
                } else {
                    memberSymbol = null;
                }
            }

            return memberSymbol;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getAllMembers = function (searchDeclKind, memberVisiblity) {
            this.ensureReferencedTypeIsResolved();

            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getAllMembers(searchDeclKind, memberVisiblity);
            }

            var requestedMembers = [];
            var allReferencedMembers = this.referencedTypeSymbol.getAllMembers(searchDeclKind, memberVisiblity);

            if (!this._allInstantiatedMemberNameCache) {
                this._allInstantiatedMemberNameCache = TypeScript.createIntrinsicsObject();

                var members = this.getMembers();

                for (var i = 0; i < members.length; i++) {
                    this._allInstantiatedMemberNameCache[members[i].name] = members[i];
                }
            }

            var referencedMember = null;
            var requestedMember = null;

            for (var i = 0; i < allReferencedMembers.length; i++) {
                referencedMember = allReferencedMembers[i];

                this._getResolver().resolveDeclaredSymbol(referencedMember);

                if (this._allInstantiatedMemberNameCache[referencedMember.name]) {
                    requestedMembers[requestedMembers.length] = this._allInstantiatedMemberNameCache[referencedMember.name];
                } else {
                    if (!referencedMember.type.wrapsSomeTypeParameter(this._typeParameterArgumentMap)) {
                        this._allInstantiatedMemberNameCache[referencedMember.name] = referencedMember;
                        requestedMembers[requestedMembers.length] = referencedMember;
                    } else {
                        requestedMember = new TypeScript.PullSymbol(referencedMember.name, referencedMember.kind);
                        requestedMember.setRootSymbol(referencedMember);

                        requestedMember.type = this._getResolver().instantiateType(referencedMember.type, this._typeParameterArgumentMap);
                        requestedMember.isOptional = referencedMember.isOptional;

                        this._allInstantiatedMemberNameCache[requestedMember.name] = requestedMember;
                        requestedMembers[requestedMembers.length] = requestedMember;
                    }
                }
            }

            return requestedMembers;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getConstructorMethod = function () {
            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getConstructorMethod();
            }

            if (!this._instantiatedConstructorMethod) {
                var referencedConstructorMethod = this.referencedTypeSymbol.getConstructorMethod();
                this._instantiatedConstructorMethod = new TypeScript.PullSymbol(referencedConstructorMethod.name, referencedConstructorMethod.kind);
                this._instantiatedConstructorMethod.setRootSymbol(referencedConstructorMethod);
                this._instantiatedConstructorMethod.setResolved();

                this._instantiatedConstructorMethod.type = PullInstantiatedTypeReferenceSymbol.create(this._getResolver(), referencedConstructorMethod.type, this._typeParameterArgumentMap);
            }

            return this._instantiatedConstructorMethod;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getAssociatedContainerType = function () {
            if (!this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getAssociatedContainerType();
            }

            if (!this._instantiatedAssociatedContainerType) {
                var referencedAssociatedContainerType = this.referencedTypeSymbol.getAssociatedContainerType();

                if (referencedAssociatedContainerType) {
                    this._instantiatedAssociatedContainerType = PullInstantiatedTypeReferenceSymbol.create(this._getResolver(), referencedAssociatedContainerType, this._typeParameterArgumentMap);
                }
            }

            return this._instantiatedAssociatedContainerType;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getCallSignatures = function () {
            this.ensureReferencedTypeIsResolved();

            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getCallSignatures();
            }

            if (this._instantiatedCallSignatures) {
                return this._instantiatedCallSignatures;
            }

            var referencedCallSignatures = this.referencedTypeSymbol.getCallSignatures();
            this._instantiatedCallSignatures = [];

            for (var i = 0; i < referencedCallSignatures.length; i++) {
                this._getResolver().resolveDeclaredSymbol(referencedCallSignatures[i]);

                if (!referencedCallSignatures[i].wrapsSomeTypeParameter(this._typeParameterArgumentMap)) {
                    this._instantiatedCallSignatures[this._instantiatedCallSignatures.length] = referencedCallSignatures[i];
                } else {
                    this._instantiatedCallSignatures[this._instantiatedCallSignatures.length] = this._getResolver().instantiateSignature(referencedCallSignatures[i], this._typeParameterArgumentMap);
                    this._instantiatedCallSignatures[this._instantiatedCallSignatures.length - 1].functionType = this;
                }
            }

            return this._instantiatedCallSignatures;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getConstructSignatures = function () {
            this.ensureReferencedTypeIsResolved();

            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getConstructSignatures();
            }

            if (this._instantiatedConstructSignatures) {
                return this._instantiatedConstructSignatures;
            }

            var referencedConstructSignatures = this.referencedTypeSymbol.getConstructSignatures();
            this._instantiatedConstructSignatures = [];

            for (var i = 0; i < referencedConstructSignatures.length; i++) {
                this._getResolver().resolveDeclaredSymbol(referencedConstructSignatures[i]);

                if (!referencedConstructSignatures[i].wrapsSomeTypeParameter(this._typeParameterArgumentMap)) {
                    this._instantiatedConstructSignatures[this._instantiatedConstructSignatures.length] = referencedConstructSignatures[i];
                } else {
                    this._instantiatedConstructSignatures[this._instantiatedConstructSignatures.length] = this._getResolver().instantiateSignature(referencedConstructSignatures[i], this._typeParameterArgumentMap);
                    this._instantiatedConstructSignatures[this._instantiatedConstructSignatures.length - 1].functionType = this;
                }
            }

            return this._instantiatedConstructSignatures;
        };

        PullInstantiatedTypeReferenceSymbol.prototype.getIndexSignatures = function () {
            this.ensureReferencedTypeIsResolved();

            if (this.isInstanceReferenceType) {
                return this.referencedTypeSymbol.getIndexSignatures();
            }

            if (this._instantiatedIndexSignatures) {
                return this._instantiatedIndexSignatures;
            }

            var referencedIndexSignatures = this.referencedTypeSymbol.getIndexSignatures();
            this._instantiatedIndexSignatures = [];

            for (var i = 0; i < referencedIndexSignatures.length; i++) {
                this._getResolver().resolveDeclaredSymbol(referencedIndexSignatures[i]);

                if (!referencedIndexSignatures[i].wrapsSomeTypeParameter(this._typeParameterArgumentMap)) {
                    this._instantiatedIndexSignatures[this._instantiatedIndexSignatures.length] = referencedIndexSignatures[i];
                } else {
                    this._instantiatedIndexSignatures[this._instantiatedIndexSignatures.length] = this._getResolver().instantiateSignature(referencedIndexSignatures[i], this._typeParameterArgumentMap);
                    this._instantiatedIndexSignatures[this._instantiatedIndexSignatures.length - 1].functionType = this;
                }
            }

            return this._instantiatedIndexSignatures;
        };
        return PullInstantiatedTypeReferenceSymbol;
    })(PullTypeReferenceSymbol);
    TypeScript.PullInstantiatedTypeReferenceSymbol = PullInstantiatedTypeReferenceSymbol;

    var PullInstantiatedSignatureSymbol = (function (_super) {
        __extends(PullInstantiatedSignatureSymbol, _super);
        function PullInstantiatedSignatureSymbol(rootSignature, _typeParameterArgumentMap) {
            _super.call(this, rootSignature.kind, rootSignature.isDefinition());
            this._typeParameterArgumentMap = _typeParameterArgumentMap;
            this.setRootSymbol(rootSignature);
            TypeScript.nSpecializedSignaturesCreated++;

            rootSignature.addSpecialization(this, _typeParameterArgumentMap);
        }
        PullInstantiatedSignatureSymbol.prototype.getTypeParameterArgumentMap = function () {
            return this._typeParameterArgumentMap;
        };

        PullInstantiatedSignatureSymbol.prototype.getIsSpecialized = function () {
            return true;
        };

        PullInstantiatedSignatureSymbol.prototype._getResolver = function () {
            return this.getRootSymbol()._getResolver();
        };

        PullInstantiatedSignatureSymbol.prototype.getTypeParameters = function () {
            var _this = this;
            if (!this._typeParameters) {
                var rootSymbol = this.getRootSymbol();
                var typeParameters = rootSymbol.getTypeParameters();
                var hasInstantiatedTypeParametersOfThisSignature = TypeScript.ArrayUtilities.all(typeParameters, function (typeParameter) {
                    return _this._typeParameterArgumentMap[typeParameter.pullSymbolID] !== undefined;
                });

                if (!hasInstantiatedTypeParametersOfThisSignature && typeParameters.length) {
                    this._typeParameters = [];
                    for (var i = 0; i < typeParameters.length; i++) {
                        this._typeParameters[this._typeParameters.length] = this._getResolver().instantiateTypeParameter(typeParameters[i], this._typeParameterArgumentMap);
                    }
                } else {
                    this._typeParameters = TypeScript.sentinelEmptyArray;
                }
            }

            return this._typeParameters;
        };

        PullInstantiatedSignatureSymbol.prototype.getAllowedToReferenceTypeParameters = function () {
            var rootSymbol = this.getRootSymbol();
            return rootSymbol.getAllowedToReferenceTypeParameters();
        };
        return PullInstantiatedSignatureSymbol;
    })(TypeScript.PullSignatureSymbol);
    TypeScript.PullInstantiatedSignatureSymbol = PullInstantiatedSignatureSymbol;

    var PullInstantiatedTypeParameterSymbol = (function (_super) {
        __extends(PullInstantiatedTypeParameterSymbol, _super);
        function PullInstantiatedTypeParameterSymbol(rootTypeParameter, constraintType) {
            _super.call(this, rootTypeParameter.name);
            TypeScript.nSpecializedTypeParameterCreated++;

            this.setRootSymbol(rootTypeParameter);
            this.setConstraint(constraintType);

            rootTypeParameter.addSpecialization(this, [constraintType]);
        }
        PullInstantiatedTypeParameterSymbol.prototype._getResolver = function () {
            return this.getRootSymbol()._getResolver();
        };
        return PullInstantiatedTypeParameterSymbol;
    })(TypeScript.PullTypeParameterSymbol);
    TypeScript.PullInstantiatedTypeParameterSymbol = PullInstantiatedTypeParameterSymbol;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SyntaxTreeToAstVisitor = (function () {
        function SyntaxTreeToAstVisitor(fileName, lineMap, compilationSettings) {
            this.fileName = fileName;
            this.lineMap = lineMap;
            this.compilationSettings = compilationSettings;
            this.position = 0;
            this.previousTokenTrailingComments = null;
        }
        SyntaxTreeToAstVisitor.visit = function (syntaxTree, fileName, compilationSettings, incrementalAST) {
            var visitor = incrementalAST ? new SyntaxTreeToIncrementalAstVisitor(fileName, syntaxTree.lineMap(), compilationSettings) : new SyntaxTreeToAstVisitor(fileName, syntaxTree.lineMap(), compilationSettings);
            return syntaxTree.sourceUnit().accept(visitor);
        };

        SyntaxTreeToAstVisitor.prototype.movePast = function (element) {
            if (element !== null) {
                this.position += element.fullWidth();
            }
        };

        SyntaxTreeToAstVisitor.prototype.moveTo = function (element1, element2) {
            if (element2 !== null) {
                this.position += TypeScript.Syntax.childOffset(element1, element2);
            }
        };

        SyntaxTreeToAstVisitor.prototype.setCommentsAndSpan = function (ast, fullStart, node) {
            var firstToken = node.firstToken();
            var lastToken = node.lastToken();

            this.setSpan(ast, fullStart, node, firstToken, lastToken);
            ast.setPreComments(this.convertTokenLeadingComments(firstToken, fullStart));
            ast.setPostComments(this.convertNodeTrailingComments(node, lastToken, fullStart));
        };

        SyntaxTreeToAstVisitor.prototype.createTokenSpan = function (fullStart, element) {
            if (element === null) {
                return null;
            }

            if (element.fullWidth() === 0) {
                return new TypeScript.ASTSpan(-1, -1);
            }

            var leadingTriviaWidth = element.leadingTriviaWidth();
            var trailingTriviaWidth = element.trailingTriviaWidth();

            var start = fullStart + leadingTriviaWidth;
            var end = fullStart + element.fullWidth() - trailingTriviaWidth;

            return new TypeScript.ASTSpan(start, end);
        };

        SyntaxTreeToAstVisitor.prototype.setSpan = function (span, fullStart, element, firstToken, lastToken) {
            if (typeof firstToken === "undefined") { firstToken = element.firstToken(); }
            if (typeof lastToken === "undefined") { lastToken = element.lastToken(); }
            var leadingTriviaWidth = firstToken ? firstToken.leadingTriviaWidth() : 0;
            var trailingTriviaWidth = lastToken ? lastToken.trailingTriviaWidth() : 0;

            var desiredMinChar = fullStart + leadingTriviaWidth;
            var desiredLimChar = fullStart + element.fullWidth() - trailingTriviaWidth;

            this.setSpanExplicit(span, desiredMinChar, desiredLimChar);

            span._trailingTriviaWidth = trailingTriviaWidth;
        };

        SyntaxTreeToAstVisitor.prototype.setSpanExplicit = function (span, start, end) {
            span._start = start;
            span._end = end;
        };

        SyntaxTreeToAstVisitor.prototype.visitSyntaxList = function (node) {
            var start = this.position;
            var array = new Array(node.childCount());

            for (var i = 0, n = node.childCount(); i < n; i++) {
                array[i] = node.childAt(i).accept(this);
            }

            var result = new TypeScript.ISyntaxList2(this.fileName, array);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitSeparatedSyntaxList = function (list) {
            var start = this.position;
            var array = new Array(list.nonSeparatorCount());

            for (var i = 0, n = list.childCount(); i < n; i++) {
                if (i % 2 === 0) {
                    array[i / 2] = list.childAt(i).accept(this);
                    this.previousTokenTrailingComments = null;
                } else {
                    var separatorToken = list.childAt(i);
                    this.previousTokenTrailingComments = this.convertTokenTrailingComments(separatorToken, this.position + separatorToken.leadingTriviaWidth() + separatorToken.width());
                    this.movePast(separatorToken);
                }
            }

            var result = new TypeScript.ISeparatedSyntaxList2(this.fileName, array, list.separatorCount());
            this.setSpan(result, start, list);

            result.setPostComments(this.previousTokenTrailingComments);
            this.previousTokenTrailingComments = null;

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.convertComment = function (trivia, commentStartPosition, hasTrailingNewLine) {
            var comment = new TypeScript.Comment(trivia, hasTrailingNewLine, commentStartPosition, commentStartPosition + trivia.fullWidth());

            return comment;
        };

        SyntaxTreeToAstVisitor.prototype.convertComments = function (triviaList, commentStartPosition) {
            var result = [];

            for (var i = 0, n = triviaList.count(); i < n; i++) {
                var trivia = triviaList.syntaxTriviaAt(i);

                if (trivia.isComment()) {
                    var hasTrailingNewLine = ((i + 1) < n) && triviaList.syntaxTriviaAt(i + 1).isNewLine();
                    result.push(this.convertComment(trivia, commentStartPosition, hasTrailingNewLine));
                }

                commentStartPosition += trivia.fullWidth();
            }

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.mergeComments = function (comments1, comments2) {
            if (comments1 === null) {
                return comments2;
            }

            if (comments2 === null) {
                return comments1;
            }

            return comments1.concat(comments2);
        };

        SyntaxTreeToAstVisitor.prototype.convertTokenLeadingComments = function (token, commentStartPosition) {
            if (token === null) {
                return null;
            }

            var preComments = token.hasLeadingComment() ? this.convertComments(token.leadingTrivia(), commentStartPosition) : null;

            var previousTokenTrailingComments = this.previousTokenTrailingComments;
            this.previousTokenTrailingComments = null;

            return this.mergeComments(previousTokenTrailingComments, preComments);
        };

        SyntaxTreeToAstVisitor.prototype.convertTokenTrailingComments = function (token, commentStartPosition) {
            if (token === null || !token.hasTrailingComment() || token.hasTrailingNewLine()) {
                return null;
            }

            return this.convertComments(token.trailingTrivia(), commentStartPosition);
        };

        SyntaxTreeToAstVisitor.prototype.convertNodeTrailingComments = function (node, lastToken, nodeStart) {
            if (lastToken === null || !lastToken.hasTrailingComment() || lastToken.hasTrailingNewLine()) {
                return null;
            }

            return this.convertComments(lastToken.trailingTrivia(), nodeStart + node.fullWidth() - lastToken.trailingTriviaWidth());
        };

        SyntaxTreeToAstVisitor.prototype.visitIdentifier = function (token) {
            return this.visitToken(token);
        };

        SyntaxTreeToAstVisitor.prototype.visitToken = function (token) {
            var fullStart = this.position;

            var result = this.visitTokenWorker(token);

            this.movePast(token);

            var start = fullStart + token.leadingTriviaWidth();
            this.setSpanExplicit(result, start, start + token.width());
            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTokenWorker = function (token) {
            switch (token.tokenKind) {
                case 60 /* AnyKeyword */:
                    return new TypeScript.BuiltInType(60 /* AnyKeyword */, token.text(), token.valueText());
                case 61 /* BooleanKeyword */:
                    return new TypeScript.BuiltInType(61 /* BooleanKeyword */, token.text(), token.valueText());
                case 67 /* NumberKeyword */:
                    return new TypeScript.BuiltInType(67 /* NumberKeyword */, token.text(), token.valueText());
                case 69 /* StringKeyword */:
                    return new TypeScript.BuiltInType(69 /* StringKeyword */, token.text(), token.valueText());
                case 41 /* VoidKeyword */:
                    return new TypeScript.BuiltInType(41 /* VoidKeyword */, token.text(), token.valueText());
                case 35 /* ThisKeyword */:
                    return new TypeScript.ThisExpression(token.text(), token.valueText());
                case 50 /* SuperKeyword */:
                    return new TypeScript.SuperExpression(token.text(), token.valueText());
                case 37 /* TrueKeyword */:
                    return new TypeScript.LiteralExpression(37 /* TrueKeyword */, token.text(), token.valueText());
                case 24 /* FalseKeyword */:
                    return new TypeScript.LiteralExpression(24 /* FalseKeyword */, token.text(), token.valueText());
                case 32 /* NullKeyword */:
                    return new TypeScript.LiteralExpression(32 /* NullKeyword */, token.text(), token.valueText());
                case 14 /* StringLiteral */:
                    return new TypeScript.StringLiteral(token.text(), token.valueText());
                case 12 /* RegularExpressionLiteral */:
                    return new TypeScript.RegularExpressionLiteral(token.text(), token.valueText());
                case 13 /* NumericLiteral */:
                    var fullStart = this.position;
                    var preComments = this.convertTokenLeadingComments(token, fullStart);

                    var result = new TypeScript.NumericLiteral(token.value(), token.text(), token.valueText());

                    result.setPreComments(preComments);
                    return result;
                case 11 /* IdentifierName */:
                    return new TypeScript.Identifier(token.text());
                default:
                    throw TypeScript.Errors.invalidOperation();
            }
        };

        SyntaxTreeToAstVisitor.prototype.visitSourceUnit = function (node) {
            var start = this.position;
            TypeScript.Debug.assert(start === 0);

            var bod = this.visitSyntaxList(node.moduleElements);
            var comments = this.convertTokenLeadingComments(node.endOfFileToken, TypeScript.Syntax.childOffset(node, node.endOfFileToken));
            var result = new TypeScript.SourceUnit(bod, comments, this.fileName);
            this.setSpanExplicit(result, start, start + node.fullWidth());

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitExternalModuleReference = function (node) {
            var start = this.position;

            this.moveTo(node, node.stringLiteral);
            var stringLiteral = node.stringLiteral.accept(this);
            this.movePast(node.closeParenToken);

            var result = new TypeScript.ExternalModuleReference(stringLiteral);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitModuleNameModuleReference = function (node) {
            var start = this.position;
            var moduleName = node.moduleName.accept(this);

            var result = new TypeScript.ModuleNameModuleReference(moduleName);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitClassDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.identifier);
            var name = this.visitIdentifier(node.identifier);

            var typeParameters = this.visitTypeParameterList(node.typeParameterList);
            var heritageClauses = node.heritageClauses ? this.visitSyntaxList(node.heritageClauses) : null;

            this.movePast(node.openBraceToken);
            var members = this.visitSyntaxList(node.classElements);

            var closeBraceToken = this.createTokenSpan(this.position, node.closeBraceToken);
            this.movePast(node.closeBraceToken);

            var modifiers = this.visitModifiers(node.modifiers);
            var result = new TypeScript.ClassDeclaration(modifiers, name, typeParameters, heritageClauses, members, closeBraceToken);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitModifiers = function (modifiers) {
            var result = null;
            if (TypeScript.SyntaxUtilities.containsToken(modifiers, 47 /* ExportKeyword */)) {
                result = result || [];
                result.push(1 /* Exported */);
            }

            if (TypeScript.SyntaxUtilities.containsToken(modifiers, 63 /* DeclareKeyword */)) {
                result = result || [];
                result.push(8 /* Ambient */);
            }

            if (TypeScript.SyntaxUtilities.containsToken(modifiers, 58 /* StaticKeyword */)) {
                result = result || [];
                result.push(16 /* Static */);
            }

            if (TypeScript.SyntaxUtilities.containsToken(modifiers, 57 /* PublicKeyword */)) {
                result = result || [];
                result.push(4 /* Public */);
            }

            if (TypeScript.SyntaxUtilities.containsToken(modifiers, 55 /* PrivateKeyword */)) {
                result = result || [];
                result.push(2 /* Private */);
            }

            return result || TypeScript.sentinelEmptyArray;
        };

        SyntaxTreeToAstVisitor.prototype.visitInterfaceDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.identifier);
            var name = this.visitIdentifier(node.identifier);
            var typeParameters = this.visitTypeParameterList(node.typeParameterList);
            var heritageClauses = node.heritageClauses ? this.visitSyntaxList(node.heritageClauses) : null;

            var body = this.visitObjectType(node.body);

            var modifiers = this.visitModifiers(node.modifiers);
            var result = new TypeScript.InterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, body);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitHeritageClause = function (node) {
            var start = this.position;

            this.movePast(node.extendsOrImplementsKeyword);
            var typeNames = this.visitSeparatedSyntaxList(node.typeNames);

            var result = new TypeScript.HeritageClause(node.extendsOrImplementsKeyword.tokenKind === 48 /* ExtendsKeyword */ ? 230 /* ExtendsHeritageClause */ : 231 /* ImplementsHeritageClause */, typeNames);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitModuleDeclaration = function (node) {
            var start = this.position;

            var modifiers = this.visitModifiers(node.modifiers);

            this.moveTo(node, node.moduleKeyword);
            this.movePast(node.moduleKeyword);

            var moduleName = node.name ? node.name.accept(this) : null;
            var stringLiteral = node.stringLiteral ? node.stringLiteral.accept(this) : null;

            this.movePast(node.openBraceToken);

            var moduleElements = this.visitSyntaxList(node.moduleElements);

            var closeBraceToken = this.createTokenSpan(this.position, node.closeBraceToken);
            this.movePast(node.closeBraceToken);

            var result = new TypeScript.ModuleDeclaration(modifiers, moduleName, stringLiteral, moduleElements, closeBraceToken);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitFunctionDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.identifier);
            var name = this.visitIdentifier(node.identifier);

            var callSignature = this.visitCallSignature(node.callSignature);
            var block = node.block ? this.visitBlock(node.block) : null;

            this.movePast(node.semicolonToken);

            var result = new TypeScript.FunctionDeclaration(this.visitModifiers(node.modifiers), name, callSignature, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitEnumDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.identifier);
            var identifier = this.visitIdentifier(node.identifier);

            this.movePast(node.openBraceToken);

            var enumElements = this.visitSeparatedSyntaxList(node.enumElements);

            this.movePast(node.closeBraceToken);

            var result = new TypeScript.EnumDeclaration(this.visitModifiers(node.modifiers), identifier, enumElements);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitEnumElement = function (node) {
            var start = this.position;

            var memberName = this.visitToken(node.propertyName);

            var value = node.equalsValueClause !== null ? this.visitEqualsValueClause(node.equalsValueClause) : null;

            var result = new TypeScript.EnumElement(memberName, value);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitImportDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.identifier);
            var name = this.visitIdentifier(node.identifier);
            this.movePast(node.equalsToken);
            var alias = node.moduleReference.accept(this);
            this.movePast(node.semicolonToken);

            var modifiers = this.visitModifiers(node.modifiers);
            var result = new TypeScript.ImportDeclaration(modifiers, name, alias);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitExportAssignment = function (node) {
            var start = this.position;

            this.moveTo(node, node.identifier);
            var name = this.visitIdentifier(node.identifier);
            this.movePast(node.semicolonToken);

            var result = new TypeScript.ExportAssignment(name);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitVariableStatement = function (node) {
            var start = this.position;

            this.moveTo(node, node.variableDeclaration);

            var declaration = node.variableDeclaration.accept(this);
            this.movePast(node.semicolonToken);

            var modifiers = this.visitModifiers(node.modifiers);

            var result = new TypeScript.VariableStatement(modifiers, declaration);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitVariableDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.variableDeclarators);
            var variableDecls = this.visitSeparatedSyntaxList(node.variableDeclarators);

            var result = new TypeScript.VariableDeclaration(variableDecls);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitVariableDeclarator = function (node) {
            var start = this.position;
            var propertyName = this.visitToken(node.propertyName);
            var typeExpr = this.visitTypeAnnotation(node.typeAnnotation);
            var init = node.equalsValueClause ? this.visitEqualsValueClause(node.equalsValueClause) : null;

            var result = new TypeScript.VariableDeclarator(propertyName, typeExpr, init);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitEqualsValueClause = function (node) {
            var start = this.position;
            var afterEqualsComments = this.convertTokenTrailingComments(node.equalsToken, this.position + node.equalsToken.leadingTriviaWidth() + node.equalsToken.width());

            this.movePast(node.equalsToken);
            var value = node.value.accept(this);
            value.setPreComments(this.mergeComments(afterEqualsComments, value.preComments()));

            var result = new TypeScript.EqualsValueClause(value);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitPrefixUnaryExpression = function (node) {
            var start = this.position;

            this.movePast(node.operatorToken);
            var operand = node.operand.accept(this);

            var result = new TypeScript.PrefixUnaryExpression(node.kind(), operand);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitArrayLiteralExpression = function (node) {
            var start = this.position;
            var openStart = this.position + node.openBracketToken.leadingTriviaWidth();
            this.movePast(node.openBracketToken);

            var expressions = this.visitSeparatedSyntaxList(node.expressions);

            var closeStart = this.position + node.closeBracketToken.leadingTriviaWidth();
            this.movePast(node.closeBracketToken);

            var result = new TypeScript.ArrayLiteralExpression(expressions);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitOmittedExpression = function (node) {
            var start = this.position;

            var result = new TypeScript.OmittedExpression();
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitParenthesizedExpression = function (node) {
            var start = this.position;

            var openParenToken = node.openParenToken;
            var openParenTrailingComments = this.convertTokenTrailingComments(openParenToken, start + openParenToken.leadingTriviaWidth() + openParenToken.width());

            this.movePast(openParenToken);

            var expr = node.expression.accept(this);
            this.movePast(node.closeParenToken);

            var result = new TypeScript.ParenthesizedExpression(openParenTrailingComments, expr);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitSimpleArrowFunctionExpression = function (node) {
            var start = this.position;

            var identifier = node.identifier.accept(this);
            this.movePast(node.equalsGreaterThanToken);

            var block = node.block ? this.visitBlock(node.block) : null;
            var expression = node.expression ? node.expression.accept(this) : null;

            var result = new TypeScript.SimpleArrowFunctionExpression(identifier, block, expression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitParenthesizedArrowFunctionExpression = function (node) {
            var start = this.position;

            var callSignature = this.visitCallSignature(node.callSignature);
            this.movePast(node.equalsGreaterThanToken);

            var block = node.block ? this.visitBlock(node.block) : null;
            var expression = node.expression ? node.expression.accept(this) : null;

            var result = new TypeScript.ParenthesizedArrowFunctionExpression(callSignature, block, expression);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitType = function (type) {
            return type ? type.accept(this) : null;
        };

        SyntaxTreeToAstVisitor.prototype.visitTypeQuery = function (node) {
            var start = this.position;
            this.movePast(node.typeOfKeyword);
            var name = node.name.accept(this);

            var result = new TypeScript.TypeQuery(name);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitQualifiedName = function (node) {
            var start = this.position;
            var left = this.visitType(node.left);
            this.movePast(node.dotToken);
            var right = this.visitIdentifier(node.right);

            var result = new TypeScript.QualifiedName(left, right);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTypeArgumentList = function (node) {
            if (node === null) {
                return null;
            }

            var start = this.position;
            this.movePast(node.lessThanToken);
            var typeArguments = this.visitSeparatedSyntaxList(node.typeArguments);
            this.movePast(node.greaterThanToken);

            var result = new TypeScript.TypeArgumentList(typeArguments);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitConstructorType = function (node) {
            var start = this.position;

            this.movePast(node.newKeyword);
            var typeParameters = this.visitTypeParameterList(node.typeParameterList);
            var parameters = this.visitParameterList(node.parameterList);
            this.movePast(node.equalsGreaterThanToken);
            var returnType = this.visitType(node.type);

            var result = new TypeScript.ConstructorType(typeParameters, parameters, returnType);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitFunctionType = function (node) {
            var start = this.position;
            var typeParameters = this.visitTypeParameterList(node.typeParameterList);
            var parameters = this.visitParameterList(node.parameterList);
            this.movePast(node.equalsGreaterThanToken);
            var returnType = this.visitType(node.type);

            var result = new TypeScript.FunctionType(typeParameters, parameters, returnType);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitObjectType = function (node) {
            var start = this.position;

            this.movePast(node.openBraceToken);
            var typeMembers = this.visitSeparatedSyntaxList(node.typeMembers);
            this.movePast(node.closeBraceToken);

            var result = new TypeScript.ObjectType(typeMembers);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitArrayType = function (node) {
            var start = this.position;

            var underlying = this.visitType(node.type);
            this.movePast(node.openBracketToken);
            this.movePast(node.closeBracketToken);

            var result = new TypeScript.ArrayType(underlying);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitGenericType = function (node) {
            var start = this.position;

            var underlying = this.visitType(node.name);
            var typeArguments = this.visitTypeArgumentList(node.typeArgumentList);

            var result = new TypeScript.GenericType(underlying, typeArguments);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTypeAnnotation = function (node) {
            if (!node) {
                return null;
            }

            var start = this.position;
            this.movePast(node.colonToken);
            var type = this.visitType(node.type);

            var result = new TypeScript.TypeAnnotation(type);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitBlock = function (node) {
            if (!node) {
                return null;
            }

            var start = this.position;

            this.movePast(node.openBraceToken);
            var statements = this.visitSyntaxList(node.statements);
            var closeBracePosition = this.position;

            var closeBraceLeadingComments = this.convertTokenLeadingComments(node.closeBraceToken, this.position);
            var closeBraceToken = this.createTokenSpan(this.position, node.closeBraceToken);
            this.movePast(node.closeBraceToken);

            var result = new TypeScript.Block(statements, closeBraceLeadingComments, closeBraceToken);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitParameter = function (node) {
            var start = this.position;

            var dotDotDotToken = this.createTokenSpan(this.position, node.dotDotDotToken);

            this.moveTo(node, node.identifier);
            var identifier = this.visitIdentifier(node.identifier);

            var questionToken = this.createTokenSpan(this.position, node.questionToken);
            this.movePast(node.questionToken);
            var typeExpr = this.visitTypeAnnotation(node.typeAnnotation);
            var init = node.equalsValueClause ? node.equalsValueClause.accept(this) : null;

            var modifiers = this.visitModifiers(node.modifiers);

            var result = new TypeScript.Parameter(dotDotDotToken, modifiers, identifier, questionToken, typeExpr, init);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitMemberAccessExpression = function (node) {
            var start = this.position;

            var expression = node.expression.accept(this);
            this.movePast(node.dotToken);
            var name = this.visitIdentifier(node.name);

            var result = new TypeScript.MemberAccessExpression(expression, name);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitPostfixUnaryExpression = function (node) {
            var start = this.position;

            var operand = node.operand.accept(this);
            this.movePast(node.operatorToken);

            var result = new TypeScript.PostfixUnaryExpression(node.kind() === 210 /* PostIncrementExpression */ ? 210 /* PostIncrementExpression */ : 211 /* PostDecrementExpression */, operand);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitElementAccessExpression = function (node) {
            var start = this.position;

            var expression = node.expression.accept(this);
            this.movePast(node.openBracketToken);
            var argumentExpression = node.argumentExpression.accept(this);
            this.movePast(node.closeBracketToken);

            var result = new TypeScript.ElementAccessExpression(expression, argumentExpression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitInvocationExpression = function (node) {
            var start = this.position;

            var expression = node.expression.accept(this);
            var argumentList = this.visitArgumentList(node.argumentList);

            var result = new TypeScript.InvocationExpression(expression, argumentList);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitArgumentList = function (node) {
            if (node === null) {
                return null;
            }

            var start = this.position;

            var typeArguments = this.visitTypeArgumentList(node.typeArgumentList);

            this.movePast(node.openParenToken);

            var _arguments = this.visitSeparatedSyntaxList(node.arguments);

            if (node.arguments.fullWidth() === 0 && node.closeParenToken.fullWidth() === 0) {
                var openParenTokenEnd = start + node.openParenToken.leadingTriviaWidth() + node.openParenToken.width();
                this.setSpanExplicit(_arguments, openParenTokenEnd, openParenTokenEnd + node.openParenToken.trailingTriviaWidth());
            }

            var closeParenToken = this.createTokenSpan(this.position, node.closeParenToken);
            this.movePast(node.closeParenToken);

            var result = new TypeScript.ArgumentList(typeArguments, _arguments, closeParenToken);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitBinaryExpression = function (node) {
            var start = this.position;

            var left = node.left.accept(this);
            this.movePast(node.operatorToken);
            var right = node.right.accept(this);

            var result = new TypeScript.BinaryExpression(node.kind(), left, right);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitConditionalExpression = function (node) {
            var start = this.position;

            var condition = node.condition.accept(this);
            this.movePast(node.questionToken);
            var whenTrue = node.whenTrue.accept(this);
            this.movePast(node.colonToken);
            var whenFalse = node.whenFalse.accept(this);

            var result = new TypeScript.ConditionalExpression(condition, whenTrue, whenFalse);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitConstructSignature = function (node) {
            var start = this.position;

            this.movePast(node.newKeyword);
            var callSignature = this.visitCallSignature(node.callSignature);

            var result = new TypeScript.ConstructSignature(callSignature);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitMethodSignature = function (node) {
            var start = this.position;

            var name = this.visitToken(node.propertyName);

            var questionToken = this.createTokenSpan(this.position, node.questionToken);
            this.movePast(node.questionToken);

            var callSignature = this.visitCallSignature(node.callSignature);

            var result = new TypeScript.MethodSignature(name, questionToken, callSignature);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitIndexSignature = function (node) {
            var start = this.position;

            this.movePast(node.openBracketToken);

            var parameter = node.parameter.accept(this);

            this.movePast(node.closeBracketToken);
            var returnType = this.visitTypeAnnotation(node.typeAnnotation);

            var result = new TypeScript.IndexSignature(parameter, returnType);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitPropertySignature = function (node) {
            var start = this.position;

            var name = this.visitToken(node.propertyName);

            var questionToken = this.createTokenSpan(this.position, node.questionToken);
            this.movePast(node.questionToken);
            var typeExpr = this.visitTypeAnnotation(node.typeAnnotation);

            var result = new TypeScript.PropertySignature(name, questionToken, typeExpr);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitParameterList = function (node) {
            if (!node) {
                return null;
            }

            var start = this.position;

            var openParenToken = node.openParenToken;

            this.previousTokenTrailingComments = this.convertTokenTrailingComments(openParenToken, start + openParenToken.leadingTriviaWidth() + openParenToken.width());
            var openParenTrailingComments = null;
            if (node.parameters.childCount() === 0) {
                openParenTrailingComments = this.previousTokenTrailingComments;
                this.previousTokenTrailingComments = null;
            }

            this.movePast(node.openParenToken);
            var parameters = this.visitSeparatedSyntaxList(node.parameters);
            this.movePast(node.closeParenToken);

            var result = new TypeScript.ParameterList(openParenTrailingComments, parameters);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitCallSignature = function (node) {
            var start = this.position;

            var typeParameters = this.visitTypeParameterList(node.typeParameterList);
            var parameters = this.visitParameterList(node.parameterList);
            var returnType = this.visitTypeAnnotation(node.typeAnnotation);

            var result = new TypeScript.CallSignature(typeParameters, parameters, returnType);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTypeParameterList = function (node) {
            if (!node) {
                return null;
            }

            var start = this.position;
            this.movePast(node.lessThanToken);
            var typeParameters = this.visitSeparatedSyntaxList(node.typeParameters);
            this.movePast(node.greaterThanToken);

            var result = new TypeScript.TypeParameterList(typeParameters);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTypeParameter = function (node) {
            var start = this.position;

            var identifier = this.visitIdentifier(node.identifier);
            var constraint = node.constraint ? node.constraint.accept(this) : null;

            var result = new TypeScript.TypeParameter(identifier, constraint);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitConstraint = function (node) {
            var start = this.position;
            this.movePast(node.extendsKeyword);
            var type = this.visitType(node.type);

            var result = new TypeScript.Constraint(type);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitIfStatement = function (node) {
            var start = this.position;

            this.moveTo(node, node.condition);
            var condition = node.condition.accept(this);
            this.movePast(node.closeParenToken);
            var thenBod = node.statement.accept(this);
            var elseBod = node.elseClause ? node.elseClause.accept(this) : null;

            var result = new TypeScript.IfStatement(condition, thenBod, elseBod);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitElseClause = function (node) {
            var start = this.position;

            this.movePast(node.elseKeyword);
            var statement = node.statement.accept(this);

            var result = new TypeScript.ElseClause(statement);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitExpressionStatement = function (node) {
            var start = this.position;

            var preComments = this.convertTokenLeadingComments(node.firstToken(), start);
            var expression = node.expression.accept(this);

            var semicolonPosition = this.position;

            var postComments = this.convertComments(node.semicolonToken.trailingTrivia(), this.position + node.semicolonToken.leadingTriviaWidth() + node.semicolonToken.width());
            this.movePast(node.semicolonToken);

            var result = new TypeScript.ExpressionStatement(expression);
            this.setSpan(result, start, node);

            result.setPreComments(preComments);
            result.setPostComments(postComments);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitConstructorDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.callSignature);
            var callSignature = this.visitCallSignature(node.callSignature);

            var block = node.block ? node.block.accept(this) : null;

            this.movePast(node.semicolonToken);

            var result = new TypeScript.ConstructorDeclaration(callSignature, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitIndexMemberDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.indexSignature);
            var indexSignature = node.indexSignature.accept(this);

            this.movePast(node.semicolonToken);

            var result = new TypeScript.IndexMemberDeclaration(indexSignature);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitMemberFunctionDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.propertyName);
            var name = this.visitToken(node.propertyName);

            var callSignature = this.visitCallSignature(node.callSignature);
            var block = node.block ? this.visitBlock(node.block) : null;
            this.movePast(node.semicolonToken);

            var result = new TypeScript.MemberFunctionDeclaration(this.visitModifiers(node.modifiers), name, callSignature, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitGetAccessor = function (node) {
            var start = this.position;

            this.moveTo(node, node.propertyName);
            var name = this.visitToken(node.propertyName);
            var parameters = this.visitParameterList(node.parameterList);
            var returnType = this.visitTypeAnnotation(node.typeAnnotation);

            var block = node.block ? node.block.accept(this) : null;
            var result = new TypeScript.GetAccessor(this.visitModifiers(node.modifiers), name, parameters, returnType, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitSetAccessor = function (node) {
            var start = this.position;

            this.moveTo(node, node.propertyName);
            var name = this.visitToken(node.propertyName);
            var parameters = this.visitParameterList(node.parameterList);
            var block = node.block ? node.block.accept(this) : null;
            var result = new TypeScript.SetAccessor(this.visitModifiers(node.modifiers), name, parameters, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitMemberVariableDeclaration = function (node) {
            var start = this.position;

            this.moveTo(node, node.variableDeclarator);
            var variableDeclarator = node.variableDeclarator.accept(this);
            this.movePast(node.semicolonToken);

            var modifiers = this.visitModifiers(node.modifiers);
            var result = new TypeScript.MemberVariableDeclaration(modifiers, variableDeclarator);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitThrowStatement = function (node) {
            var start = this.position;

            this.movePast(node.throwKeyword);
            var expression = node.expression.accept(this);
            this.movePast(node.semicolonToken);

            var result = new TypeScript.ThrowStatement(expression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitReturnStatement = function (node) {
            var start = this.position;

            this.movePast(node.returnKeyword);
            var expression = node.expression ? node.expression.accept(this) : null;
            this.movePast(node.semicolonToken);

            var result = new TypeScript.ReturnStatement(expression);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitObjectCreationExpression = function (node) {
            var start = this.position;

            this.movePast(node.newKeyword);
            var expression = node.expression.accept(this);
            var argumentList = this.visitArgumentList(node.argumentList);

            var result = new TypeScript.ObjectCreationExpression(expression, argumentList);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitSwitchStatement = function (node) {
            var start = this.position;

            this.movePast(node.switchKeyword);
            this.movePast(node.openParenToken);
            var expression = node.expression.accept(this);

            var closeParenToken = this.createTokenSpan(this.position, node.closeParenToken);
            this.movePast(node.closeParenToken);
            this.movePast(node.openBraceToken);
            var switchClauses = this.visitSyntaxList(node.switchClauses);
            this.movePast(node.closeBraceToken);

            var result = new TypeScript.SwitchStatement(expression, closeParenToken, switchClauses);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitCaseSwitchClause = function (node) {
            var start = this.position;

            this.movePast(node.caseKeyword);
            var expression = node.expression.accept(this);
            this.movePast(node.colonToken);
            var statements = this.visitSyntaxList(node.statements);

            var result = new TypeScript.CaseSwitchClause(expression, statements);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitDefaultSwitchClause = function (node) {
            var start = this.position;

            this.movePast(node.defaultKeyword);
            this.movePast(node.colonToken);
            var statements = this.visitSyntaxList(node.statements);

            var result = new TypeScript.DefaultSwitchClause(statements);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitBreakStatement = function (node) {
            var start = this.position;

            this.movePast(node.breakKeyword);
            var identifier = node.identifier ? node.identifier.accept(this) : null;
            this.movePast(node.semicolonToken);

            var result = new TypeScript.BreakStatement(identifier);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitContinueStatement = function (node) {
            var start = this.position;

            this.movePast(node.continueKeyword);
            var identifier = node.identifier ? node.identifier.accept(this) : null;
            this.movePast(node.semicolonToken);

            var result = new TypeScript.ContinueStatement(identifier);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitForStatement = function (node) {
            var start = this.position;

            this.movePast(node.forKeyword);
            this.movePast(node.openParenToken);
            var variableDeclaration = node.variableDeclaration ? node.variableDeclaration.accept(this) : null;
            var initializer = node.initializer ? node.initializer.accept(this) : null;

            this.movePast(node.firstSemicolonToken);
            var cond = node.condition ? node.condition.accept(this) : null;
            this.movePast(node.secondSemicolonToken);
            var incr = node.incrementor ? node.incrementor.accept(this) : null;
            this.movePast(node.closeParenToken);
            var body = node.statement.accept(this);

            var result = new TypeScript.ForStatement(variableDeclaration, initializer, cond, incr, body);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitForInStatement = function (node) {
            var start = this.position;

            this.movePast(node.forKeyword);
            this.movePast(node.openParenToken);
            var variableDeclaration = node.variableDeclaration ? node.variableDeclaration.accept(this) : null;
            var left = node.left ? node.left.accept(this) : null;

            this.movePast(node.inKeyword);
            var expression = node.expression.accept(this);
            this.movePast(node.closeParenToken);
            var body = node.statement.accept(this);

            var result = new TypeScript.ForInStatement(variableDeclaration, left, expression, body);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitWhileStatement = function (node) {
            var start = this.position;

            this.moveTo(node, node.condition);
            var condition = node.condition.accept(this);
            this.movePast(node.closeParenToken);
            var statement = node.statement.accept(this);

            var result = new TypeScript.WhileStatement(condition, statement);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitWithStatement = function (node) {
            var start = this.position;

            this.moveTo(node, node.condition);
            var condition = node.condition.accept(this);
            this.movePast(node.closeParenToken);
            var statement = node.statement.accept(this);

            var result = new TypeScript.WithStatement(condition, statement);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitCastExpression = function (node) {
            var start = this.position;

            this.movePast(node.lessThanToken);
            var castTerm = this.visitType(node.type);
            this.movePast(node.greaterThanToken);
            var expression = node.expression.accept(this);

            var result = new TypeScript.CastExpression(castTerm, expression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitObjectLiteralExpression = function (node) {
            var start = this.position;

            var openStart = this.position + node.openBraceToken.leadingTriviaWidth();
            this.movePast(node.openBraceToken);

            var propertyAssignments = this.visitSeparatedSyntaxList(node.propertyAssignments);

            var closeStart = this.position + node.closeBraceToken.leadingTriviaWidth();
            this.movePast(node.closeBraceToken);

            var result = new TypeScript.ObjectLiteralExpression(propertyAssignments);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitSimplePropertyAssignment = function (node) {
            var start = this.position;

            var preComments = this.convertTokenLeadingComments(node.firstToken(), start);
            var postComments = this.convertNodeTrailingComments(node, node.lastToken(), start);

            var propertyName = node.propertyName.accept(this);

            var afterColonComments = this.convertTokenTrailingComments(node.colonToken, this.position + node.colonToken.leadingTriviaWidth() + node.colonToken.width());

            this.movePast(node.colonToken);
            var expression = node.expression.accept(this);
            expression.setPreComments(this.mergeComments(afterColonComments, expression.preComments()));

            var result = new TypeScript.SimplePropertyAssignment(propertyName, expression);
            this.setSpan(result, start, node);

            result.setPreComments(preComments);
            result.setPostComments(postComments);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitFunctionPropertyAssignment = function (node) {
            var start = this.position;

            var propertyName = node.propertyName.accept(this);
            var callSignature = this.visitCallSignature(node.callSignature);
            var block = this.visitBlock(node.block);

            var result = new TypeScript.FunctionPropertyAssignment(propertyName, callSignature, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitFunctionExpression = function (node) {
            var start = this.position;

            this.movePast(node.functionKeyword);
            var name = node.identifier === null ? null : this.visitIdentifier(node.identifier);

            var callSignature = this.visitCallSignature(node.callSignature);
            var block = node.block ? node.block.accept(this) : null;

            var result = new TypeScript.FunctionExpression(name, callSignature, block);
            this.setCommentsAndSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitEmptyStatement = function (node) {
            var start = this.position;

            this.movePast(node.semicolonToken);

            var result = new TypeScript.EmptyStatement();
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTryStatement = function (node) {
            var start = this.position;

            this.movePast(node.tryKeyword);
            var tryBody = node.block.accept(this);

            var catchClause = null;
            if (node.catchClause !== null) {
                catchClause = node.catchClause.accept(this);
            }

            var finallyBody = null;
            if (node.finallyClause !== null) {
                finallyBody = node.finallyClause.accept(this);
            }

            var result = new TypeScript.TryStatement(tryBody, catchClause, finallyBody);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitCatchClause = function (node) {
            var start = this.position;

            this.movePast(node.catchKeyword);
            this.movePast(node.openParenToken);
            var identifier = this.visitIdentifier(node.identifier);
            var typeAnnotation = this.visitTypeAnnotation(node.typeAnnotation);
            this.movePast(node.closeParenToken);
            var block = node.block.accept(this);

            var result = new TypeScript.CatchClause(identifier, typeAnnotation, block);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitFinallyClause = function (node) {
            var start = this.position;
            this.movePast(node.finallyKeyword);
            var block = node.block.accept(this);

            var result = new TypeScript.FinallyClause(block);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitLabeledStatement = function (node) {
            var start = this.position;

            var identifier = this.visitIdentifier(node.identifier);
            this.movePast(node.colonToken);
            var statement = node.statement.accept(this);

            var result = new TypeScript.LabeledStatement(identifier, statement);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitDoStatement = function (node) {
            var start = this.position;

            this.movePast(node.doKeyword);
            var statement = node.statement.accept(this);
            var whileKeyword = this.createTokenSpan(this.position, node.whileKeyword);

            this.movePast(node.whileKeyword);
            this.movePast(node.openParenToken);
            var condition = node.condition.accept(this);
            this.movePast(node.closeParenToken);
            this.movePast(node.semicolonToken);

            var result = new TypeScript.DoStatement(statement, whileKeyword, condition);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitTypeOfExpression = function (node) {
            var start = this.position;

            this.movePast(node.typeOfKeyword);
            var expression = node.expression.accept(this);

            var result = new TypeScript.TypeOfExpression(expression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitDeleteExpression = function (node) {
            var start = this.position;

            this.movePast(node.deleteKeyword);
            var expression = node.expression.accept(this);

            var result = new TypeScript.DeleteExpression(expression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitVoidExpression = function (node) {
            var start = this.position;

            this.movePast(node.voidKeyword);
            var expression = node.expression.accept(this);

            var result = new TypeScript.VoidExpression(expression);
            this.setSpan(result, start, node);

            return result;
        };

        SyntaxTreeToAstVisitor.prototype.visitDebuggerStatement = function (node) {
            var start = this.position;

            this.movePast(node.debuggerKeyword);
            this.movePast(node.semicolonToken);

            var result = new TypeScript.DebuggerStatement();
            this.setSpan(result, start, node);

            return result;
        };
        return SyntaxTreeToAstVisitor;
    })();
    TypeScript.SyntaxTreeToAstVisitor = SyntaxTreeToAstVisitor;

    function applyDelta(ast, delta) {
        if (ast) {
            if (ast._start !== -1) {
                ast._start += delta;
            }

            if (ast._end !== -1) {
                ast._end += delta;
            }
        }
    }

    function applyDeltaToComments(comments, delta) {
        if (comments && comments.length > 0) {
            for (var i = 0; i < comments.length; i++) {
                var comment = comments[i];
                applyDelta(comment, delta);
            }
        }
    }

    var SyntaxTreeToIncrementalAstVisitor = (function (_super) {
        __extends(SyntaxTreeToIncrementalAstVisitor, _super);
        function SyntaxTreeToIncrementalAstVisitor() {
            _super.apply(this, arguments);
        }
        SyntaxTreeToIncrementalAstVisitor.prototype.applyDelta = function (ast, delta) {
            if (delta === 0) {
                return;
            }

            var pre = function (cur) {
                applyDelta(cur, delta);
                applyDeltaToComments(cur.preComments(), delta);
                applyDeltaToComments(cur.postComments(), delta);

                switch (cur.kind()) {
                    case 146 /* Block */:
                        applyDelta(cur.closeBraceToken, delta);
                        break;

                    case 226 /* ArgumentList */:
                        applyDelta(cur.closeParenToken, delta);
                        break;

                    case 130 /* ModuleDeclaration */:
                        applyDelta(cur.endingToken, delta);
                        break;

                    case 131 /* ClassDeclaration */:
                        applyDelta(cur.closeBraceToken, delta);
                        break;

                    case 161 /* DoStatement */:
                        applyDelta(cur.whileKeyword, delta);
                        break;

                    case 151 /* SwitchStatement */:
                        applyDelta(cur.closeParenToken, delta);
                        break;
                }
            };

            TypeScript.getAstWalkerFactory().simpleWalk(ast, pre);
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.setSpanExplicit = function (span, start, end) {
            if (span._start !== -1) {
                var delta = start - span._start;
                this.applyDelta(span, delta);

                span._end = end;
            } else {
                _super.prototype.setSpanExplicit.call(this, span, start, end);
            }
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.getAndMovePastAST = function (element) {
            if (this.previousTokenTrailingComments !== null) {
                return null;
            }

            var result = element._ast;
            if (!result) {
                return null;
            }

            var start = this.position;
            this.movePast(element);
            this.setSpan(result, start, element);
            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.setAST = function (element, ast) {
            element._ast = ast;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitSyntaxList = function (list) {
            var result = this.getAndMovePastAST(list);
            if (!result) {
                result = _super.prototype.visitSyntaxList.call(this, list);

                if (list.childCount() > 0) {
                    this.setAST(list, result);
                }
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitSeparatedSyntaxList = function (list) {
            var result = this.getAndMovePastAST(list);
            if (!result) {
                result = _super.prototype.visitSeparatedSyntaxList.call(this, list);

                if (list.childCount() > 0) {
                    this.setAST(list, result);
                }
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitToken = function (token) {
            var result = this.getAndMovePastAST(token);

            if (!result) {
                result = _super.prototype.visitToken.call(this, token);
                this.setAST(token, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitClassDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitClassDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitInterfaceDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitInterfaceDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitHeritageClause = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitHeritageClause.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitModuleDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitModuleDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitFunctionDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitFunctionDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitImportDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitImportDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitExportAssignment = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitExportAssignment.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitPrefixUnaryExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitPrefixUnaryExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitArrayLiteralExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitArrayLiteralExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitOmittedExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitOmittedExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitParenthesizedExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitParenthesizedExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitSimpleArrowFunctionExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitSimpleArrowFunctionExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitParenthesizedArrowFunctionExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitParenthesizedArrowFunctionExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitQualifiedName = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                var result = _super.prototype.visitQualifiedName.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitConstructorType = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitConstructorType.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitFunctionType = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitFunctionType.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitObjectType = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitObjectType.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitArrayType = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitArrayType.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitGenericType = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitGenericType.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitBlock = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitBlock.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitParameter = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitParameter.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitMemberAccessExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitMemberAccessExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitPostfixUnaryExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitPostfixUnaryExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitElementAccessExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitElementAccessExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitInvocationExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitInvocationExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitBinaryExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitBinaryExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitConditionalExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitConditionalExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitConstructSignature = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitConstructSignature.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitMethodSignature = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitMethodSignature.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitIndexSignature = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitIndexSignature.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitPropertySignature = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitPropertySignature.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitCallSignature = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitCallSignature.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitTypeParameter = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitTypeParameter.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitIfStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitIfStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitExpressionStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitExpressionStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitConstructorDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitConstructorDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitMemberFunctionDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitMemberFunctionDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitGetAccessor = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitGetAccessor.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitSetAccessor = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitSetAccessor.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitMemberVariableDeclaration = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitMemberVariableDeclaration.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitThrowStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitThrowStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitReturnStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitReturnStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitObjectCreationExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitObjectCreationExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitSwitchStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitSwitchStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitCaseSwitchClause = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitCaseSwitchClause.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitDefaultSwitchClause = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitDefaultSwitchClause.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitBreakStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitBreakStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitContinueStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitContinueStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitForStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitForStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitForInStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitForInStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitWhileStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitWhileStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitWithStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitWithStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitCastExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitCastExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitObjectLiteralExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitObjectLiteralExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitSimplePropertyAssignment = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitSimplePropertyAssignment.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitFunctionPropertyAssignment = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitFunctionPropertyAssignment.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitFunctionExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitFunctionExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitEmptyStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitEmptyStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitTryStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitTryStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitCatchClause = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitCatchClause.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitLabeledStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitLabeledStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitDoStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitDoStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitTypeOfExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitTypeOfExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitDeleteExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitDeleteExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitVoidExpression = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitVoidExpression.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };

        SyntaxTreeToIncrementalAstVisitor.prototype.visitDebuggerStatement = function (node) {
            var result = this.getAndMovePastAST(node);
            if (!result) {
                result = _super.prototype.visitDebuggerStatement.call(this, node);
                this.setAST(node, result);
            }

            return result;
        };
        return SyntaxTreeToIncrementalAstVisitor;
    })(SyntaxTreeToAstVisitor);
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var ASTSpan = (function () {
        function ASTSpan(_start, _end) {
            this._start = _start;
            this._end = _end;
        }
        ASTSpan.prototype.start = function () {
            return this._start;
        };

        ASTSpan.prototype.end = function () {
            return this._end;
        };
        return ASTSpan;
    })();
    TypeScript.ASTSpan = ASTSpan;

    var astID = 0;

    function structuralEqualsNotIncludingPosition(ast1, ast2) {
        return structuralEquals(ast1, ast2, false);
    }
    TypeScript.structuralEqualsNotIncludingPosition = structuralEqualsNotIncludingPosition;

    function structuralEqualsIncludingPosition(ast1, ast2) {
        return structuralEquals(ast1, ast2, true);
    }
    TypeScript.structuralEqualsIncludingPosition = structuralEqualsIncludingPosition;

    function commentStructuralEqualsNotIncludingPosition(ast1, ast2) {
        return commentStructuralEquals(ast1, ast2, false);
    }

    function commentStructuralEqualsIncludingPosition(ast1, ast2) {
        return commentStructuralEquals(ast1, ast2, true);
    }

    function structuralEquals(ast1, ast2, includingPosition) {
        if (ast1 === ast2) {
            return true;
        }

        return ast1 !== null && ast2 !== null && ast1.kind() === ast2.kind() && ast1.structuralEquals(ast2, includingPosition);
    }

    function commentStructuralEquals(ast1, ast2, includingPosition) {
        if (ast1 === ast2) {
            return true;
        }

        return ast1 !== null && ast2 !== null && ast1.structuralEquals(ast2, includingPosition);
    }

    function astArrayStructuralEquals(array1, array2, includingPosition) {
        return TypeScript.ArrayUtilities.sequenceEquals(array1, array2, includingPosition ? structuralEqualsIncludingPosition : structuralEqualsNotIncludingPosition);
    }

    function commentArrayStructuralEquals(array1, array2, includingPosition) {
        return TypeScript.ArrayUtilities.sequenceEquals(array1, array2, includingPosition ? commentStructuralEqualsIncludingPosition : commentStructuralEqualsNotIncludingPosition);
    }

    var AST = (function () {
        function AST() {
            this.parent = null;
            this._start = -1;
            this._end = -1;
            this._trailingTriviaWidth = 0;
            this._astID = astID++;
            this._preComments = null;
            this._postComments = null;
        }
        AST.prototype.syntaxID = function () {
            return this._astID;
        };

        AST.prototype.start = function () {
            return this._start;
        };

        AST.prototype.end = function () {
            return this._end;
        };

        AST.prototype.trailingTriviaWidth = function () {
            return this._trailingTriviaWidth;
        };

        AST.prototype.fileName = function () {
            return this.parent.fileName();
        };

        AST.prototype.kind = function () {
            throw TypeScript.Errors.abstract();
        };

        AST.prototype.preComments = function () {
            return this._preComments;
        };

        AST.prototype.postComments = function () {
            return this._postComments;
        };

        AST.prototype.setPreComments = function (comments) {
            if (comments && comments.length) {
                this._preComments = comments;
            } else if (this._preComments) {
                this._preComments = null;
            }
        };

        AST.prototype.setPostComments = function (comments) {
            if (comments && comments.length) {
                this._postComments = comments;
            } else if (this._postComments) {
                this._postComments = null;
            }
        };

        AST.prototype.width = function () {
            return this.end() - this.start();
        };

        AST.prototype.structuralEquals = function (ast, includingPosition) {
            if (includingPosition) {
                if (this.start() !== ast.start() || this.end() !== ast.end()) {
                    return false;
                }
            }

            return commentArrayStructuralEquals(this.preComments(), ast.preComments(), includingPosition) && commentArrayStructuralEquals(this.postComments(), ast.postComments(), includingPosition);
        };

        AST.prototype.isExpression = function () {
            return false;
        };
        return AST;
    })();
    TypeScript.AST = AST;

    var ISyntaxList2 = (function (_super) {
        __extends(ISyntaxList2, _super);
        function ISyntaxList2(_fileName, members) {
            _super.call(this);
            this._fileName = _fileName;
            this.members = members;

            for (var i = 0, n = members.length; i < n; i++) {
                members[i].parent = this;
            }
        }
        ISyntaxList2.prototype.childCount = function () {
            return this.members.length;
        };

        ISyntaxList2.prototype.childAt = function (index) {
            return this.members[index];
        };

        ISyntaxList2.prototype.fileName = function () {
            return this._fileName;
        };

        ISyntaxList2.prototype.kind = function () {
            return 1 /* List */;
        };

        ISyntaxList2.prototype.firstOrDefault = function (func) {
            return TypeScript.ArrayUtilities.firstOrDefault(this.members, func);
        };

        ISyntaxList2.prototype.lastOrDefault = function (func) {
            return TypeScript.ArrayUtilities.lastOrDefault(this.members, func);
        };

        ISyntaxList2.prototype.any = function (func) {
            return TypeScript.ArrayUtilities.any(this.members, func);
        };

        ISyntaxList2.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && astArrayStructuralEquals(this.members, ast.members, includingPosition);
        };
        return ISyntaxList2;
    })(AST);
    TypeScript.ISyntaxList2 = ISyntaxList2;

    var ISeparatedSyntaxList2 = (function (_super) {
        __extends(ISeparatedSyntaxList2, _super);
        function ISeparatedSyntaxList2(_fileName, members, _separatorCount) {
            _super.call(this);
            this._fileName = _fileName;
            this.members = members;
            this._separatorCount = _separatorCount;

            for (var i = 0, n = members.length; i < n; i++) {
                members[i].parent = this;
            }
        }
        ISeparatedSyntaxList2.prototype.nonSeparatorCount = function () {
            return this.members.length;
        };

        ISeparatedSyntaxList2.prototype.separatorCount = function () {
            return this._separatorCount;
        };

        ISeparatedSyntaxList2.prototype.nonSeparatorAt = function (index) {
            return this.members[index];
        };

        ISeparatedSyntaxList2.prototype.nonSeparatorIndexOf = function (ast) {
            for (var i = 0, n = this.nonSeparatorCount(); i < n; i++) {
                if (this.nonSeparatorAt(i) === ast) {
                    return i;
                }
            }

            return -1;
        };

        ISeparatedSyntaxList2.prototype.fileName = function () {
            return this._fileName;
        };

        ISeparatedSyntaxList2.prototype.kind = function () {
            return 2 /* SeparatedList */;
        };

        ISeparatedSyntaxList2.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && astArrayStructuralEquals(this.members, ast.members, includingPosition);
        };
        return ISeparatedSyntaxList2;
    })(AST);
    TypeScript.ISeparatedSyntaxList2 = ISeparatedSyntaxList2;

    var SourceUnit = (function (_super) {
        __extends(SourceUnit, _super);
        function SourceUnit(moduleElements, endOfFileTokenLeadingComments, _fileName) {
            _super.call(this);
            this.moduleElements = moduleElements;
            this.endOfFileTokenLeadingComments = endOfFileTokenLeadingComments;
            this._fileName = _fileName;
            moduleElements && (moduleElements.parent = this);
        }
        SourceUnit.prototype.fileName = function () {
            return this._fileName;
        };

        SourceUnit.prototype.kind = function () {
            return 120 /* SourceUnit */;
        };

        SourceUnit.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.moduleElements, ast.moduleElements, includingPosition);
        };
        return SourceUnit;
    })(AST);
    TypeScript.SourceUnit = SourceUnit;

    var Identifier = (function (_super) {
        __extends(Identifier, _super);
        function Identifier(_text) {
            _super.call(this);
            this._text = _text;
            this._valueText = null;
        }
        Identifier.prototype.text = function () {
            return this._text;
        };
        Identifier.prototype.valueText = function () {
            if (!this._valueText) {
                var text = this._text;
                if (text === "__proto__") {
                    this._valueText = "#__proto__";
                } else {
                    this._valueText = TypeScript.Syntax.massageEscapes(text);
                }
            }

            return this._valueText;
        };

        Identifier.prototype.kind = function () {
            return 11 /* IdentifierName */;
        };

        Identifier.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && this._text === ast._text;
        };

        Identifier.prototype.isExpression = function () {
            return true;
        };
        return Identifier;
    })(AST);
    TypeScript.Identifier = Identifier;

    var LiteralExpression = (function (_super) {
        __extends(LiteralExpression, _super);
        function LiteralExpression(_nodeType, _text, _valueText) {
            _super.call(this);
            this._nodeType = _nodeType;
            this._text = _text;
            this._valueText = _valueText;
        }
        LiteralExpression.prototype.text = function () {
            return this._text;
        };

        LiteralExpression.prototype.valueText = function () {
            return this._valueText;
        };

        LiteralExpression.prototype.kind = function () {
            return this._nodeType;
        };

        LiteralExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };

        LiteralExpression.prototype.isExpression = function () {
            return true;
        };
        return LiteralExpression;
    })(AST);
    TypeScript.LiteralExpression = LiteralExpression;

    var ThisExpression = (function (_super) {
        __extends(ThisExpression, _super);
        function ThisExpression(_text, _valueText) {
            _super.call(this);
            this._text = _text;
            this._valueText = _valueText;
        }
        ThisExpression.prototype.text = function () {
            return this._text;
        };

        ThisExpression.prototype.valueText = function () {
            return this._valueText;
        };

        ThisExpression.prototype.kind = function () {
            return 35 /* ThisKeyword */;
        };

        ThisExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };

        ThisExpression.prototype.isExpression = function () {
            return true;
        };
        return ThisExpression;
    })(AST);
    TypeScript.ThisExpression = ThisExpression;

    var SuperExpression = (function (_super) {
        __extends(SuperExpression, _super);
        function SuperExpression(_text, _valueText) {
            _super.call(this);
            this._text = _text;
            this._valueText = _valueText;
        }
        SuperExpression.prototype.text = function () {
            return this._text;
        };

        SuperExpression.prototype.valueText = function () {
            return this._valueText;
        };

        SuperExpression.prototype.kind = function () {
            return 50 /* SuperKeyword */;
        };

        SuperExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };

        SuperExpression.prototype.isExpression = function () {
            return true;
        };
        return SuperExpression;
    })(AST);
    TypeScript.SuperExpression = SuperExpression;

    var NumericLiteral = (function (_super) {
        __extends(NumericLiteral, _super);
        function NumericLiteral(_value, _text, _valueText) {
            _super.call(this);
            this._value = _value;
            this._text = _text;
            this._valueText = _valueText;
        }
        NumericLiteral.prototype.text = function () {
            return this._text;
        };
        NumericLiteral.prototype.valueText = function () {
            return this._valueText;
        };
        NumericLiteral.prototype.value = function () {
            return this._value;
        };

        NumericLiteral.prototype.kind = function () {
            return 13 /* NumericLiteral */;
        };

        NumericLiteral.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && (this._value === ast._value || (isNaN(this._value) && isNaN(ast._value))) && this._text === ast._text;
        };

        NumericLiteral.prototype.isExpression = function () {
            return true;
        };
        return NumericLiteral;
    })(AST);
    TypeScript.NumericLiteral = NumericLiteral;

    var RegularExpressionLiteral = (function (_super) {
        __extends(RegularExpressionLiteral, _super);
        function RegularExpressionLiteral(_text, _valueText) {
            _super.call(this);
            this._text = _text;
            this._valueText = _valueText;
        }
        RegularExpressionLiteral.prototype.text = function () {
            return this._text;
        };

        RegularExpressionLiteral.prototype.valueText = function () {
            return this._valueText;
        };

        RegularExpressionLiteral.prototype.kind = function () {
            return 12 /* RegularExpressionLiteral */;
        };

        RegularExpressionLiteral.prototype.isExpression = function () {
            return true;
        };
        return RegularExpressionLiteral;
    })(AST);
    TypeScript.RegularExpressionLiteral = RegularExpressionLiteral;

    var StringLiteral = (function (_super) {
        __extends(StringLiteral, _super);
        function StringLiteral(_text, _valueText) {
            _super.call(this);
            this._text = _text;
            this._valueText = _valueText;
            this._valueText = _valueText === "__proto__" ? "#__proto__" : _valueText;
        }
        StringLiteral.prototype.text = function () {
            return this._text;
        };
        StringLiteral.prototype.valueText = function () {
            return this._valueText;
        };

        StringLiteral.prototype.kind = function () {
            return 14 /* StringLiteral */;
        };

        StringLiteral.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && this._text === ast._text;
        };

        StringLiteral.prototype.isExpression = function () {
            return true;
        };
        return StringLiteral;
    })(AST);
    TypeScript.StringLiteral = StringLiteral;

    var TypeAnnotation = (function (_super) {
        __extends(TypeAnnotation, _super);
        function TypeAnnotation(type) {
            _super.call(this);
            this.type = type;
            type && (type.parent = this);
        }
        TypeAnnotation.prototype.kind = function () {
            return 244 /* TypeAnnotation */;
        };
        return TypeAnnotation;
    })(AST);
    TypeScript.TypeAnnotation = TypeAnnotation;

    var BuiltInType = (function (_super) {
        __extends(BuiltInType, _super);
        function BuiltInType(_nodeType, _text, _valueText) {
            _super.call(this);
            this._nodeType = _nodeType;
            this._text = _text;
            this._valueText = _valueText;
        }
        BuiltInType.prototype.text = function () {
            return this._text;
        };

        BuiltInType.prototype.valueText = function () {
            return this._valueText;
        };

        BuiltInType.prototype.kind = function () {
            return this._nodeType;
        };
        return BuiltInType;
    })(AST);
    TypeScript.BuiltInType = BuiltInType;

    var ExternalModuleReference = (function (_super) {
        __extends(ExternalModuleReference, _super);
        function ExternalModuleReference(stringLiteral) {
            _super.call(this);
            this.stringLiteral = stringLiteral;
            stringLiteral && (stringLiteral.parent = this);
        }
        ExternalModuleReference.prototype.kind = function () {
            return 245 /* ExternalModuleReference */;
        };
        return ExternalModuleReference;
    })(AST);
    TypeScript.ExternalModuleReference = ExternalModuleReference;

    var ModuleNameModuleReference = (function (_super) {
        __extends(ModuleNameModuleReference, _super);
        function ModuleNameModuleReference(moduleName) {
            _super.call(this);
            this.moduleName = moduleName;
            moduleName && (moduleName.parent = this);
        }
        ModuleNameModuleReference.prototype.kind = function () {
            return 246 /* ModuleNameModuleReference */;
        };
        return ModuleNameModuleReference;
    })(AST);
    TypeScript.ModuleNameModuleReference = ModuleNameModuleReference;

    var ImportDeclaration = (function (_super) {
        __extends(ImportDeclaration, _super);
        function ImportDeclaration(modifiers, identifier, moduleReference) {
            _super.call(this);
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.moduleReference = moduleReference;
            identifier && (identifier.parent = this);
            moduleReference && (moduleReference.parent = this);
        }
        ImportDeclaration.prototype.kind = function () {
            return 133 /* ImportDeclaration */;
        };

        ImportDeclaration.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.moduleReference, ast.moduleReference, includingPosition);
        };
        return ImportDeclaration;
    })(AST);
    TypeScript.ImportDeclaration = ImportDeclaration;

    var ExportAssignment = (function (_super) {
        __extends(ExportAssignment, _super);
        function ExportAssignment(identifier) {
            _super.call(this);
            this.identifier = identifier;
            identifier && (identifier.parent = this);
        }
        ExportAssignment.prototype.kind = function () {
            return 134 /* ExportAssignment */;
        };

        ExportAssignment.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition);
        };
        return ExportAssignment;
    })(AST);
    TypeScript.ExportAssignment = ExportAssignment;

    var TypeParameterList = (function (_super) {
        __extends(TypeParameterList, _super);
        function TypeParameterList(typeParameters) {
            _super.call(this);
            this.typeParameters = typeParameters;
            typeParameters && (typeParameters.parent = this);
        }
        TypeParameterList.prototype.kind = function () {
            return 229 /* TypeParameterList */;
        };
        return TypeParameterList;
    })(AST);
    TypeScript.TypeParameterList = TypeParameterList;

    var ClassDeclaration = (function (_super) {
        __extends(ClassDeclaration, _super);
        function ClassDeclaration(modifiers, identifier, typeParameterList, heritageClauses, classElements, closeBraceToken) {
            _super.call(this);
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.typeParameterList = typeParameterList;
            this.heritageClauses = heritageClauses;
            this.classElements = classElements;
            this.closeBraceToken = closeBraceToken;
            identifier && (identifier.parent = this);
            typeParameterList && (typeParameterList.parent = this);
            heritageClauses && (heritageClauses.parent = this);
            classElements && (classElements.parent = this);
        }
        ClassDeclaration.prototype.kind = function () {
            return 131 /* ClassDeclaration */;
        };

        ClassDeclaration.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.classElements, ast.classElements, includingPosition) && structuralEquals(this.typeParameterList, ast.typeParameterList, includingPosition) && structuralEquals(this.heritageClauses, ast.heritageClauses, includingPosition);
        };
        return ClassDeclaration;
    })(AST);
    TypeScript.ClassDeclaration = ClassDeclaration;

    var InterfaceDeclaration = (function (_super) {
        __extends(InterfaceDeclaration, _super);
        function InterfaceDeclaration(modifiers, identifier, typeParameterList, heritageClauses, body) {
            _super.call(this);
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.typeParameterList = typeParameterList;
            this.heritageClauses = heritageClauses;
            this.body = body;
            identifier && (identifier.parent = this);
            typeParameterList && (typeParameterList.parent = this);
            body && (body.parent = this);
            heritageClauses && (heritageClauses.parent = this);
        }
        InterfaceDeclaration.prototype.kind = function () {
            return 128 /* InterfaceDeclaration */;
        };

        InterfaceDeclaration.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.body, ast.body, includingPosition) && structuralEquals(this.typeParameterList, ast.typeParameterList, includingPosition) && structuralEquals(this.heritageClauses, ast.heritageClauses, includingPosition);
        };
        return InterfaceDeclaration;
    })(AST);
    TypeScript.InterfaceDeclaration = InterfaceDeclaration;

    var HeritageClause = (function (_super) {
        __extends(HeritageClause, _super);
        function HeritageClause(_nodeType, typeNames) {
            _super.call(this);
            this._nodeType = _nodeType;
            this.typeNames = typeNames;
            typeNames && (typeNames.parent = this);
        }
        HeritageClause.prototype.kind = function () {
            return this._nodeType;
        };

        HeritageClause.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.typeNames, ast.typeNames, includingPosition);
        };
        return HeritageClause;
    })(AST);
    TypeScript.HeritageClause = HeritageClause;

    var ModuleDeclaration = (function (_super) {
        __extends(ModuleDeclaration, _super);
        function ModuleDeclaration(modifiers, name, stringLiteral, moduleElements, endingToken) {
            _super.call(this);
            this.modifiers = modifiers;
            this.name = name;
            this.stringLiteral = stringLiteral;
            this.moduleElements = moduleElements;
            this.endingToken = endingToken;
            name && (name.parent = this);
            stringLiteral && (stringLiteral.parent = this);
            moduleElements && (moduleElements.parent = this);
        }
        ModuleDeclaration.prototype.kind = function () {
            return 130 /* ModuleDeclaration */;
        };

        ModuleDeclaration.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.name, ast.name, includingPosition) && structuralEquals(this.moduleElements, ast.moduleElements, includingPosition);
        };
        return ModuleDeclaration;
    })(AST);
    TypeScript.ModuleDeclaration = ModuleDeclaration;

    var FunctionDeclaration = (function (_super) {
        __extends(FunctionDeclaration, _super);
        function FunctionDeclaration(modifiers, identifier, callSignature, block) {
            _super.call(this);
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.callSignature = callSignature;
            this.block = block;
            identifier && (identifier.parent = this);
            callSignature && (callSignature.parent = this);
            block && (block.parent = this);
        }
        FunctionDeclaration.prototype.kind = function () {
            return 129 /* FunctionDeclaration */;
        };

        FunctionDeclaration.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.block, ast.block, includingPosition) && structuralEquals(this.callSignature, ast.callSignature, includingPosition);
        };
        return FunctionDeclaration;
    })(AST);
    TypeScript.FunctionDeclaration = FunctionDeclaration;

    var VariableStatement = (function (_super) {
        __extends(VariableStatement, _super);
        function VariableStatement(modifiers, declaration) {
            _super.call(this);
            this.modifiers = modifiers;
            this.declaration = declaration;
            declaration && (declaration.parent = this);
        }
        VariableStatement.prototype.kind = function () {
            return 148 /* VariableStatement */;
        };

        VariableStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.declaration, ast.declaration, includingPosition);
        };
        return VariableStatement;
    })(AST);
    TypeScript.VariableStatement = VariableStatement;

    var VariableDeclaration = (function (_super) {
        __extends(VariableDeclaration, _super);
        function VariableDeclaration(declarators) {
            _super.call(this);
            this.declarators = declarators;
            declarators && (declarators.parent = this);
        }
        VariableDeclaration.prototype.kind = function () {
            return 224 /* VariableDeclaration */;
        };

        VariableDeclaration.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.declarators, ast.declarators, includingPosition);
        };
        return VariableDeclaration;
    })(AST);
    TypeScript.VariableDeclaration = VariableDeclaration;

    var VariableDeclarator = (function (_super) {
        __extends(VariableDeclarator, _super);
        function VariableDeclarator(propertyName, typeAnnotation, equalsValueClause) {
            _super.call(this);
            this.propertyName = propertyName;
            this.typeAnnotation = typeAnnotation;
            this.equalsValueClause = equalsValueClause;
            propertyName && (propertyName.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
            equalsValueClause && (equalsValueClause.parent = this);
        }
        VariableDeclarator.prototype.kind = function () {
            return 225 /* VariableDeclarator */;
        };
        return VariableDeclarator;
    })(AST);
    TypeScript.VariableDeclarator = VariableDeclarator;

    var EqualsValueClause = (function (_super) {
        __extends(EqualsValueClause, _super);
        function EqualsValueClause(value) {
            _super.call(this);
            this.value = value;
            value && (value.parent = this);
        }
        EqualsValueClause.prototype.kind = function () {
            return 232 /* EqualsValueClause */;
        };
        return EqualsValueClause;
    })(AST);
    TypeScript.EqualsValueClause = EqualsValueClause;

    var PrefixUnaryExpression = (function (_super) {
        __extends(PrefixUnaryExpression, _super);
        function PrefixUnaryExpression(_nodeType, operand) {
            _super.call(this);
            this._nodeType = _nodeType;
            this.operand = operand;
            operand && (operand.parent = this);
        }
        PrefixUnaryExpression.prototype.kind = function () {
            return this._nodeType;
        };

        PrefixUnaryExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.operand, ast.operand, includingPosition);
        };

        PrefixUnaryExpression.prototype.isExpression = function () {
            return true;
        };
        return PrefixUnaryExpression;
    })(AST);
    TypeScript.PrefixUnaryExpression = PrefixUnaryExpression;

    var ArrayLiteralExpression = (function (_super) {
        __extends(ArrayLiteralExpression, _super);
        function ArrayLiteralExpression(expressions) {
            _super.call(this);
            this.expressions = expressions;
            expressions && (expressions.parent = this);
        }
        ArrayLiteralExpression.prototype.kind = function () {
            return 214 /* ArrayLiteralExpression */;
        };

        ArrayLiteralExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expressions, ast.expressions, includingPosition);
        };

        ArrayLiteralExpression.prototype.isExpression = function () {
            return true;
        };
        return ArrayLiteralExpression;
    })(AST);
    TypeScript.ArrayLiteralExpression = ArrayLiteralExpression;

    var OmittedExpression = (function (_super) {
        __extends(OmittedExpression, _super);
        function OmittedExpression() {
            _super.apply(this, arguments);
        }
        OmittedExpression.prototype.kind = function () {
            return 223 /* OmittedExpression */;
        };

        OmittedExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };

        OmittedExpression.prototype.isExpression = function () {
            return true;
        };
        return OmittedExpression;
    })(AST);
    TypeScript.OmittedExpression = OmittedExpression;

    var ParenthesizedExpression = (function (_super) {
        __extends(ParenthesizedExpression, _super);
        function ParenthesizedExpression(openParenTrailingComments, expression) {
            _super.call(this);
            this.openParenTrailingComments = openParenTrailingComments;
            this.expression = expression;
            expression && (expression.parent = this);
        }
        ParenthesizedExpression.prototype.kind = function () {
            return 217 /* ParenthesizedExpression */;
        };

        ParenthesizedExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };

        ParenthesizedExpression.prototype.isExpression = function () {
            return true;
        };
        return ParenthesizedExpression;
    })(AST);
    TypeScript.ParenthesizedExpression = ParenthesizedExpression;

    var SimpleArrowFunctionExpression = (function (_super) {
        __extends(SimpleArrowFunctionExpression, _super);
        function SimpleArrowFunctionExpression(identifier, block, expression) {
            _super.call(this);
            this.identifier = identifier;
            this.block = block;
            this.expression = expression;
            identifier && (identifier.parent = this);
            block && (block.parent = this);
            expression && (expression.parent = this);
        }
        SimpleArrowFunctionExpression.prototype.kind = function () {
            return 219 /* SimpleArrowFunctionExpression */;
        };

        SimpleArrowFunctionExpression.prototype.isExpression = function () {
            return true;
        };
        return SimpleArrowFunctionExpression;
    })(AST);
    TypeScript.SimpleArrowFunctionExpression = SimpleArrowFunctionExpression;

    var ParenthesizedArrowFunctionExpression = (function (_super) {
        __extends(ParenthesizedArrowFunctionExpression, _super);
        function ParenthesizedArrowFunctionExpression(callSignature, block, expression) {
            _super.call(this);
            this.callSignature = callSignature;
            this.block = block;
            this.expression = expression;
            callSignature && (callSignature.parent = this);
            block && (block.parent = this);
            expression && (expression.parent = this);
        }
        ParenthesizedArrowFunctionExpression.prototype.kind = function () {
            return 218 /* ParenthesizedArrowFunctionExpression */;
        };

        ParenthesizedArrowFunctionExpression.prototype.isExpression = function () {
            return true;
        };
        return ParenthesizedArrowFunctionExpression;
    })(AST);
    TypeScript.ParenthesizedArrowFunctionExpression = ParenthesizedArrowFunctionExpression;

    var QualifiedName = (function (_super) {
        __extends(QualifiedName, _super);
        function QualifiedName(left, right) {
            _super.call(this);
            this.left = left;
            this.right = right;
            left && (left.parent = this);
            right && (right.parent = this);
        }
        QualifiedName.prototype.kind = function () {
            return 121 /* QualifiedName */;
        };

        QualifiedName.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.left, ast.left, includingPosition) && structuralEquals(this.right, ast.right, includingPosition);
        };
        return QualifiedName;
    })(AST);
    TypeScript.QualifiedName = QualifiedName;

    var ParameterList = (function (_super) {
        __extends(ParameterList, _super);
        function ParameterList(openParenTrailingComments, parameters) {
            _super.call(this);
            this.openParenTrailingComments = openParenTrailingComments;
            this.parameters = parameters;
            parameters && (parameters.parent = this);
        }
        ParameterList.prototype.kind = function () {
            return 227 /* ParameterList */;
        };
        return ParameterList;
    })(AST);
    TypeScript.ParameterList = ParameterList;

    var ConstructorType = (function (_super) {
        __extends(ConstructorType, _super);
        function ConstructorType(typeParameterList, parameterList, type) {
            _super.call(this);
            this.typeParameterList = typeParameterList;
            this.parameterList = parameterList;
            this.type = type;
            typeParameterList && (typeParameterList.parent = this);
            parameterList && (parameterList.parent = this);
            type && (type.parent = this);
        }
        ConstructorType.prototype.kind = function () {
            return 125 /* ConstructorType */;
        };
        return ConstructorType;
    })(AST);
    TypeScript.ConstructorType = ConstructorType;

    var FunctionType = (function (_super) {
        __extends(FunctionType, _super);
        function FunctionType(typeParameterList, parameterList, type) {
            _super.call(this);
            this.typeParameterList = typeParameterList;
            this.parameterList = parameterList;
            this.type = type;
            typeParameterList && (typeParameterList.parent = this);
            parameterList && (parameterList.parent = this);
            type && (type.parent = this);
        }
        FunctionType.prototype.kind = function () {
            return 123 /* FunctionType */;
        };
        return FunctionType;
    })(AST);
    TypeScript.FunctionType = FunctionType;

    var ObjectType = (function (_super) {
        __extends(ObjectType, _super);
        function ObjectType(typeMembers) {
            _super.call(this);
            this.typeMembers = typeMembers;
            typeMembers && (typeMembers.parent = this);
        }
        ObjectType.prototype.kind = function () {
            return 122 /* ObjectType */;
        };

        ObjectType.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.typeMembers, ast.typeMembers, includingPosition);
        };
        return ObjectType;
    })(AST);
    TypeScript.ObjectType = ObjectType;

    var ArrayType = (function (_super) {
        __extends(ArrayType, _super);
        function ArrayType(type) {
            _super.call(this);
            this.type = type;
            type && (type.parent = this);
        }
        ArrayType.prototype.kind = function () {
            return 124 /* ArrayType */;
        };

        ArrayType.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.type, ast.type, includingPosition);
        };
        return ArrayType;
    })(AST);
    TypeScript.ArrayType = ArrayType;

    var TypeArgumentList = (function (_super) {
        __extends(TypeArgumentList, _super);
        function TypeArgumentList(typeArguments) {
            _super.call(this);
            this.typeArguments = typeArguments;
            typeArguments && (typeArguments.parent = this);
        }
        TypeArgumentList.prototype.kind = function () {
            return 228 /* TypeArgumentList */;
        };
        return TypeArgumentList;
    })(AST);
    TypeScript.TypeArgumentList = TypeArgumentList;

    var GenericType = (function (_super) {
        __extends(GenericType, _super);
        function GenericType(name, typeArgumentList) {
            _super.call(this);
            this.name = name;
            this.typeArgumentList = typeArgumentList;
            name && (name.parent = this);
            typeArgumentList && (typeArgumentList.parent = this);
        }
        GenericType.prototype.kind = function () {
            return 126 /* GenericType */;
        };

        GenericType.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.name, ast.name, includingPosition) && structuralEquals(this.typeArgumentList, ast.typeArgumentList, includingPosition);
        };
        return GenericType;
    })(AST);
    TypeScript.GenericType = GenericType;

    var TypeQuery = (function (_super) {
        __extends(TypeQuery, _super);
        function TypeQuery(name) {
            _super.call(this);
            this.name = name;
            name && (name.parent = this);
        }
        TypeQuery.prototype.kind = function () {
            return 127 /* TypeQuery */;
        };

        TypeQuery.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.name, ast.name, includingPosition);
        };
        return TypeQuery;
    })(AST);
    TypeScript.TypeQuery = TypeQuery;

    var Block = (function (_super) {
        __extends(Block, _super);
        function Block(statements, closeBraceLeadingComments, closeBraceToken) {
            _super.call(this);
            this.statements = statements;
            this.closeBraceLeadingComments = closeBraceLeadingComments;
            this.closeBraceToken = closeBraceToken;
            statements && (statements.parent = this);
        }
        Block.prototype.kind = function () {
            return 146 /* Block */;
        };

        Block.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.statements, ast.statements, includingPosition);
        };
        return Block;
    })(AST);
    TypeScript.Block = Block;

    var Parameter = (function (_super) {
        __extends(Parameter, _super);
        function Parameter(dotDotDotToken, modifiers, identifier, questionToken, typeAnnotation, equalsValueClause) {
            _super.call(this);
            this.dotDotDotToken = dotDotDotToken;
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.questionToken = questionToken;
            this.typeAnnotation = typeAnnotation;
            this.equalsValueClause = equalsValueClause;
            identifier && (identifier.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
            equalsValueClause && (equalsValueClause.parent = this);
        }
        Parameter.prototype.kind = function () {
            return 242 /* Parameter */;
        };
        return Parameter;
    })(AST);
    TypeScript.Parameter = Parameter;

    var MemberAccessExpression = (function (_super) {
        __extends(MemberAccessExpression, _super);
        function MemberAccessExpression(expression, name) {
            _super.call(this);
            this.expression = expression;
            this.name = name;
            expression && (expression.parent = this);
            name && (name.parent = this);
        }
        MemberAccessExpression.prototype.kind = function () {
            return 212 /* MemberAccessExpression */;
        };

        MemberAccessExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition) && structuralEquals(this.name, ast.name, includingPosition);
        };

        MemberAccessExpression.prototype.isExpression = function () {
            return true;
        };
        return MemberAccessExpression;
    })(AST);
    TypeScript.MemberAccessExpression = MemberAccessExpression;

    var PostfixUnaryExpression = (function (_super) {
        __extends(PostfixUnaryExpression, _super);
        function PostfixUnaryExpression(_nodeType, operand) {
            _super.call(this);
            this._nodeType = _nodeType;
            this.operand = operand;
            operand && (operand.parent = this);
        }
        PostfixUnaryExpression.prototype.kind = function () {
            return this._nodeType;
        };

        PostfixUnaryExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.operand, ast.operand, includingPosition);
        };

        PostfixUnaryExpression.prototype.isExpression = function () {
            return true;
        };
        return PostfixUnaryExpression;
    })(AST);
    TypeScript.PostfixUnaryExpression = PostfixUnaryExpression;

    var ElementAccessExpression = (function (_super) {
        __extends(ElementAccessExpression, _super);
        function ElementAccessExpression(expression, argumentExpression) {
            _super.call(this);
            this.expression = expression;
            this.argumentExpression = argumentExpression;
            expression && (expression.parent = this);
            argumentExpression && (argumentExpression.parent = this);
        }
        ElementAccessExpression.prototype.kind = function () {
            return 221 /* ElementAccessExpression */;
        };

        ElementAccessExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition) && structuralEquals(this.argumentExpression, ast.argumentExpression, includingPosition);
        };

        ElementAccessExpression.prototype.isExpression = function () {
            return true;
        };
        return ElementAccessExpression;
    })(AST);
    TypeScript.ElementAccessExpression = ElementAccessExpression;

    var InvocationExpression = (function (_super) {
        __extends(InvocationExpression, _super);
        function InvocationExpression(expression, argumentList) {
            _super.call(this);
            this.expression = expression;
            this.argumentList = argumentList;
            expression && (expression.parent = this);
            argumentList && (argumentList.parent = this);
        }
        InvocationExpression.prototype.kind = function () {
            return 213 /* InvocationExpression */;
        };

        InvocationExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition) && structuralEquals(this.argumentList, ast.argumentList, includingPosition);
        };

        InvocationExpression.prototype.isExpression = function () {
            return true;
        };
        return InvocationExpression;
    })(AST);
    TypeScript.InvocationExpression = InvocationExpression;

    var ArgumentList = (function (_super) {
        __extends(ArgumentList, _super);
        function ArgumentList(typeArgumentList, _arguments, closeParenToken) {
            _super.call(this);
            this.typeArgumentList = typeArgumentList;
            this.closeParenToken = closeParenToken;
            this.arguments = _arguments;

            typeArgumentList && (typeArgumentList.parent = this);
            _arguments && (_arguments.parent = this);
        }
        ArgumentList.prototype.kind = function () {
            return 226 /* ArgumentList */;
        };
        return ArgumentList;
    })(AST);
    TypeScript.ArgumentList = ArgumentList;

    var BinaryExpression = (function (_super) {
        __extends(BinaryExpression, _super);
        function BinaryExpression(_nodeType, left, right) {
            _super.call(this);
            this._nodeType = _nodeType;
            this.left = left;
            this.right = right;
            left && (left.parent = this);
            right && (right.parent = this);
        }
        BinaryExpression.prototype.kind = function () {
            return this._nodeType;
        };

        BinaryExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.left, ast.left, includingPosition) && structuralEquals(this.right, ast.right, includingPosition);
        };

        BinaryExpression.prototype.isExpression = function () {
            return true;
        };
        return BinaryExpression;
    })(AST);
    TypeScript.BinaryExpression = BinaryExpression;

    var ConditionalExpression = (function (_super) {
        __extends(ConditionalExpression, _super);
        function ConditionalExpression(condition, whenTrue, whenFalse) {
            _super.call(this);
            this.condition = condition;
            this.whenTrue = whenTrue;
            this.whenFalse = whenFalse;
            condition && (condition.parent = this);
            whenTrue && (whenTrue.parent = this);
            whenFalse && (whenFalse.parent = this);
        }
        ConditionalExpression.prototype.kind = function () {
            return 186 /* ConditionalExpression */;
        };

        ConditionalExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.condition, ast.condition, includingPosition) && structuralEquals(this.whenTrue, ast.whenTrue, includingPosition) && structuralEquals(this.whenFalse, ast.whenFalse, includingPosition);
        };

        ConditionalExpression.prototype.isExpression = function () {
            return true;
        };
        return ConditionalExpression;
    })(AST);
    TypeScript.ConditionalExpression = ConditionalExpression;

    var ConstructSignature = (function (_super) {
        __extends(ConstructSignature, _super);
        function ConstructSignature(callSignature) {
            _super.call(this);
            this.callSignature = callSignature;
            callSignature && (callSignature.parent = this);
        }
        ConstructSignature.prototype.kind = function () {
            return 143 /* ConstructSignature */;
        };
        return ConstructSignature;
    })(AST);
    TypeScript.ConstructSignature = ConstructSignature;

    var MethodSignature = (function (_super) {
        __extends(MethodSignature, _super);
        function MethodSignature(propertyName, questionToken, callSignature) {
            _super.call(this);
            this.propertyName = propertyName;
            this.questionToken = questionToken;
            this.callSignature = callSignature;
            propertyName && (propertyName.parent = this);
            callSignature && (callSignature.parent = this);
        }
        MethodSignature.prototype.kind = function () {
            return 145 /* MethodSignature */;
        };
        return MethodSignature;
    })(AST);
    TypeScript.MethodSignature = MethodSignature;

    var IndexSignature = (function (_super) {
        __extends(IndexSignature, _super);
        function IndexSignature(parameter, typeAnnotation) {
            _super.call(this);
            this.parameter = parameter;
            this.typeAnnotation = typeAnnotation;
            parameter && (parameter.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
        }
        IndexSignature.prototype.kind = function () {
            return 144 /* IndexSignature */;
        };
        return IndexSignature;
    })(AST);
    TypeScript.IndexSignature = IndexSignature;

    var PropertySignature = (function (_super) {
        __extends(PropertySignature, _super);
        function PropertySignature(propertyName, questionToken, typeAnnotation) {
            _super.call(this);
            this.propertyName = propertyName;
            this.questionToken = questionToken;
            this.typeAnnotation = typeAnnotation;
            propertyName && (propertyName.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
        }
        PropertySignature.prototype.kind = function () {
            return 141 /* PropertySignature */;
        };
        return PropertySignature;
    })(AST);
    TypeScript.PropertySignature = PropertySignature;

    var CallSignature = (function (_super) {
        __extends(CallSignature, _super);
        function CallSignature(typeParameterList, parameterList, typeAnnotation) {
            _super.call(this);
            this.typeParameterList = typeParameterList;
            this.parameterList = parameterList;
            this.typeAnnotation = typeAnnotation;
            typeParameterList && (typeParameterList.parent = this);
            parameterList && (parameterList.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
        }
        CallSignature.prototype.kind = function () {
            return 142 /* CallSignature */;
        };
        return CallSignature;
    })(AST);
    TypeScript.CallSignature = CallSignature;

    var TypeParameter = (function (_super) {
        __extends(TypeParameter, _super);
        function TypeParameter(identifier, constraint) {
            _super.call(this);
            this.identifier = identifier;
            this.constraint = constraint;
            identifier && (identifier.parent = this);
            constraint && (constraint.parent = this);
        }
        TypeParameter.prototype.kind = function () {
            return 238 /* TypeParameter */;
        };

        TypeParameter.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.constraint, ast.constraint, includingPosition);
        };
        return TypeParameter;
    })(AST);
    TypeScript.TypeParameter = TypeParameter;

    var Constraint = (function (_super) {
        __extends(Constraint, _super);
        function Constraint(type) {
            _super.call(this);
            this.type = type;
            type && (type.parent = this);
        }
        Constraint.prototype.kind = function () {
            return 239 /* Constraint */;
        };
        return Constraint;
    })(AST);
    TypeScript.Constraint = Constraint;

    var ElseClause = (function (_super) {
        __extends(ElseClause, _super);
        function ElseClause(statement) {
            _super.call(this);
            this.statement = statement;
            statement && (statement.parent = this);
        }
        ElseClause.prototype.kind = function () {
            return 235 /* ElseClause */;
        };

        ElseClause.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition);
        };
        return ElseClause;
    })(AST);
    TypeScript.ElseClause = ElseClause;

    var IfStatement = (function (_super) {
        __extends(IfStatement, _super);
        function IfStatement(condition, statement, elseClause) {
            _super.call(this);
            this.condition = condition;
            this.statement = statement;
            this.elseClause = elseClause;
            condition && (condition.parent = this);
            statement && (statement.parent = this);
            elseClause && (elseClause.parent = this);
        }
        IfStatement.prototype.kind = function () {
            return 147 /* IfStatement */;
        };

        IfStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.condition, ast.condition, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition) && structuralEquals(this.elseClause, ast.elseClause, includingPosition);
        };
        return IfStatement;
    })(AST);
    TypeScript.IfStatement = IfStatement;

    var ExpressionStatement = (function (_super) {
        __extends(ExpressionStatement, _super);
        function ExpressionStatement(expression) {
            _super.call(this);
            this.expression = expression;
            expression && (expression.parent = this);
        }
        ExpressionStatement.prototype.kind = function () {
            return 149 /* ExpressionStatement */;
        };

        ExpressionStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };
        return ExpressionStatement;
    })(AST);
    TypeScript.ExpressionStatement = ExpressionStatement;

    var ConstructorDeclaration = (function (_super) {
        __extends(ConstructorDeclaration, _super);
        function ConstructorDeclaration(callSignature, block) {
            _super.call(this);
            this.callSignature = callSignature;
            this.block = block;
            callSignature && (callSignature.parent = this);
            block && (block.parent = this);
        }
        ConstructorDeclaration.prototype.kind = function () {
            return 137 /* ConstructorDeclaration */;
        };
        return ConstructorDeclaration;
    })(AST);
    TypeScript.ConstructorDeclaration = ConstructorDeclaration;

    var MemberFunctionDeclaration = (function (_super) {
        __extends(MemberFunctionDeclaration, _super);
        function MemberFunctionDeclaration(modifiers, propertyName, callSignature, block) {
            _super.call(this);
            this.modifiers = modifiers;
            this.propertyName = propertyName;
            this.callSignature = callSignature;
            this.block = block;
            propertyName && (propertyName.parent = this);
            callSignature && (callSignature.parent = this);
            block && (block.parent = this);
        }
        MemberFunctionDeclaration.prototype.kind = function () {
            return 135 /* MemberFunctionDeclaration */;
        };
        return MemberFunctionDeclaration;
    })(AST);
    TypeScript.MemberFunctionDeclaration = MemberFunctionDeclaration;

    var GetAccessor = (function (_super) {
        __extends(GetAccessor, _super);
        function GetAccessor(modifiers, propertyName, parameterList, typeAnnotation, block) {
            _super.call(this);
            this.modifiers = modifiers;
            this.propertyName = propertyName;
            this.parameterList = parameterList;
            this.typeAnnotation = typeAnnotation;
            this.block = block;
            propertyName && (propertyName.parent = this);
            parameterList && (parameterList.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
            block && (block.parent = this);
        }
        GetAccessor.prototype.kind = function () {
            return 139 /* GetAccessor */;
        };
        return GetAccessor;
    })(AST);
    TypeScript.GetAccessor = GetAccessor;

    var SetAccessor = (function (_super) {
        __extends(SetAccessor, _super);
        function SetAccessor(modifiers, propertyName, parameterList, block) {
            _super.call(this);
            this.modifiers = modifiers;
            this.propertyName = propertyName;
            this.parameterList = parameterList;
            this.block = block;
            propertyName && (propertyName.parent = this);
            parameterList && (parameterList.parent = this);
            block && (block.parent = this);
        }
        SetAccessor.prototype.kind = function () {
            return 140 /* SetAccessor */;
        };
        return SetAccessor;
    })(AST);
    TypeScript.SetAccessor = SetAccessor;

    var MemberVariableDeclaration = (function (_super) {
        __extends(MemberVariableDeclaration, _super);
        function MemberVariableDeclaration(modifiers, variableDeclarator) {
            _super.call(this);
            this.modifiers = modifiers;
            this.variableDeclarator = variableDeclarator;
            variableDeclarator && (variableDeclarator.parent = this);
        }
        MemberVariableDeclaration.prototype.kind = function () {
            return 136 /* MemberVariableDeclaration */;
        };
        return MemberVariableDeclaration;
    })(AST);
    TypeScript.MemberVariableDeclaration = MemberVariableDeclaration;

    var IndexMemberDeclaration = (function (_super) {
        __extends(IndexMemberDeclaration, _super);
        function IndexMemberDeclaration(indexSignature) {
            _super.call(this);
            this.indexSignature = indexSignature;
            indexSignature && (indexSignature.parent = this);
        }
        IndexMemberDeclaration.prototype.kind = function () {
            return 138 /* IndexMemberDeclaration */;
        };
        return IndexMemberDeclaration;
    })(AST);
    TypeScript.IndexMemberDeclaration = IndexMemberDeclaration;

    var ThrowStatement = (function (_super) {
        __extends(ThrowStatement, _super);
        function ThrowStatement(expression) {
            _super.call(this);
            this.expression = expression;
            expression && (expression.parent = this);
        }
        ThrowStatement.prototype.kind = function () {
            return 157 /* ThrowStatement */;
        };

        ThrowStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };
        return ThrowStatement;
    })(AST);
    TypeScript.ThrowStatement = ThrowStatement;

    var ReturnStatement = (function (_super) {
        __extends(ReturnStatement, _super);
        function ReturnStatement(expression) {
            _super.call(this);
            this.expression = expression;
            expression && (expression.parent = this);
        }
        ReturnStatement.prototype.kind = function () {
            return 150 /* ReturnStatement */;
        };

        ReturnStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };
        return ReturnStatement;
    })(AST);
    TypeScript.ReturnStatement = ReturnStatement;

    var ObjectCreationExpression = (function (_super) {
        __extends(ObjectCreationExpression, _super);
        function ObjectCreationExpression(expression, argumentList) {
            _super.call(this);
            this.expression = expression;
            this.argumentList = argumentList;
            expression && (expression.parent = this);
            argumentList && (argumentList.parent = this);
        }
        ObjectCreationExpression.prototype.kind = function () {
            return 216 /* ObjectCreationExpression */;
        };

        ObjectCreationExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition) && structuralEquals(this.argumentList, ast.argumentList, includingPosition);
        };

        ObjectCreationExpression.prototype.isExpression = function () {
            return true;
        };
        return ObjectCreationExpression;
    })(AST);
    TypeScript.ObjectCreationExpression = ObjectCreationExpression;

    var SwitchStatement = (function (_super) {
        __extends(SwitchStatement, _super);
        function SwitchStatement(expression, closeParenToken, switchClauses) {
            _super.call(this);
            this.expression = expression;
            this.closeParenToken = closeParenToken;
            this.switchClauses = switchClauses;
            expression && (expression.parent = this);
            switchClauses && (switchClauses.parent = this);
        }
        SwitchStatement.prototype.kind = function () {
            return 151 /* SwitchStatement */;
        };

        SwitchStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.switchClauses, ast.switchClauses, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };
        return SwitchStatement;
    })(AST);
    TypeScript.SwitchStatement = SwitchStatement;

    var CaseSwitchClause = (function (_super) {
        __extends(CaseSwitchClause, _super);
        function CaseSwitchClause(expression, statements) {
            _super.call(this);
            this.expression = expression;
            this.statements = statements;
            expression && (expression.parent = this);
            statements && (statements.parent = this);
        }
        CaseSwitchClause.prototype.kind = function () {
            return 233 /* CaseSwitchClause */;
        };

        CaseSwitchClause.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition) && structuralEquals(this.statements, ast.statements, includingPosition);
        };
        return CaseSwitchClause;
    })(AST);
    TypeScript.CaseSwitchClause = CaseSwitchClause;

    var DefaultSwitchClause = (function (_super) {
        __extends(DefaultSwitchClause, _super);
        function DefaultSwitchClause(statements) {
            _super.call(this);
            this.statements = statements;
            statements && (statements.parent = this);
        }
        DefaultSwitchClause.prototype.kind = function () {
            return 234 /* DefaultSwitchClause */;
        };

        DefaultSwitchClause.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.statements, ast.statements, includingPosition);
        };
        return DefaultSwitchClause;
    })(AST);
    TypeScript.DefaultSwitchClause = DefaultSwitchClause;

    var BreakStatement = (function (_super) {
        __extends(BreakStatement, _super);
        function BreakStatement(identifier) {
            _super.call(this);
            this.identifier = identifier;
        }
        BreakStatement.prototype.kind = function () {
            return 152 /* BreakStatement */;
        };

        BreakStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };
        return BreakStatement;
    })(AST);
    TypeScript.BreakStatement = BreakStatement;

    var ContinueStatement = (function (_super) {
        __extends(ContinueStatement, _super);
        function ContinueStatement(identifier) {
            _super.call(this);
            this.identifier = identifier;
        }
        ContinueStatement.prototype.kind = function () {
            return 153 /* ContinueStatement */;
        };

        ContinueStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };
        return ContinueStatement;
    })(AST);
    TypeScript.ContinueStatement = ContinueStatement;

    var ForStatement = (function (_super) {
        __extends(ForStatement, _super);
        function ForStatement(variableDeclaration, initializer, condition, incrementor, statement) {
            _super.call(this);
            this.variableDeclaration = variableDeclaration;
            this.initializer = initializer;
            this.condition = condition;
            this.incrementor = incrementor;
            this.statement = statement;
            variableDeclaration && (variableDeclaration.parent = this);
            initializer && (initializer.parent = this);
            condition && (condition.parent = this);
            incrementor && (incrementor.parent = this);
            statement && (statement.parent = this);
        }
        ForStatement.prototype.kind = function () {
            return 154 /* ForStatement */;
        };

        ForStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.initializer, ast.initializer, includingPosition) && structuralEquals(this.condition, ast.condition, includingPosition) && structuralEquals(this.incrementor, ast.incrementor, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition);
        };
        return ForStatement;
    })(AST);
    TypeScript.ForStatement = ForStatement;

    var ForInStatement = (function (_super) {
        __extends(ForInStatement, _super);
        function ForInStatement(variableDeclaration, left, expression, statement) {
            _super.call(this);
            this.variableDeclaration = variableDeclaration;
            this.left = left;
            this.expression = expression;
            this.statement = statement;
            variableDeclaration && (variableDeclaration.parent = this);
            left && (left.parent = this);
            expression && (expression.parent = this);
            statement && (statement.parent = this);
        }
        ForInStatement.prototype.kind = function () {
            return 155 /* ForInStatement */;
        };

        ForInStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.variableDeclaration, ast.variableDeclaration, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition);
        };
        return ForInStatement;
    })(AST);
    TypeScript.ForInStatement = ForInStatement;

    var WhileStatement = (function (_super) {
        __extends(WhileStatement, _super);
        function WhileStatement(condition, statement) {
            _super.call(this);
            this.condition = condition;
            this.statement = statement;
            condition && (condition.parent = this);
            statement && (statement.parent = this);
        }
        WhileStatement.prototype.kind = function () {
            return 158 /* WhileStatement */;
        };

        WhileStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.condition, ast.condition, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition);
        };
        return WhileStatement;
    })(AST);
    TypeScript.WhileStatement = WhileStatement;

    var WithStatement = (function (_super) {
        __extends(WithStatement, _super);
        function WithStatement(condition, statement) {
            _super.call(this);
            this.condition = condition;
            this.statement = statement;
            condition && (condition.parent = this);
            statement && (statement.parent = this);
        }
        WithStatement.prototype.kind = function () {
            return 163 /* WithStatement */;
        };

        WithStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.condition, ast.condition, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition);
        };
        return WithStatement;
    })(AST);
    TypeScript.WithStatement = WithStatement;

    var EnumDeclaration = (function (_super) {
        __extends(EnumDeclaration, _super);
        function EnumDeclaration(modifiers, identifier, enumElements) {
            _super.call(this);
            this.modifiers = modifiers;
            this.identifier = identifier;
            this.enumElements = enumElements;
            identifier && (identifier.parent = this);
            enumElements && (enumElements.parent = this);
        }
        EnumDeclaration.prototype.kind = function () {
            return 132 /* EnumDeclaration */;
        };
        return EnumDeclaration;
    })(AST);
    TypeScript.EnumDeclaration = EnumDeclaration;

    var EnumElement = (function (_super) {
        __extends(EnumElement, _super);
        function EnumElement(propertyName, equalsValueClause) {
            _super.call(this);
            this.propertyName = propertyName;
            this.equalsValueClause = equalsValueClause;
            propertyName && (propertyName.parent = this);
            equalsValueClause && (equalsValueClause.parent = this);
        }
        EnumElement.prototype.kind = function () {
            return 243 /* EnumElement */;
        };
        return EnumElement;
    })(AST);
    TypeScript.EnumElement = EnumElement;

    var CastExpression = (function (_super) {
        __extends(CastExpression, _super);
        function CastExpression(type, expression) {
            _super.call(this);
            this.type = type;
            this.expression = expression;
            type && (type.parent = this);
            expression && (expression.parent = this);
        }
        CastExpression.prototype.kind = function () {
            return 220 /* CastExpression */;
        };

        CastExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.type, ast.type, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };

        CastExpression.prototype.isExpression = function () {
            return true;
        };
        return CastExpression;
    })(AST);
    TypeScript.CastExpression = CastExpression;

    var ObjectLiteralExpression = (function (_super) {
        __extends(ObjectLiteralExpression, _super);
        function ObjectLiteralExpression(propertyAssignments) {
            _super.call(this);
            this.propertyAssignments = propertyAssignments;
            propertyAssignments && (propertyAssignments.parent = this);
        }
        ObjectLiteralExpression.prototype.kind = function () {
            return 215 /* ObjectLiteralExpression */;
        };

        ObjectLiteralExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.propertyAssignments, ast.propertyAssignments, includingPosition);
        };

        ObjectLiteralExpression.prototype.isExpression = function () {
            return true;
        };
        return ObjectLiteralExpression;
    })(AST);
    TypeScript.ObjectLiteralExpression = ObjectLiteralExpression;

    var SimplePropertyAssignment = (function (_super) {
        __extends(SimplePropertyAssignment, _super);
        function SimplePropertyAssignment(propertyName, expression) {
            _super.call(this);
            this.propertyName = propertyName;
            this.expression = expression;
            propertyName && (propertyName.parent = this);
            expression && (expression.parent = this);
        }
        SimplePropertyAssignment.prototype.kind = function () {
            return 240 /* SimplePropertyAssignment */;
        };
        return SimplePropertyAssignment;
    })(AST);
    TypeScript.SimplePropertyAssignment = SimplePropertyAssignment;

    var FunctionPropertyAssignment = (function (_super) {
        __extends(FunctionPropertyAssignment, _super);
        function FunctionPropertyAssignment(propertyName, callSignature, block) {
            _super.call(this);
            this.propertyName = propertyName;
            this.callSignature = callSignature;
            this.block = block;
            propertyName && (propertyName.parent = this);
            callSignature && (callSignature.parent = this);
            block && (block.parent = this);
        }
        FunctionPropertyAssignment.prototype.kind = function () {
            return 241 /* FunctionPropertyAssignment */;
        };
        return FunctionPropertyAssignment;
    })(AST);
    TypeScript.FunctionPropertyAssignment = FunctionPropertyAssignment;

    var FunctionExpression = (function (_super) {
        __extends(FunctionExpression, _super);
        function FunctionExpression(identifier, callSignature, block) {
            _super.call(this);
            this.identifier = identifier;
            this.callSignature = callSignature;
            this.block = block;
            identifier && (identifier.parent = this);
            callSignature && (callSignature.parent = this);
            block && (block.parent = this);
        }
        FunctionExpression.prototype.kind = function () {
            return 222 /* FunctionExpression */;
        };

        FunctionExpression.prototype.isExpression = function () {
            return true;
        };
        return FunctionExpression;
    })(AST);
    TypeScript.FunctionExpression = FunctionExpression;

    var EmptyStatement = (function (_super) {
        __extends(EmptyStatement, _super);
        function EmptyStatement() {
            _super.apply(this, arguments);
        }
        EmptyStatement.prototype.kind = function () {
            return 156 /* EmptyStatement */;
        };

        EmptyStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition);
        };
        return EmptyStatement;
    })(AST);
    TypeScript.EmptyStatement = EmptyStatement;

    var TryStatement = (function (_super) {
        __extends(TryStatement, _super);
        function TryStatement(block, catchClause, finallyClause) {
            _super.call(this);
            this.block = block;
            this.catchClause = catchClause;
            this.finallyClause = finallyClause;
            block && (block.parent = this);
            catchClause && (catchClause.parent = this);
            finallyClause && (finallyClause.parent = this);
        }
        TryStatement.prototype.kind = function () {
            return 159 /* TryStatement */;
        };

        TryStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.block, ast.block, includingPosition) && structuralEquals(this.catchClause, ast.catchClause, includingPosition) && structuralEquals(this.finallyClause, ast.finallyClause, includingPosition);
        };
        return TryStatement;
    })(AST);
    TypeScript.TryStatement = TryStatement;

    var CatchClause = (function (_super) {
        __extends(CatchClause, _super);
        function CatchClause(identifier, typeAnnotation, block) {
            _super.call(this);
            this.identifier = identifier;
            this.typeAnnotation = typeAnnotation;
            this.block = block;
            identifier && (identifier.parent = this);
            typeAnnotation && (typeAnnotation.parent = this);
            block && (block.parent = this);
        }
        CatchClause.prototype.kind = function () {
            return 236 /* CatchClause */;
        };

        CatchClause.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.typeAnnotation, ast.typeAnnotation, includingPosition) && structuralEquals(this.block, ast.block, includingPosition);
        };
        return CatchClause;
    })(AST);
    TypeScript.CatchClause = CatchClause;

    var FinallyClause = (function (_super) {
        __extends(FinallyClause, _super);
        function FinallyClause(block) {
            _super.call(this);
            this.block = block;
            block && (block.parent = this);
        }
        FinallyClause.prototype.kind = function () {
            return 237 /* FinallyClause */;
        };

        FinallyClause.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.block, ast.block, includingPosition);
        };
        return FinallyClause;
    })(AST);
    TypeScript.FinallyClause = FinallyClause;

    var LabeledStatement = (function (_super) {
        __extends(LabeledStatement, _super);
        function LabeledStatement(identifier, statement) {
            _super.call(this);
            this.identifier = identifier;
            this.statement = statement;
            identifier && (identifier.parent = this);
            statement && (statement.parent = this);
        }
        LabeledStatement.prototype.kind = function () {
            return 160 /* LabeledStatement */;
        };

        LabeledStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.identifier, ast.identifier, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition);
        };
        return LabeledStatement;
    })(AST);
    TypeScript.LabeledStatement = LabeledStatement;

    var DoStatement = (function (_super) {
        __extends(DoStatement, _super);
        function DoStatement(statement, whileKeyword, condition) {
            _super.call(this);
            this.statement = statement;
            this.whileKeyword = whileKeyword;
            this.condition = condition;
            statement && (statement.parent = this);
            condition && (condition.parent = this);
        }
        DoStatement.prototype.kind = function () {
            return 161 /* DoStatement */;
        };

        DoStatement.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.statement, ast.statement, includingPosition) && structuralEquals(this.condition, ast.condition, includingPosition);
        };
        return DoStatement;
    })(AST);
    TypeScript.DoStatement = DoStatement;

    var TypeOfExpression = (function (_super) {
        __extends(TypeOfExpression, _super);
        function TypeOfExpression(expression) {
            _super.call(this);
            this.expression = expression;
            expression && (expression.parent = this);
        }
        TypeOfExpression.prototype.kind = function () {
            return 171 /* TypeOfExpression */;
        };

        TypeOfExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };

        TypeOfExpression.prototype.isExpression = function () {
            return true;
        };
        return TypeOfExpression;
    })(AST);
    TypeScript.TypeOfExpression = TypeOfExpression;

    var DeleteExpression = (function (_super) {
        __extends(DeleteExpression, _super);
        function DeleteExpression(expression) {
            _super.call(this);
            this.expression = expression;
            expression && (expression.parent = this);
        }
        DeleteExpression.prototype.kind = function () {
            return 170 /* DeleteExpression */;
        };

        DeleteExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };

        DeleteExpression.prototype.isExpression = function () {
            return true;
        };
        return DeleteExpression;
    })(AST);
    TypeScript.DeleteExpression = DeleteExpression;

    var VoidExpression = (function (_super) {
        __extends(VoidExpression, _super);
        function VoidExpression(expression) {
            _super.call(this);
            this.expression = expression;
            expression && (expression.parent = this);
        }
        VoidExpression.prototype.kind = function () {
            return 172 /* VoidExpression */;
        };

        VoidExpression.prototype.structuralEquals = function (ast, includingPosition) {
            return _super.prototype.structuralEquals.call(this, ast, includingPosition) && structuralEquals(this.expression, ast.expression, includingPosition);
        };

        VoidExpression.prototype.isExpression = function () {
            return true;
        };
        return VoidExpression;
    })(AST);
    TypeScript.VoidExpression = VoidExpression;

    var DebuggerStatement = (function (_super) {
        __extends(DebuggerStatement, _super);
        function DebuggerStatement() {
            _super.apply(this, arguments);
        }
        DebuggerStatement.prototype.kind = function () {
            return 162 /* DebuggerStatement */;
        };
        return DebuggerStatement;
    })(AST);
    TypeScript.DebuggerStatement = DebuggerStatement;

    var Comment = (function () {
        function Comment(_trivia, endsLine, _start, _end) {
            this._trivia = _trivia;
            this.endsLine = endsLine;
            this._start = _start;
            this._end = _end;
        }
        Comment.prototype.start = function () {
            return this._start;
        };

        Comment.prototype.end = function () {
            return this._end;
        };

        Comment.prototype.fullText = function () {
            return this._trivia.fullText();
        };

        Comment.prototype.kind = function () {
            return this._trivia.kind();
        };

        Comment.prototype.structuralEquals = function (ast, includingPosition) {
            if (includingPosition) {
                if (this.start() !== ast.start() || this.end() !== ast.end()) {
                    return false;
                }
            }

            return this._trivia.fullText() === ast._trivia.fullText() && this.endsLine === ast.endsLine;
        };
        return Comment;
    })();
    TypeScript.Comment = Comment;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    (function (IOUtils) {
        function createDirectoryStructure(ioHost, dirName) {
            if (ioHost.directoryExists(dirName)) {
                return;
            }

            var parentDirectory = ioHost.dirName(dirName);
            if (parentDirectory != "") {
                createDirectoryStructure(ioHost, parentDirectory);
            }
            ioHost.createDirectory(dirName);
        }

        function writeFileAndFolderStructure(ioHost, fileName, contents, writeByteOrderMark) {
            var start = new Date().getTime();
            var path = ioHost.resolvePath(fileName);
            TypeScript.ioHostResolvePathTime += new Date().getTime() - start;

            var start = new Date().getTime();
            var dirName = ioHost.dirName(path);
            TypeScript.ioHostDirectoryNameTime += new Date().getTime() - start;

            var start = new Date().getTime();
            createDirectoryStructure(ioHost, dirName);
            TypeScript.ioHostCreateDirectoryStructureTime += new Date().getTime() - start;

            var start = new Date().getTime();
            ioHost.writeFile(path, contents, writeByteOrderMark);
            TypeScript.ioHostWriteFileTime += new Date().getTime() - start;
        }
        IOUtils.writeFileAndFolderStructure = writeFileAndFolderStructure;

        function throwIOError(message, error) {
            var errorMessage = message;
            if (error && error.message) {
                errorMessage += (" " + error.message);
            }
            throw new Error(errorMessage);
        }
        IOUtils.throwIOError = throwIOError;

        function combine(prefix, suffix) {
            return prefix + "/" + suffix;
        }
        IOUtils.combine = combine;

        var BufferedTextWriter = (function () {
            function BufferedTextWriter(writer, capacity) {
                if (typeof capacity === "undefined") { capacity = 1024; }
                this.writer = writer;
                this.capacity = capacity;
                this.buffer = "";
            }
            BufferedTextWriter.prototype.Write = function (str) {
                this.buffer += str;
                if (this.buffer.length >= this.capacity) {
                    this.writer.Write(this.buffer);
                    this.buffer = "";
                }
            };
            BufferedTextWriter.prototype.WriteLine = function (str) {
                this.Write(str + '\r\n');
            };
            BufferedTextWriter.prototype.Close = function () {
                this.writer.Write(this.buffer);
                this.writer.Close();
                this.buffer = null;
            };
            return BufferedTextWriter;
        })();
        IOUtils.BufferedTextWriter = BufferedTextWriter;
    })(TypeScript.IOUtils || (TypeScript.IOUtils = {}));
    var IOUtils = TypeScript.IOUtils;

    TypeScript.IO = (function () {
        function getWindowsScriptHostIO() {
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            var streamObjectPool = [];

            function getStreamObject() {
                if (streamObjectPool.length > 0) {
                    return streamObjectPool.pop();
                } else {
                    return new ActiveXObject("ADODB.Stream");
                }
            }

            function releaseStreamObject(obj) {
                streamObjectPool.push(obj);
            }

            var args = [];
            for (var i = 0; i < WScript.Arguments.length; i++) {
                args[i] = WScript.Arguments.Item(i);
            }

            return {
                appendFile: function (path, content) {
                    var txtFile = fso.OpenTextFile(path, 8, true);
                    txtFile.Write(content);
                    txtFile.Close();
                },
                readFile: function (path, codepage) {
                    return TypeScript.Environment.readFile(path, codepage);
                },
                writeFile: function (path, contents, writeByteOrderMark) {
                    TypeScript.Environment.writeFile(path, contents, writeByteOrderMark);
                },
                fileExists: function (path) {
                    return fso.FileExists(path);
                },
                resolvePath: function (path) {
                    return fso.GetAbsolutePathName(path);
                },
                dirName: function (path) {
                    return fso.GetParentFolderName(path);
                },
                findFile: function (rootPath, partialFilePath) {
                    var path = fso.GetAbsolutePathName(rootPath) + "/" + partialFilePath;

                    while (true) {
                        if (fso.FileExists(path)) {
                            return { fileInformation: this.readFile(path), path: path };
                        } else {
                            rootPath = fso.GetParentFolderName(fso.GetAbsolutePathName(rootPath));

                            if (rootPath == "") {
                                return null;
                            } else {
                                path = fso.BuildPath(rootPath, partialFilePath);
                            }
                        }
                    }
                },
                deleteFile: function (path) {
                    try  {
                        if (fso.FileExists(path)) {
                            fso.DeleteFile(path, true);
                        }
                    } catch (e) {
                        IOUtils.throwIOError(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Could_not_delete_file_0, [path]), e);
                    }
                },
                directoryExists: function (path) {
                    return fso.FolderExists(path);
                },
                createDirectory: function (path) {
                    try  {
                        if (!this.directoryExists(path)) {
                            fso.CreateFolder(path);
                        }
                    } catch (e) {
                        IOUtils.throwIOError(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Could_not_create_directory_0, [path]), e);
                    }
                },
                dir: function (path, spec, options) {
                    options = options || {};
                    function filesInFolder(folder, root) {
                        var paths = [];
                        var fc;

                        if (options.recursive) {
                            fc = new Enumerator(folder.subfolders);

                            for (; !fc.atEnd(); fc.moveNext()) {
                                paths = paths.concat(filesInFolder(fc.item(), root + "/" + fc.item().Name));
                            }
                        }

                        fc = new Enumerator(folder.files);

                        for (; !fc.atEnd(); fc.moveNext()) {
                            if (!spec || fc.item().Name.match(spec)) {
                                paths.push(root + "/" + fc.item().Name);
                            }
                        }

                        return paths;
                    }

                    var folder = fso.GetFolder(path);
                    var paths = [];

                    return filesInFolder(folder, path);
                },
                print: function (str) {
                    WScript.StdOut.Write(str);
                },
                printLine: function (str) {
                    WScript.Echo(str);
                },
                arguments: args,
                stderr: WScript.StdErr,
                stdout: WScript.StdOut,
                watchFile: null,
                run: function (source, fileName) {
                    try  {
                        eval(source);
                    } catch (e) {
                        IOUtils.throwIOError(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Error_while_executing_file_0, [fileName]), e);
                    }
                },
                getExecutingFilePath: function () {
                    return WScript.ScriptFullName;
                },
                quit: function (exitCode) {
                    if (typeof exitCode === "undefined") { exitCode = 0; }
                    try  {
                        WScript.Quit(exitCode);
                    } catch (e) {
                    }
                }
            };
        }
        ;

        function getNodeIO() {
            var _fs = require('fs');
            var _path = require('path');
            var _module = require('module');

            return {
                appendFile: function (path, content) {
                    _fs.appendFileSync(path, content);
                },
                readFile: function (file, codepage) {
                    return TypeScript.Environment.readFile(file, codepage);
                },
                writeFile: function (path, contents, writeByteOrderMark) {
                    TypeScript.Environment.writeFile(path, contents, writeByteOrderMark);
                },
                deleteFile: function (path) {
                    try  {
                        _fs.unlinkSync(path);
                    } catch (e) {
                        IOUtils.throwIOError(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Could_not_delete_file_0, [path]), e);
                    }
                },
                fileExists: function (path) {
                    return _fs.existsSync(path);
                },
                dir: function dir(path, spec, options) {
                    options = options || {};

                    function filesInFolder(folder) {
                        var paths = [];

                        try  {
                            var files = _fs.readdirSync(folder);
                            for (var i = 0; i < files.length; i++) {
                                var stat = _fs.statSync(folder + "/" + files[i]);
                                if (options.recursive && stat.isDirectory()) {
                                    paths = paths.concat(filesInFolder(folder + "/" + files[i]));
                                } else if (stat.isFile() && (!spec || files[i].match(spec))) {
                                    paths.push(folder + "/" + files[i]);
                                }
                            }
                        } catch (err) {
                        }

                        return paths;
                    }

                    return filesInFolder(path);
                },
                createDirectory: function (path) {
                    try  {
                        if (!this.directoryExists(path)) {
                            _fs.mkdirSync(path);
                        }
                    } catch (e) {
                        IOUtils.throwIOError(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Could_not_create_directory_0, [path]), e);
                    }
                },
                directoryExists: function (path) {
                    return _fs.existsSync(path) && _fs.statSync(path).isDirectory();
                },
                resolvePath: function (path) {
                    return _path.resolve(path);
                },
                dirName: function (path) {
                    var dirPath = _path.dirname(path);

                    if (dirPath === path) {
                        dirPath = null;
                    }

                    return dirPath;
                },
                findFile: function (rootPath, partialFilePath) {
                    var path = rootPath + "/" + partialFilePath;

                    while (true) {
                        if (_fs.existsSync(path)) {
                            return { fileInformation: this.readFile(path), path: path };
                        } else {
                            var parentPath = _path.resolve(rootPath, "..");

                            if (rootPath === parentPath) {
                                return null;
                            } else {
                                rootPath = parentPath;
                                path = _path.resolve(rootPath, partialFilePath);
                            }
                        }
                    }
                },
                print: function (str) {
                    process.stdout.write(str);
                },
                printLine: function (str) {
                    process.stdout.write(str + '\n');
                },
                arguments: process.argv.slice(2),
                stderr: {
                    Write: function (str) {
                        process.stderr.write(str);
                    },
                    WriteLine: function (str) {
                        process.stderr.write(str + '\n');
                    },
                    Close: function () {
                    }
                },
                stdout: {
                    Write: function (str) {
                        process.stdout.write(str);
                    },
                    WriteLine: function (str) {
                        process.stdout.write(str + '\n');
                    },
                    Close: function () {
                    }
                },
                watchFile: function (fileName, callback) {
                    var firstRun = true;
                    var processingChange = false;

                    var fileChanged = function (curr, prev) {
                        if (!firstRun) {
                            if (curr.mtime < prev.mtime) {
                                return;
                            }

                            _fs.unwatchFile(fileName, fileChanged);
                            if (!processingChange) {
                                processingChange = true;
                                callback(fileName);
                                setTimeout(function () {
                                    processingChange = false;
                                }, 100);
                            }
                        }
                        firstRun = false;
                        _fs.watchFile(fileName, { persistent: true, interval: 500 }, fileChanged);
                    };

                    fileChanged();
                    return {
                        fileName: fileName,
                        close: function () {
                            _fs.unwatchFile(fileName, fileChanged);
                        }
                    };
                },
                run: function (source, fileName) {
                    require.main.fileName = fileName;
                    require.main.paths = _module._nodeModulePaths(_path.dirname(_fs.realpathSync(fileName)));
                    require.main._compile(source, fileName);
                },
                getExecutingFilePath: function () {
                    return process.mainModule.filename;
                },
                quit: function (code) {
                    var stderrFlushed = process.stderr.write('');
                    var stdoutFlushed = process.stdout.write('');
                    process.stderr.on('drain', function () {
                        stderrFlushed = true;
                        if (stdoutFlushed) {
                            process.exit(code);
                        }
                    });
                    process.stdout.on('drain', function () {
                        stdoutFlushed = true;
                        if (stderrFlushed) {
                            process.exit(code);
                        }
                    });
                    setTimeout(function () {
                        process.exit(code);
                    }, 5);
                }
            };
        }
        ;

        if (typeof WScript !== "undefined" && typeof ActiveXObject === "function")
            return getWindowsScriptHostIO();
        else if (typeof module !== 'undefined' && module.exports)
            return getNodeIO();
        else
            return null;
    })();
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var OptionsParser = (function () {
        function OptionsParser(host, version) {
            this.host = host;
            this.version = version;
            this.DEFAULT_SHORT_FLAG = "-";
            this.DEFAULT_LONG_FLAG = "--";
            this.printedVersion = false;
            this.unnamed = [];
            this.options = [];
        }
        OptionsParser.prototype.findOption = function (arg) {
            var upperCaseArg = arg && arg.toUpperCase();

            for (var i = 0; i < this.options.length; i++) {
                var current = this.options[i];

                if (upperCaseArg === (current.short && current.short.toUpperCase()) || upperCaseArg === (current.name && current.name.toUpperCase())) {
                    return current;
                }
            }

            return null;
        };

        OptionsParser.prototype.printUsage = function () {
            this.printVersion();

            var optionsWord = TypeScript.getLocalizedText(TypeScript.DiagnosticCode.options, null);
            var fileWord = TypeScript.getLocalizedText(TypeScript.DiagnosticCode.file1, null);
            var tscSyntax = "tsc [" + optionsWord + "] [" + fileWord + " ..]";
            var syntaxHelp = TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Syntax_0, [tscSyntax]);
            this.host.printLine(syntaxHelp);
            this.host.printLine("");
            this.host.printLine(TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Examples, null) + " tsc hello.ts");
            this.host.printLine("          tsc --out foo.js foo.ts");
            this.host.printLine("          tsc @args.txt");
            this.host.printLine("");
            this.host.printLine(TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Options, null));

            var output = [];
            var maxLength = 0;
            var i = 0;

            this.options = this.options.sort(function (a, b) {
                var aName = a.name.toLowerCase();
                var bName = b.name.toLowerCase();

                if (aName > bName) {
                    return 1;
                } else if (aName < bName) {
                    return -1;
                } else {
                    return 0;
                }
            });

            for (i = 0; i < this.options.length; i++) {
                var option = this.options[i];

                if (option.experimental) {
                    continue;
                }

                if (!option.usage) {
                    break;
                }

                var usageString = "  ";
                var type = option.type ? (" " + TypeScript.getLocalizedText(option.type, null)) : "";

                if (option.short) {
                    usageString += this.DEFAULT_SHORT_FLAG + option.short + type + ", ";
                }

                usageString += this.DEFAULT_LONG_FLAG + option.name + type;

                output.push([usageString, TypeScript.getLocalizedText(option.usage.locCode, option.usage.args)]);

                if (usageString.length > maxLength) {
                    maxLength = usageString.length;
                }
            }

            var fileDescription = TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Insert_command_line_options_and_files_from_a_file, null);
            output.push(["  @<" + fileWord + ">", fileDescription]);

            for (i = 0; i < output.length; i++) {
                this.host.printLine(output[i][0] + (new Array(maxLength - output[i][0].length + 3)).join(" ") + output[i][1]);
            }
        };

        OptionsParser.prototype.printVersion = function () {
            if (!this.printedVersion) {
                this.host.printLine(TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Version_0, [this.version]));
                this.printedVersion = true;
            }
        };

        OptionsParser.prototype.option = function (name, config, short) {
            if (!config) {
                config = short;
                short = null;
            }

            config.name = name;
            config.short = short;
            config.flag = false;

            this.options.push(config);
        };

        OptionsParser.prototype.flag = function (name, config, short) {
            if (!config) {
                config = short;
                short = null;
            }

            config.name = name;
            config.short = short;
            config.flag = true;

            this.options.push(config);
        };

        OptionsParser.prototype.parseString = function (argString) {
            var position = 0;
            var tokens = argString.match(/\s+|"|[^\s"]+/g);

            function peek() {
                return tokens[position];
            }

            function consume() {
                return tokens[position++];
            }

            function consumeQuotedString() {
                var value = '';
                consume();

                var token = peek();

                while (token && token !== '"') {
                    consume();

                    value += token;

                    token = peek();
                }

                consume();

                return value;
            }

            var args = [];
            var currentArg = '';

            while (position < tokens.length) {
                var token = peek();

                if (token === '"') {
                    currentArg += consumeQuotedString();
                } else if (token.match(/\s/)) {
                    if (currentArg.length > 0) {
                        args.push(currentArg);
                        currentArg = '';
                    }

                    consume();
                } else {
                    consume();
                    currentArg += token;
                }
            }

            if (currentArg.length > 0) {
                args.push(currentArg);
            }

            this.parse(args);
        };

        OptionsParser.prototype.parse = function (args) {
            var position = 0;

            function consume() {
                return args[position++];
            }

            while (position < args.length) {
                var current = consume();
                var match = current.match(/^(--?|@)(.*)/);
                var value = null;

                if (match) {
                    if (match[1] === '@') {
                        this.parseString(this.host.readFile(match[2], null).contents);
                    } else {
                        var arg = match[2];
                        var option = this.findOption(arg);

                        if (option === null) {
                            this.host.printLine(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Unknown_option_0, [arg]));
                            this.host.printLine(TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Use_the_0_flag_to_see_options, ["--help"]));
                        } else {
                            if (!option.flag) {
                                value = consume();
                                if (value === undefined) {
                                    this.host.printLine(TypeScript.getDiagnosticMessage(TypeScript.DiagnosticCode.Option_0_specified_without_1, [arg, TypeScript.getLocalizedText(option.type, null)]));
                                    this.host.printLine(TypeScript.getLocalizedText(TypeScript.DiagnosticCode.Use_the_0_flag_to_see_options, ["--help"]));
                                    continue;
                                }
                            }

                            option.set(value);
                        }
                    }
                } else {
                    this.unnamed.push(current);
                }
            }
        };
        return OptionsParser;
    })();
    TypeScript.OptionsParser = OptionsParser;
})(TypeScript || (TypeScript = {}));
var TypeScript;
(function (TypeScript) {
    var SourceFile = (function () {
        function SourceFile(scriptSnapshot, byteOrderMark) {
            this.scriptSnapshot = scriptSnapshot;
            this.byteOrderMark = byteOrderMark;
        }
        return SourceFile;
    })();

    var DiagnosticsLogger = (function () {
        function DiagnosticsLogger(ioHost) {
            this.ioHost = ioHost;
        }
        DiagnosticsLogger.prototype.information = function () {
            return false;
        };
        DiagnosticsLogger.prototype.debug = function () {
            return false;
        };
        DiagnosticsLogger.prototype.warning = function () {
            return false;
        };
        DiagnosticsLogger.prototype.error = function () {
            return false;
        };
        DiagnosticsLogger.prototype.fatal = function () {
            return false;
        };
        DiagnosticsLogger.prototype.log = function (s) {
            this.ioHost.stdout.WriteLine(s);
        };
        return DiagnosticsLogger;
    })();

    var FileLogger = (function () {
        function FileLogger(ioHost) {
            this.ioHost = ioHost;
            var file = "tsc." + Date.now() + ".log";

            this.fileName = this.ioHost.resolvePath(file);
        }
        FileLogger.prototype.information = function () {
            return false;
        };
        FileLogger.prototype.debug = function () {
            return false;
        };
        FileLogger.prototype.warning = function () {
            return false;
        };
        FileLogger.prototype.error = function () {
            return false;
        };
        FileLogger.prototype.fatal = function () {
            return false;
        };
        FileLogger.prototype.log = function (s) {
            this.ioHost.appendFile(this.fileName, s + '\r\n');
        };
        return FileLogger;
    })();

    var BatchCompiler = (function () {
        function BatchCompiler(ioHost) {
            this.ioHost = ioHost;
            this.compilerVersion = "1.0.1.0";
            this.inputFiles = [];
            this.resolvedFiles = [];
            this.fileNameToSourceFile = new TypeScript.StringHashTable();
            this.hasErrors = false;
            this.logger = null;
            this.fileExistsCache = TypeScript.createIntrinsicsObject();
            this.resolvePathCache = TypeScript.createIntrinsicsObject();
        }
        BatchCompiler.prototype.batchCompile = function () {
            var _this = this;
            var start = new Date().getTime();

            TypeScript.CompilerDiagnostics.diagnosticWriter = { Alert: function (s) {
                    _this.ioHost.printLine(s);
                } };

            if (this.parseOptions()) {
                if (this.compilationSettings.createFileLog()) {
                    this.logger = new FileLogger(this.ioHost);
                } else if (this.compilationSettings.gatherDiagnostics()) {
                    this.logger = new DiagnosticsLogger(this.ioHost);
                } else {
                    this.logger = new TypeScript.NullLogger();
                }

                if (this.compilationSettings.watch()) {
                    this.watchFiles();
                    return;
                }

                this.resolve();

                this.compile();

                if (this.compilationSettings.createFileLog()) {
                    this.logger.log("Compilation settings:");
                    this.logger.log(" propagateEnumConstants " + this.compilationSettings.propagateEnumConstants());
                    this.logger.log(" removeComments " + this.compilationSettings.removeComments());
                    this.logger.log(" watch " + this.compilationSettings.watch());
                    this.logger.log(" noResolve " + this.compilationSettings.noResolve());
                    this.logger.log(" noImplicitAny " + this.compilationSettings.noImplicitAny());
                    this.logger.log(" nolib " + this.compilationSettings.noLib());
                    this.logger.log(" target " + this.compilationSettings.codeGenTarget());
                    this.logger.log(" module " + this.compilationSettings.moduleGenTarget());
                    this.logger.log(" out " + this.compilationSettings.outFileOption());
                    this.logger.log(" outDir " + this.compilationSettings.outDirOption());
                    this.logger.log(" sourcemap " + this.compilationSettings.mapSourceFiles());
                    this.logger.log(" mapRoot " + this.compilationSettings.mapRoot());
                    this.logger.log(" sourceroot " + this.compilationSettings.sourceRoot());
                    this.logger.log(" declaration " + this.compilationSettings.generateDeclarationFiles());
                    this.logger.log(" useCaseSensitiveFileResolution " + this.compilationSettings.useCaseSensitiveFileResolution());
                    this.logger.log(" diagnostics " + this.compilationSettings.gatherDiagnostics());
                    this.logger.log(" codepage " + this.compilationSettings.codepage());

                    this.logger.log("");

                    this.logger.log("Input files:");
                    this.inputFiles.forEach(function (file) {
                        _this.logger.log(" " + file);
                    });

                    this.logger.log("");

                    this.logger.log("Resolved Files:");
                    this.resolvedFiles.forEach(function (file) {
                        file.importedFiles.forEach(function (file) {
                            _this.logger.log(" " + file);
                        });
                        file.referencedFiles.forEach(function (file) {
                            _this.logger.log(" " + file);
                        });
                    });
                }

                if (this.compilationSettings.gatherDiagnostics()) {
                    this.logger.log("");
                    this.logger.log("File resolution time:                     " + TypeScript.fileResolutionTime);
                    this.logger.log("           file read:                     " + TypeScript.fileResolutionIOTime);
                    this.logger.log("        scan imports:                     " + TypeScript.fileResolutionScanImportsTime);
                    this.logger.log("       import search:                     " + TypeScript.fileResolutionImportFileSearchTime);
                    this.logger.log("        get lib.d.ts:                     " + TypeScript.fileResolutionGetDefaultLibraryTime);

                    this.logger.log("SyntaxTree parse time:                    " + TypeScript.syntaxTreeParseTime);
                    this.logger.log("Syntax Diagnostics time:                  " + TypeScript.syntaxDiagnosticsTime);
                    this.logger.log("AST translation time:                     " + TypeScript.astTranslationTime);
                    this.logger.log("");
                    this.logger.log("Type check time:                          " + TypeScript.typeCheckTime);
                    this.logger.log("");
                    this.logger.log("Emit time:                                " + TypeScript.emitTime);
                    this.logger.log("Declaration emit time:                    " + TypeScript.declarationEmitTime);

                    this.logger.log("Total number of symbols created:          " + TypeScript.pullSymbolID);
                    this.logger.log("Specialized types created:                " + TypeScript.nSpecializationsCreated);
                    this.logger.log("Specialized signatures created:           " + TypeScript.nSpecializedSignaturesCreated);

                    this.logger.log("  IsExternallyVisibleTime:                " + TypeScript.declarationEmitIsExternallyVisibleTime);
                    this.logger.log("  TypeSignatureTime:                      " + TypeScript.declarationEmitTypeSignatureTime);
                    this.logger.log("  GetBoundDeclTypeTime:                   " + TypeScript.declarationEmitGetBoundDeclTypeTime);
                    this.logger.log("  IsOverloadedCallSignatureTime:          " + TypeScript.declarationEmitIsOverloadedCallSignatureTime);
                    this.logger.log("  FunctionDeclarationGetSymbolTime:       " + TypeScript.declarationEmitFunctionDeclarationGetSymbolTime);
                    this.logger.log("  GetBaseTypeTime:                        " + TypeScript.declarationEmitGetBaseTypeTime);
                    this.logger.log("  GetAccessorFunctionTime:                " + TypeScript.declarationEmitGetAccessorFunctionTime);
                    this.logger.log("  GetTypeParameterSymbolTime:             " + TypeScript.declarationEmitGetTypeParameterSymbolTime);
                    this.logger.log("  GetImportDeclarationSymbolTime:         " + TypeScript.declarationEmitGetImportDeclarationSymbolTime);

                    this.logger.log("Emit write file time:                     " + TypeScript.emitWriteFileTime);

                    this.logger.log("Compiler resolve path time:               " + TypeScript.compilerResolvePathTime);
                    this.logger.log("Compiler directory name time:             " + TypeScript.compilerDirectoryNameTime);
                    this.logger.log("Compiler directory exists time:           " + TypeScript.compilerDirectoryExistsTime);
                    this.logger.log("Compiler file exists time:                " + TypeScript.compilerFileExistsTime);

                    this.logger.log("IO host resolve path time:                " + TypeScript.ioHostResolvePathTime);
                    this.logger.log("IO host directory name time:              " + TypeScript.ioHostDirectoryNameTime);
                    this.logger.log("IO host create directory structure time:  " + TypeScript.ioHostCreateDirectoryStructureTime);
                    this.logger.log("IO host write file time:                  " + TypeScript.ioHostWriteFileTime);

                    this.logger.log("Node make directory time:                 " + TypeScript.nodeMakeDirectoryTime);
                    this.logger.log("Node writeFileSync time:                  " + TypeScript.nodeWriteFileSyncTime);
                    this.logger.log("Node createBuffer time:                   " + TypeScript.nodeCreateBufferTime);
                }
            }

            this.ioHost.quit(this.hasErrors ? 1 : 0);
        };

        BatchCompiler.prototype.resolve = function () {
            var _this = this;
            var includeDefaultLibrary = !this.compilationSettings.noLib();
            var resolvedFiles = [];

            var start = new Date().getTime();

            if (!this.compilationSettings.noResolve()) {
                var resolutionResults = TypeScript.ReferenceResolver.resolve(this.inputFiles, this, this.compilationSettings.useCaseSensitiveFileResolution());
                resolvedFiles = resolutionResults.resolvedFiles;

                includeDefaultLibrary = !this.compilationSettings.noLib() && !resolutionResults.seenNoDefaultLibTag;

                resolutionResults.diagnostics.forEach(function (d) {
                    return _this.addDiagnostic(d);
                });
            } else {
                for (var i = 0, n = this.inputFiles.length; i < n; i++) {
                    var inputFile = this.inputFiles[i];
                    var referencedFiles = [];
                    var importedFiles = [];

                    if (this.compilationSettings.generateDeclarationFiles()) {
                        var references = TypeScript.getReferencedFiles(inputFile, this.getScriptSnapshot(inputFile));
                        for (var j = 0; j < references.length; j++) {
                            referencedFiles.push(references[j].path);
                        }

                        inputFile = this.resolvePath(inputFile);
                    }

                    resolvedFiles.push({
                        path: inputFile,
                        referencedFiles: referencedFiles,
                        importedFiles: importedFiles
                    });
                }
            }

            var defaultLibStart = new Date().getTime();
            if (includeDefaultLibrary) {
                var libraryResolvedFile = {
                    path: this.getDefaultLibraryFilePath(),
                    referencedFiles: [],
                    importedFiles: []
                };

                resolvedFiles = [libraryResolvedFile].concat(resolvedFiles);
            }
            TypeScript.fileResolutionGetDefaultLibraryTime += new Date().getTime() - defaultLibStart;

            this.resolvedFiles = resolvedFiles;

            TypeScript.fileResolutionTime = new Date().getTime() - start;
        };

        BatchCompiler.prototype.compile = function () {
            var _this = this;
            var compiler = new TypeScript.TypeScriptCompiler(this.logger, this.compilationSettings);

            this.resolvedFiles.forEach(function (resolvedFile) {
                var sourceFile = _this.getSourceFile(resolvedFile.path);
                compiler.addFile(resolvedFile.path, sourceFile.scriptSnapshot, sourceFile.byteOrderMark, 0, false, resolvedFile.referencedFiles);
            });

            for (var it = compiler.compile(function (path) {
                return _this.resolvePath(path);
            }); it.moveNext();) {
                var result = it.current();

                result.diagnostics.forEach(function (d) {
                    return _this.addDiagnostic(d);
                });
                if (!this.tryWriteOutputFiles(result.outputFiles)) {
                    return;
                }
            }
        };

        BatchCompiler.prototype.parseOptions = function () {
            var _this = this;
            var opts = new TypeScript.OptionsParser(this.ioHost, this.compilerVersion);

            var mutableSettings = new TypeScript.CompilationSettings();
            opts.option('out', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Concatenate_and_emit_output_to_single_file,
                    args: null
                },
                type: TypeScript.DiagnosticCode.file2,
                set: function (str) {
                    mutableSettings.outFileOption = str;
                }
            });

            opts.option('outDir', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Redirect_output_structure_to_the_directory,
                    args: null
                },
                type: TypeScript.DiagnosticCode.DIRECTORY,
                set: function (str) {
                    mutableSettings.outDirOption = str;
                }
            });

            opts.flag('sourcemap', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Generates_corresponding_0_file,
                    args: ['.map']
                },
                set: function () {
                    mutableSettings.mapSourceFiles = true;
                }
            });

            opts.option('mapRoot', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
                    args: null
                },
                type: TypeScript.DiagnosticCode.LOCATION,
                set: function (str) {
                    mutableSettings.mapRoot = str;
                }
            });

            opts.option('sourceRoot', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
                    args: null
                },
                type: TypeScript.DiagnosticCode.LOCATION,
                set: function (str) {
                    mutableSettings.sourceRoot = str;
                }
            });

            opts.flag('declaration', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Generates_corresponding_0_file,
                    args: ['.d.ts']
                },
                set: function () {
                    mutableSettings.generateDeclarationFiles = true;
                }
            }, 'd');

            if (this.ioHost.watchFile) {
                opts.flag('watch', {
                    usage: {
                        locCode: TypeScript.DiagnosticCode.Watch_input_files,
                        args: null
                    },
                    set: function () {
                        mutableSettings.watch = true;
                    }
                }, 'w');
            }

            opts.flag('propagateEnumConstants', {
                experimental: true,
                set: function () {
                    mutableSettings.propagateEnumConstants = true;
                }
            });

            opts.flag('removeComments', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Do_not_emit_comments_to_output,
                    args: null
                },
                set: function () {
                    mutableSettings.removeComments = true;
                }
            });

            opts.flag('noResolve', {
                experimental: true,
                usage: {
                    locCode: TypeScript.DiagnosticCode.Skip_resolution_and_preprocessing,
                    args: null
                },
                set: function () {
                    mutableSettings.noResolve = true;
                }
            });

            opts.flag('noLib', {
                experimental: true,
                set: function () {
                    mutableSettings.noLib = true;
                }
            });

            opts.flag('diagnostics', {
                experimental: true,
                set: function () {
                    mutableSettings.gatherDiagnostics = true;
                }
            });

            opts.flag('logFile', {
                experimental: true,
                set: function () {
                    mutableSettings.createFileLog = true;
                }
            });

            opts.option('target', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Specify_ECMAScript_target_version_0_default_or_1,
                    args: ['ES3', 'ES5']
                },
                type: TypeScript.DiagnosticCode.VERSION,
                set: function (type) {
                    type = type.toLowerCase();

                    if (type === 'es3') {
                        mutableSettings.codeGenTarget = 0 /* EcmaScript3 */;
                    } else if (type === 'es5') {
                        mutableSettings.codeGenTarget = 1 /* EcmaScript5 */;
                    } else {
                        _this.addDiagnostic(new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.ECMAScript_target_version_0_not_supported_Specify_a_valid_target_version_1_default_or_2, [type, "ES3", "ES5"]));
                    }
                }
            }, 't');

            opts.option('module', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Specify_module_code_generation_0_or_1,
                    args: ['commonjs', 'amd']
                },
                type: TypeScript.DiagnosticCode.KIND,
                set: function (type) {
                    type = type.toLowerCase();

                    if (type === 'commonjs') {
                        mutableSettings.moduleGenTarget = 1 /* Synchronous */;
                    } else if (type === 'amd') {
                        mutableSettings.moduleGenTarget = 2 /* Asynchronous */;
                    } else {
                        _this.addDiagnostic(new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Module_code_generation_0_not_supported, [type]));
                    }
                }
            }, 'm');

            var needsHelp = false;
            opts.flag('help', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Print_this_message,
                    args: null
                },
                set: function () {
                    needsHelp = true;
                }
            }, 'h');

            opts.flag('useCaseSensitiveFileResolution', {
                experimental: true,
                set: function () {
                    mutableSettings.useCaseSensitiveFileResolution = true;
                }
            });
            var shouldPrintVersionOnly = false;
            opts.flag('version', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Print_the_compiler_s_version_0,
                    args: [this.compilerVersion]
                },
                set: function () {
                    shouldPrintVersionOnly = true;
                }
            }, 'v');

            var locale = null;
            opts.option('locale', {
                experimental: true,
                usage: {
                    locCode: TypeScript.DiagnosticCode.Specify_locale_for_errors_and_messages_For_example_0_or_1,
                    args: ['en', 'ja-jp']
                },
                type: TypeScript.DiagnosticCode.STRING,
                set: function (value) {
                    locale = value;
                }
            });

            opts.flag('noImplicitAny', {
                usage: {
                    locCode: TypeScript.DiagnosticCode.Warn_on_expressions_and_declarations_with_an_implied_any_type,
                    args: null
                },
                set: function () {
                    mutableSettings.noImplicitAny = true;
                }
            });

            if (TypeScript.Environment.supportsCodePage()) {
                opts.option('codepage', {
                    usage: {
                        locCode: TypeScript.DiagnosticCode.Specify_the_codepage_to_use_when_opening_source_files,
                        args: null
                    },
                    type: TypeScript.DiagnosticCode.NUMBER,
                    set: function (arg) {
                        mutableSettings.codepage = parseInt(arg, 10);
                    }
                });
            }

            opts.parse(this.ioHost.arguments);

            this.compilationSettings = TypeScript.ImmutableCompilationSettings.fromCompilationSettings(mutableSettings);

            if (locale) {
                if (!this.setLocale(locale)) {
                    return false;
                }
            }

            this.inputFiles.push.apply(this.inputFiles, opts.unnamed);

            if (shouldPrintVersionOnly) {
                opts.printVersion();
                return false;
            } else if (this.inputFiles.length === 0 || needsHelp) {
                opts.printUsage();
                return false;
            }

            return !this.hasErrors;
        };

        BatchCompiler.prototype.setLocale = function (locale) {
            var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
            if (!matchResult) {
                this.addDiagnostic(new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, ['en', 'ja-jp']));
                return false;
            }

            var language = matchResult[1];
            var territory = matchResult[3];

            if (!this.setLanguageAndTerritory(language, territory) && !this.setLanguageAndTerritory(language, null)) {
                this.addDiagnostic(new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Unsupported_locale_0, [locale]));
                return false;
            }

            return true;
        };

        BatchCompiler.prototype.setLanguageAndTerritory = function (language, territory) {
            var compilerFilePath = this.ioHost.getExecutingFilePath();
            var containingDirectoryPath = this.ioHost.dirName(compilerFilePath);

            var filePath = TypeScript.IOUtils.combine(containingDirectoryPath, language);
            if (territory) {
                filePath = filePath + "-" + territory;
            }

            filePath = this.resolvePath(TypeScript.IOUtils.combine(filePath, "diagnosticMessages.generated.json"));

            if (!this.fileExists(filePath)) {
                return false;
            }

            var fileContents = this.ioHost.readFile(filePath, this.compilationSettings.codepage());
            TypeScript.LocalizedDiagnosticMessages = JSON.parse(fileContents.contents);
            return true;
        };

        BatchCompiler.prototype.watchFiles = function () {
            var _this = this;
            if (!this.ioHost.watchFile) {
                this.addDiagnostic(new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Current_host_does_not_support_0_option, ['-w[atch]']));
                return;
            }

            var lastResolvedFileSet = [];
            var watchers = {};
            var firstTime = true;

            var addWatcher = function (fileName) {
                if (!watchers[fileName]) {
                    var watcher = _this.ioHost.watchFile(fileName, onWatchedFileChange);
                    watchers[fileName] = watcher;
                } else {
                    TypeScript.CompilerDiagnostics.debugPrint("Cannot watch file, it is already watched.");
                }
            };

            var removeWatcher = function (fileName) {
                if (watchers[fileName]) {
                    watchers[fileName].close();
                    delete watchers[fileName];
                } else {
                    TypeScript.CompilerDiagnostics.debugPrint("Cannot stop watching file, it is not being watched.");
                }
            };

            var onWatchedFileChange = function () {
                _this.hasErrors = false;

                _this.fileNameToSourceFile = new TypeScript.StringHashTable();

                _this.resolve();

                var oldFiles = lastResolvedFileSet;
                var newFiles = _this.resolvedFiles.map(function (resolvedFile) {
                    return resolvedFile.path;
                }).sort();

                var i = 0, j = 0;
                while (i < oldFiles.length && j < newFiles.length) {
                    var compareResult = oldFiles[i].localeCompare(newFiles[j]);
                    if (compareResult === 0) {
                        i++;
                        j++;
                    } else if (compareResult < 0) {
                        removeWatcher(oldFiles[i]);
                        i++;
                    } else {
                        addWatcher(newFiles[j]);
                        j++;
                    }
                }

                for (var k = i; k < oldFiles.length; k++) {
                    removeWatcher(oldFiles[k]);
                }

                for (k = j; k < newFiles.length; k++) {
                    addWatcher(newFiles[k]);
                }

                lastResolvedFileSet = newFiles;

                if (!firstTime) {
                    var fileNames = "";
                    for (var k = 0; k < lastResolvedFileSet.length; k++) {
                        fileNames += TypeScript.Environment.newLine + "    " + lastResolvedFileSet[k];
                    }
                    _this.ioHost.printLine(TypeScript.getLocalizedText(TypeScript.DiagnosticCode.NL_Recompiling_0, [fileNames]));
                } else {
                    firstTime = false;
                }

                _this.compile();
            };

            this.ioHost.stderr = this.ioHost.stdout;

            onWatchedFileChange();
        };

        BatchCompiler.prototype.getSourceFile = function (fileName) {
            var sourceFile = this.fileNameToSourceFile.lookup(fileName);
            if (!sourceFile) {
                var fileInformation;

                try  {
                    fileInformation = this.ioHost.readFile(fileName, this.compilationSettings.codepage());
                } catch (e) {
                    this.addDiagnostic(new TypeScript.Diagnostic(null, null, 0, 0, TypeScript.DiagnosticCode.Cannot_read_file_0_1, [fileName, e.message]));
                    fileInformation = new TypeScript.FileInformation("", 0 /* None */);
                }

                var snapshot = TypeScript.ScriptSnapshot.fromString(fileInformation.contents);
                var sourceFile = new SourceFile(snapshot, fileInformation.byteOrderMark);
                this.fileNameToSourceFile.add(fileName, sourceFile);
            }

            return sourceFile;
        };

        BatchCompiler.prototype.getDefaultLibraryFilePath = function () {
            var compilerFilePath = this.ioHost.getExecutingFilePath();
            var containingDirectoryPath = this.ioHost.dirName(compilerFilePath);
            var libraryFilePath = this.resolvePath(TypeScript.IOUtils.combine(containingDirectoryPath, "lib.d.ts"));

            return libraryFilePath;
        };

        BatchCompiler.prototype.getScriptSnapshot = function (fileName) {
            return this.getSourceFile(fileName).scriptSnapshot;
        };

        BatchCompiler.prototype.resolveRelativePath = function (path, directory) {
            var start = new Date().getTime();

            var unQuotedPath = TypeScript.stripStartAndEndQuotes(path);
            var normalizedPath;

            if (TypeScript.isRooted(unQuotedPath) || !directory) {
                normalizedPath = unQuotedPath;
            } else {
                normalizedPath = TypeScript.IOUtils.combine(directory, unQuotedPath);
            }

            normalizedPath = this.resolvePath(normalizedPath);

            normalizedPath = TypeScript.switchToForwardSlashes(normalizedPath);

            return normalizedPath;
        };

        BatchCompiler.prototype.fileExists = function (path) {
            var exists = this.fileExistsCache[path];
            if (exists === undefined) {
                var start = new Date().getTime();
                exists = this.ioHost.fileExists(path);
                this.fileExistsCache[path] = exists;
                TypeScript.compilerFileExistsTime += new Date().getTime() - start;
            }

            return exists;
        };

        BatchCompiler.prototype.getParentDirectory = function (path) {
            var start = new Date().getTime();
            var result = this.ioHost.dirName(path);
            TypeScript.compilerDirectoryNameTime += new Date().getTime() - start;

            return result;
        };

        BatchCompiler.prototype.addDiagnostic = function (diagnostic) {
            var _this = this;
            var diagnosticInfo = diagnostic.info();
            if (diagnosticInfo.category === 1 /* Error */) {
                this.hasErrors = true;
            }

            this.ioHost.stderr.Write(TypeScript.TypeScriptCompiler.getFullDiagnosticText(diagnostic, function (path) {
                return _this.resolvePath(path);
            }));
        };

        BatchCompiler.prototype.tryWriteOutputFiles = function (outputFiles) {
            for (var i = 0, n = outputFiles.length; i < n; i++) {
                var outputFile = outputFiles[i];

                try  {
                    this.writeFile(outputFile.name, outputFile.text, outputFile.writeByteOrderMark);
                } catch (e) {
                    this.addDiagnostic(new TypeScript.Diagnostic(outputFile.name, null, 0, 0, TypeScript.DiagnosticCode.Emit_Error_0, [e.message]));
                    return false;
                }
            }

            return true;
        };

        BatchCompiler.prototype.writeFile = function (fileName, contents, writeByteOrderMark) {
            var start = new Date().getTime();
            TypeScript.IOUtils.writeFileAndFolderStructure(this.ioHost, fileName, contents, writeByteOrderMark);
            TypeScript.emitWriteFileTime += new Date().getTime() - start;
        };

        BatchCompiler.prototype.directoryExists = function (path) {
            var start = new Date().getTime();
            var result = this.ioHost.directoryExists(path);
            TypeScript.compilerDirectoryExistsTime += new Date().getTime() - start;
            return result;
        };

        BatchCompiler.prototype.resolvePath = function (path) {
            var cachedValue = this.resolvePathCache[path];
            if (!cachedValue) {
                var start = new Date().getTime();
                cachedValue = this.ioHost.resolvePath(path);
                this.resolvePathCache[path] = cachedValue;
                TypeScript.compilerResolvePathTime += new Date().getTime() - start;
            }

            return cachedValue;
        };
        return BatchCompiler;
    })();
    TypeScript.BatchCompiler = BatchCompiler;

    var batch = new TypeScript.BatchCompiler(TypeScript.IO);
    batch.batchCompile();
})(TypeScript || (TypeScript = {}));