diff --git a/.editorconfig b/.editorconfig
index ba59a53f..7f421d03 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -41,220 +41,48 @@ indent_size = 4
 [*.{cmd,bat}]
 end_of_line = crlf
 
+[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
+indent_style = space
+indent_size = 2
+
+[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
+indent_style = space
+indent_size = 4
+tab_width = 4
+
 # Bash Files
 [*.sh]
 end_of_line = lf
-
 # C# files
 [*.cs]
-# Microsoft .NET properties
-csharp_new_line_before_members_in_object_initializers = false
-csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
-csharp_style_prefer_utf8_string_literals = true:suggestion
-csharp_style_var_elsewhere = true:suggestion
-csharp_style_var_for_built_in_types = true:suggestion
-csharp_style_var_when_type_is_apparent = true:suggestion
-dotnet_naming_rule.constants_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.constants_rule.severity = warning
-dotnet_naming_rule.constants_rule.style = pascal_case
-dotnet_naming_rule.constants_rule.symbols = constants_symbols
-dotnet_naming_rule.event_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.event_rule.severity = warning
-dotnet_naming_rule.event_rule.style = pascal_case
-dotnet_naming_rule.event_rule.symbols = event_symbols
-dotnet_naming_rule.interfaces_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.interfaces_rule.severity = warning
-dotnet_naming_rule.interfaces_rule.style = begins_with_i
-dotnet_naming_rule.interfaces_rule.symbols = interfaces_symbols
-dotnet_naming_rule.method_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.method_rule.severity = warning
-dotnet_naming_rule.method_rule.style = pascal_case
-dotnet_naming_rule.method_rule.symbols = method_symbols
-dotnet_naming_rule.private_constants_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.private_constants_rule.severity = warning
-dotnet_naming_rule.private_constants_rule.style = pascal_case
-dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
-dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.private_instance_fields_rule.severity = warning
-dotnet_naming_rule.private_instance_fields_rule.style = begins_with__
-dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
-dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.private_static_fields_rule.severity = warning
-dotnet_naming_rule.private_static_fields_rule.style = begins_with__
-dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
-dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.private_static_readonly_rule.severity = warning
-dotnet_naming_rule.private_static_readonly_rule.style = pascal_case
-dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols
-dotnet_naming_rule.property_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.property_rule.severity = warning
-dotnet_naming_rule.property_rule.style = pascal_case
-dotnet_naming_rule.property_rule.symbols = property_symbols
-dotnet_naming_rule.public_fields_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.public_fields_rule.severity = warning
-dotnet_naming_rule.public_fields_rule.style = pascal_case
-dotnet_naming_rule.public_fields_rule.symbols = public_fields_symbols
-dotnet_naming_rule.static_readonly_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.static_readonly_rule.severity = warning
-dotnet_naming_rule.static_readonly_rule.style = pascal_case
-dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols
-dotnet_naming_rule.types_and_namespaces_rule.import_to_resharper = as_predefined
-dotnet_naming_rule.types_and_namespaces_rule.severity = warning
-dotnet_naming_rule.types_and_namespaces_rule.style = pascal_case
-dotnet_naming_rule.types_and_namespaces_rule.symbols = types_and_namespaces_symbols
-dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
-dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
-dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
-dotnet_naming_rule.unity_serialized_field_rule.severity = warning
-dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
-dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
-dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
-dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
-dotnet_naming_symbols.constants_symbols.applicable_kinds = field
-dotnet_naming_symbols.constants_symbols.required_modifiers = const
-dotnet_naming_symbols.event_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.event_symbols.applicable_kinds = event
-dotnet_naming_symbols.interfaces_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.interfaces_symbols.applicable_kinds = interface
-dotnet_naming_symbols.method_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.method_symbols.applicable_kinds = method
-dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
-dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
-dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
-dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
-dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
-dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
-dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
-dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
-dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
-dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
-dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static,readonly
-dotnet_naming_symbols.property_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.property_symbols.applicable_kinds = property
-dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
-dotnet_naming_symbols.public_fields_symbols.applicable_kinds = field
-dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
-dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field
-dotnet_naming_symbols.static_readonly_symbols.required_modifiers = static,readonly
-dotnet_naming_symbols.types_and_namespaces_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.types_and_namespaces_symbols.applicable_kinds = namespace,class,struct,enum,delegate
-dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
-dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
-dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
-dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
-dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
-dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
-dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
-dotnet_style_predefined_type_for_member_access = true:suggestion
-dotnet_style_qualification_for_event = false:suggestion
-dotnet_style_qualification_for_field = false:suggestion
-dotnet_style_qualification_for_method = false:suggestion
-dotnet_style_qualification_for_property = false:suggestion
-dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
-
-# ReSharper properties
-resharper_autodetect_indent_settings = true
-resharper_braces_for_for = required
-resharper_braces_for_foreach = required
-resharper_braces_for_ifelse = required
-resharper_braces_for_while = required
-resharper_braces_redundant = false
-resharper_csharp_brace_style = next_line
-resharper_csharp_naming_rule.constants = AaBb
-resharper_csharp_naming_rule.event = AaBb
-resharper_csharp_naming_rule.interfaces = I + AaBb
-resharper_csharp_naming_rule.method = AaBb
-resharper_csharp_naming_rule.private_constants = AaBb
-resharper_csharp_naming_rule.private_instance_fields = _ + aaBb
-resharper_csharp_naming_rule.private_static_fields = _ + aaBb
-resharper_csharp_naming_rule.private_static_readonly = AaBb
-resharper_csharp_naming_rule.property = AaBb
-resharper_csharp_naming_rule.public_fields = AaBb
-resharper_csharp_naming_rule.static_readonly = AaBb
-resharper_csharp_naming_rule.types_and_namespaces = AaBb
-resharper_formatter_off_tag = @formatter:off
-resharper_formatter_on_tag = @formatter:on
-resharper_formatter_tags_enabled = true
-resharper_keep_existing_declaration_block_arrangement = false
-resharper_keep_existing_embedded_block_arrangement = false
-resharper_keep_existing_enum_arrangement = false
-resharper_use_heuristics_for_body_style = true
-resharper_use_indent_from_vs = false
-
-# ReSharper inspection severities
-resharper_arrange_accessor_owner_body_highlighting = suggestion
-resharper_arrange_redundant_parentheses_highlighting = hint
-resharper_arrange_this_qualifier_highlighting = hint
-resharper_arrange_type_member_modifiers_highlighting = hint
-resharper_arrange_type_modifiers_highlighting = hint
-resharper_built_in_type_reference_style_for_member_access_highlighting = hint
-resharper_built_in_type_reference_style_highlighting = hint
-resharper_enforce_do_while_statement_braces_highlighting = warning
-resharper_enforce_fixed_statement_braces_highlighting = warning
-resharper_enforce_foreach_statement_braces_highlighting = warning
-resharper_enforce_for_statement_braces_highlighting = warning
-resharper_enforce_if_statement_braces_highlighting = warning
-resharper_enforce_lock_statement_braces_highlighting = warning
-resharper_enforce_using_statement_braces_highlighting = warning
-resharper_enforce_while_statement_braces_highlighting = warning
-resharper_redundant_base_qualifier_highlighting = warning
-resharper_suggest_var_or_type_built_in_types_highlighting = hint
-resharper_suggest_var_or_type_elsewhere_highlighting = hint
-resharper_suggest_var_or_type_simple_types_highlighting = hint
-resharper_web_config_module_not_resolved_highlighting = warning
-resharper_web_config_type_not_resolved_highlighting = warning
-resharper_web_config_wrong_module_highlighting = warning
 
+#### Core EditorConfig Options ####
 
-dotnet_style_operator_placement_when_wrapping = beginning_of_line
-dotnet_style_coalesce_expression = true:suggestion
-dotnet_style_null_propagation = true:suggestion
-dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
-dotnet_style_prefer_auto_properties = true:silent
-dotnet_style_object_initializer = true:suggestion
-dotnet_style_collection_initializer = true:suggestion
-dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
-dotnet_style_prefer_conditional_expression_over_assignment = true:silent
-dotnet_style_prefer_conditional_expression_over_return = true:silent
-dotnet_style_explicit_tuple_names = true:suggestion
-dotnet_style_prefer_inferred_tuple_names = true:suggestion
-dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
-dotnet_style_prefer_compound_assignment = true:suggestion
-dotnet_style_prefer_simplified_interpolation = true:suggestion
-dotnet_style_namespace_match_folder = true:suggestion
-dotnet_style_readonly_field = true:suggestion
-dotnet_style_predefined_type_for_locals_parameters_members = true:silent
-dotnet_style_predefined_type_for_member_access = true:silent
-dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
-dotnet_style_allow_multiple_blank_lines_experimental = true:silent
-dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
-dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
-dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
-dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
-dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
-dotnet_code_quality_unused_parameters = all:suggestion
-dotnet_style_qualification_for_event = false:silent
-dotnet_style_qualification_for_method = false:silent
-dotnet_style_qualification_for_property = false:silent
-dotnet_style_qualification_for_field = false:silent
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
 
 #### .NET Coding Conventions ####
 
 # Organize usings
 dotnet_separate_import_directive_groups = false
 dotnet_sort_system_directives_first = true
-file_header_template =
+file_header_template = unset
 
 # this. and Me. preferences
-dotnet_style_qualification_for_event = false
+dotnet_style_qualification_for_event = false:warning
 dotnet_style_qualification_for_field = false
-dotnet_style_qualification_for_method = false
-dotnet_style_qualification_for_property = false
+dotnet_style_qualification_for_method = false:warning
+dotnet_style_qualification_for_property = false:warning
 
 # Language keywords vs BCL types preferences
-dotnet_style_predefined_type_for_locals_parameters_members = true
-dotnet_style_predefined_type_for_member_access = true
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
 
 # Parentheses preferences
 dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
@@ -273,10 +101,11 @@ dotnet_style_namespace_match_folder = true
 dotnet_style_null_propagation = true
 dotnet_style_object_initializer = true
 dotnet_style_operator_placement_when_wrapping = beginning_of_line
-dotnet_style_prefer_auto_properties = true
+dotnet_style_prefer_auto_properties = true:suggestion
+dotnet_style_prefer_collection_expression = true
 dotnet_style_prefer_compound_assignment = true
-dotnet_style_prefer_conditional_expression_over_assignment = true
-dotnet_style_prefer_conditional_expression_over_return = true
+dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_return = true:suggestion
 dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
 dotnet_style_prefer_inferred_anonymous_type_member_names = true
 dotnet_style_prefer_inferred_tuple_names = true
@@ -285,7 +114,7 @@ dotnet_style_prefer_simplified_boolean_expressions = true
 dotnet_style_prefer_simplified_interpolation = true
 
 # Field preferences
-dotnet_style_readonly_field = true
+dotnet_style_readonly_field = true:warning
 
 # Parameter preferences
 dotnet_code_quality_unused_parameters = all
@@ -300,65 +129,69 @@ dotnet_style_allow_statement_immediately_after_block_experimental = true
 #### C# Coding Conventions ####
 
 # var preferences
-csharp_style_var_elsewhere = false:silent
-csharp_style_var_for_built_in_types = false:silent
-csharp_style_var_when_type_is_apparent = false:silent
+csharp_style_var_elsewhere = true:suggestion
+csharp_style_var_for_built_in_types = true:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
 
 # Expression-bodied members
-csharp_style_expression_bodied_accessors = true:silent
-csharp_style_expression_bodied_constructors = false:silent
-csharp_style_expression_bodied_indexers = true:silent
-csharp_style_expression_bodied_lambdas = true:silent
-csharp_style_expression_bodied_local_functions = false:silent
-csharp_style_expression_bodied_methods = false:silent
-csharp_style_expression_bodied_operators = false:silent
-csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_accessors = true
+csharp_style_expression_bodied_constructors = false
+csharp_style_expression_bodied_indexers = true
+csharp_style_expression_bodied_lambdas = true
+csharp_style_expression_bodied_local_functions = false
+csharp_style_expression_bodied_methods = false
+csharp_style_expression_bodied_operators = false
+csharp_style_expression_bodied_properties = true
 
 # Pattern matching preferences
-csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
-csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
-csharp_style_prefer_extended_property_pattern = true:suggestion
-csharp_style_prefer_not_pattern = true:suggestion
-csharp_style_prefer_pattern_matching = true:silent
-csharp_style_prefer_switch_expression = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true
+csharp_style_pattern_matching_over_is_with_cast_check = true
+csharp_style_prefer_extended_property_pattern = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_pattern_matching = true:suggestion
+csharp_style_prefer_switch_expression = true
 
 # Null-checking preferences
-csharp_style_conditional_delegate_call = true:suggestion
+csharp_style_conditional_delegate_call = true
 
 # Modifier preferences
-csharp_prefer_static_local_function = true:suggestion
+csharp_prefer_static_local_function = true
 csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
-csharp_style_prefer_readonly_struct = true:suggestion
-csharp_style_prefer_readonly_struct_member = true:suggestion
+csharp_style_prefer_readonly_struct = true
+csharp_style_prefer_readonly_struct_member = true
 
 # Code-block preferences
-csharp_prefer_simple_using_statement = true:silent
-csharp_style_prefer_method_group_conversion = true:silent
-csharp_style_prefer_top_level_statements = true:silent
+csharp_prefer_braces = true:warning
+csharp_prefer_simple_using_statement = true
+csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_prefer_method_group_conversion = true
+csharp_style_prefer_primary_constructors = true
+csharp_style_prefer_top_level_statements = true
 
 # Expression-level preferences
-csharp_prefer_simple_default_expression = true:suggestion
-csharp_style_deconstructed_variable_declaration = true:suggestion
-csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
-csharp_style_inlined_variable_declaration = true:suggestion
-csharp_style_prefer_index_operator = true:suggestion
-csharp_style_prefer_local_over_anonymous_function = true:suggestion
-csharp_style_prefer_null_check_over_type_check = true:suggestion
-csharp_style_prefer_range_operator = true:suggestion
-csharp_style_prefer_tuple_swap = true:suggestion
-csharp_style_prefer_utf8_string_literals = true:suggestion
-csharp_style_throw_expression = true:suggestion
-csharp_style_unused_value_assignment_preference = discard_variable:suggestion
-csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+csharp_prefer_simple_default_expression = true
+csharp_style_deconstructed_variable_declaration = true
+csharp_style_implicit_object_creation_when_type_is_apparent = true
+csharp_style_inlined_variable_declaration = true
+csharp_style_prefer_index_operator = true
+csharp_style_prefer_local_over_anonymous_function = true
+csharp_style_prefer_null_check_over_type_check = true
+csharp_style_prefer_range_operator = true
+csharp_style_prefer_tuple_swap = true
+csharp_style_prefer_utf8_string_literals = true
+csharp_style_throw_expression = true
+csharp_style_unused_value_assignment_preference = discard_variable
+csharp_style_unused_value_expression_statement_preference = discard_variable
 
 # 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:warning
 
 # New line preferences
-csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
-csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
-csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
-csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
-csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
+csharp_style_allow_embedded_statements_on_same_line_experimental = true
 
 #### C# Formatting Rules ####
 
@@ -411,94 +244,78 @@ csharp_preserve_single_line_statements = true
 
 # Naming rules
 
-dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
 dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
 dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
 
-dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.severity = warning
 dotnet_naming_rule.types_should_be_pascal_case.symbols = types
 dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
 
-dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
 dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
 dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
 
+dotnet_naming_rule.property_should_be_pascal_case.severity = warning
+dotnet_naming_rule.property_should_be_pascal_case.symbols = property
+dotnet_naming_rule.property_should_be_pascal_case.style = pascal_case
+
 dotnet_naming_rule.private_or_internal_field_should_be_begins_with__.severity = warning
 dotnet_naming_rule.private_or_internal_field_should_be_begins_with__.symbols = private_or_internal_field
 dotnet_naming_rule.private_or_internal_field_should_be_begins_with__.style = begins_with__
 
-dotnet_naming_rule.static_field_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
-dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
-
 # Symbol specifications
 
 dotnet_naming_symbols.interface.applicable_kinds = interface
 dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.interface.required_modifiers =
+dotnet_naming_symbols.interface.required_modifiers = 
 
-dotnet_naming_symbols.static_field.applicable_kinds = field
-dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.static_field.required_modifiers = static
+dotnet_naming_symbols.property.applicable_kinds = property
+dotnet_naming_symbols.property.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.property.required_modifiers = 
 
 dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
 dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
-dotnet_naming_symbols.private_or_internal_field.required_modifiers =
+dotnet_naming_symbols.private_or_internal_field.required_modifiers = 
 
 dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
 dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.types.required_modifiers =
+dotnet_naming_symbols.types.required_modifiers = 
 
 dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
 dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
-dotnet_naming_symbols.non_field_members.required_modifiers =
+dotnet_naming_symbols.non_field_members.required_modifiers = 
 
 # Naming styles
 
-dotnet_naming_style.pascal_case.required_prefix =
-dotnet_naming_style.pascal_case.required_suffix =
-dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.required_prefix = 
+dotnet_naming_style.pascal_case.required_suffix = 
+dotnet_naming_style.pascal_case.word_separator = 
 dotnet_naming_style.pascal_case.capitalization = pascal_case
 
 dotnet_naming_style.begins_with_i.required_prefix = I
-dotnet_naming_style.begins_with_i.required_suffix =
-dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.required_suffix = 
+dotnet_naming_style.begins_with_i.word_separator = 
 dotnet_naming_style.begins_with_i.capitalization = pascal_case
 
 dotnet_naming_style.begins_with__.required_prefix = _
-dotnet_naming_style.begins_with__.required_suffix =
-dotnet_naming_style.begins_with__.word_separator =
+dotnet_naming_style.begins_with__.required_suffix = 
+dotnet_naming_style.begins_with__.word_separator = 
 dotnet_naming_style.begins_with__.capitalization = camel_case
 
-#
-dotnet_style_allow_multiple_blank_lines_experimental = true:silent
-dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
 
-#
 dotnet_analyzer_diagnostic.category-roslynator.severity = warning
-# Enable/disable all analyzers by default
-# NOTE: This option can be used only in .roslynatorconfig file
 roslynator_analyzers.enabled_by_default = true
-
-# Enable/disable all refactorings
 roslynator_refactorings.enabled = true
-
-# Enable/disable all compiler diagnostic fixes
 roslynator_compiler_diagnostic_fixes.enabled = true
-tab_width = 4
+ 
+# roslynator_refactoring.<REFACTORING_NAME>.enabled = true
+# roslynator_compiler_diagnostic_fix.<COMPILER_DIAGNOSTIC_ID>.enabled = true|false 
+# dotnet_diagnostic.<ANALYZER_ID>.severity = default|none|silent|suggestion|warning|error
 
-#
+dotnet_diagnostic.Ca2016.severity = warning
+dotnet_diagnostic.RCS1251.severity = none
 dotnet_diagnostic.CA1848.severity = silent
-dotnet_diagnostic.CA1305.severity = silent
-dotnet_diagnostic.CA2016.severity = warning
+dotnet_diagnostic.CA1305.severity = silent 
 dotnet_diagnostic.ide0011.severity = warning
-dotnet_diagnostic.RCS1251.severity = silent
-
-[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
-indent_style = space
-indent_size = 2
-
-[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
-indent_style = space
-indent_size = 4
-tab_width = 4
+dotnet_diagnostic.RCS1251.severity = silent
\ No newline at end of file
diff --git a/src/Passingwind.Abp.ElsaModule.Application/Workflow/DesignerAppService.cs b/src/Passingwind.Abp.ElsaModule.Application/Workflow/DesignerAppService.cs
index d709ed7b..31c0e9f9 100644
--- a/src/Passingwind.Abp.ElsaModule.Application/Workflow/DesignerAppService.cs
+++ b/src/Passingwind.Abp.ElsaModule.Application/Workflow/DesignerAppService.cs
@@ -11,6 +11,7 @@
 using Elsa.Services;
 using Elsa.Services.Models;
 using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.Logging;
 using Passingwind.Abp.ElsaModule.Common;
 using Passingwind.Abp.ElsaModule.CSharp;
 using Passingwind.Abp.ElsaModule.Permissions;
@@ -128,12 +129,20 @@ public async Task<WorkflowDesignerCSharpLanguageCompletionProviderResultDto> CSh
 
         var workflowDefinition = _storeMapper.MapToModel(version, definition);
 
-        var result = await _workflowCSharpEditorService.GetCompletionAsync(workflowDefinition, input.Id, input.Text, input.Position);
+        try
+        {
+            var result = await _workflowCSharpEditorService.GetCompletionAsync(workflowDefinition, input.Id, input.Text, input.Position);
 
-        return new WorkflowDesignerCSharpLanguageCompletionProviderResultDto
+            return new WorkflowDesignerCSharpLanguageCompletionProviderResultDto
+            {
+                Items = result?.Items ?? new List<WorkflowCSharpEditorCompletionItem>(),
+            };
+        }
+        catch (Exception ex)
         {
-            Items = result?.Items ?? new List<WorkflowCSharpEditorCompletionItem>(),
-        };
+            Logger.LogError(ex, "Get csharp language completions failed.");
+            return new WorkflowDesignerCSharpLanguageCompletionProviderResultDto();
+        }
     }
 
     public async Task<WorkflowDesignerCSharpLanguageHoverProviderResultDto> CSharpLanguageHoverProviderAsync(Guid id, WorkflowDesignerCSharpLanguageHoverProviderRequestDto input)
@@ -143,17 +152,27 @@ public async Task<WorkflowDesignerCSharpLanguageHoverProviderResultDto> CSharpLa
 
         var workflowDefinition = _storeMapper.MapToModel(version, definition);
 
-        var result = await _workflowCSharpEditorService.GetHoverInfoAsync(workflowDefinition, input.Id, input.Text, input.Position);
-
-        if (result == null)
-            return null;
-
-        return new WorkflowDesignerCSharpLanguageHoverProviderResultDto
+        try
         {
-            Information = result.Information,
-            OffsetFrom = result.OffsetFrom,
-            OffsetTo = result.OffsetTo,
-        };
+            var result = await _workflowCSharpEditorService.GetHoverInfoAsync(workflowDefinition, input.Id, input.Text, input.Position);
+
+            if (result == null)
+            {
+                return null;
+            }
+
+            return new WorkflowDesignerCSharpLanguageHoverProviderResultDto
+            {
+                Information = result.Information,
+                OffsetFrom = result.OffsetFrom,
+                OffsetTo = result.OffsetTo,
+            };
+        }
+        catch (Exception ex)
+        {
+            Logger.LogError(ex, "Get csharp language hover info failed.");
+            return null;
+        }
     }
 
     public async Task<WorkflowDesignerCSharpLanguageSignatureProviderResultDto> CSharpLanguageSignatureProviderAsync(Guid id, WorkflowDesignerCSharpLanguageSignatureProviderRequestDto input)
@@ -163,17 +182,25 @@ public async Task<WorkflowDesignerCSharpLanguageSignatureProviderResultDto> CSha
 
         var workflowDefinition = _storeMapper.MapToModel(version, definition);
 
-        var result = await _workflowCSharpEditorService.GetSignaturesAsync(workflowDefinition, input.Id, input.Text, input.Position);
+        try
+        {
+            var result = await _workflowCSharpEditorService.GetSignaturesAsync(workflowDefinition, input.Id, input.Text, input.Position);
 
-        if (result == null)
-            return null;
+            if (result == null)
+                return null;
 
-        return new WorkflowDesignerCSharpLanguageSignatureProviderResultDto
+            return new WorkflowDesignerCSharpLanguageSignatureProviderResultDto
+            {
+                Signatures = result.Signatures,
+                ActiveParameter = result.ActiveParameter,
+                ActiveSignature = result.ActiveSignature,
+            };
+        }
+        catch (Exception ex)
         {
-            Signatures = result.Signatures,
-            ActiveParameter = result.ActiveParameter,
-            ActiveSignature = result.ActiveSignature,
-        };
+            Logger.LogError(ex, "Get csharp language signature failed.");
+            return null;
+        }
     }
 
     public async Task<WorkflowDesignerCSharpLanguageAnalysisResultDto> CSharpLanguageCodeAnalysisAsync(Guid id, WorkflowDesignerCSharpLanguageAnalysisRequestDto input)
@@ -183,12 +210,20 @@ public async Task<WorkflowDesignerCSharpLanguageAnalysisResultDto> CSharpLanguag
 
         var workflowDefinition = _storeMapper.MapToModel(version, definition);
 
-        var result = await _workflowCSharpEditorService.GetCodeAnalysisAsync(workflowDefinition, input.Id, input.Text);
+        try
+        {
+            var result = await _workflowCSharpEditorService.GetCodeAnalysisAsync(workflowDefinition, input.Id, input.Text);
 
-        return new WorkflowDesignerCSharpLanguageAnalysisResultDto
+            return new WorkflowDesignerCSharpLanguageAnalysisResultDto
+            {
+                Items = result?.Items ?? new List<WorkflowCSharpEditorCodeAnalysis>(),
+            };
+        }
+        catch (Exception ex)
         {
-            Items = result?.Items ?? new List<WorkflowCSharpEditorCodeAnalysis>(),
-        };
+            Logger.LogError(ex, "Get csharp language analysis failed.");
+            return new WorkflowDesignerCSharpLanguageAnalysisResultDto();
+        }
     }
 
     public async Task<WorkflowDesignerCSharpLanguageFormatterResult> CSharpLanguageCodeFormatterAsync(WorkflowDesignerCSharpLanguageFormatterRequestDto input)
diff --git a/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Scripting/CSharp/CSharpService.cs b/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Scripting/CSharp/CSharpService.cs
index dff9e5d8..a146281c 100644
--- a/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Scripting/CSharp/CSharpService.cs
+++ b/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Scripting/CSharp/CSharpService.cs
@@ -36,7 +36,7 @@ public async Task<object> EvaluateAsync(string expression, Type returnType, Acti
         CSharpScriptConfigureNotification scriptConfigure = new(expression);
         await _mediator.Publish(scriptConfigure, cancellationToken);
 
-        string scriptId = $"{context.WorkflowExecutionContext.WorkflowBlueprint.VersionId}:{context.ActivityId}";
+        string scriptId = $"{context.WorkflowExecutionContext.WorkflowBlueprint.VersionId}_{context.ActivityId}".Replace("-", null);
 
         _logger.LogDebug("Evaluate csharp code with id '{ScriptId}' ", scriptId);
 
@@ -47,7 +47,7 @@ public async Task<object> EvaluateAsync(string expression, Type returnType, Acti
 
         Stopwatch sw = Stopwatch.StartNew();
 
-        object resultValue = await _cSharpScriptHost.RunAsync(scriptContext, cancellationToken: cancellationToken);
+        var resultValue = await _cSharpScriptHost.RunAsync(scriptContext, cancellationToken: cancellationToken);
 
         sw.Stop();
 
diff --git a/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Services/WorkflowCSharpEditorService.cs b/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Services/WorkflowCSharpEditorService.cs
index 6ae643f0..3d66564e 100644
--- a/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Services/WorkflowCSharpEditorService.cs
+++ b/src/Passingwind.Abp.ElsaModule.ElsaExtensions/Services/WorkflowCSharpEditorService.cs
@@ -11,6 +11,7 @@
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.Formatting;
 using Microsoft.CodeAnalysis.Shared.Extensions;
+using Microsoft.CodeAnalysis.Text;
 using Microsoft.Extensions.Logging;
 using Passingwind.Abp.ElsaModule.CSharp;
 using Passingwind.Abp.ElsaModule.Scripting.CSharp;
@@ -20,7 +21,7 @@ namespace Passingwind.Abp.ElsaModule.Services;
 
 public class WorkflowCSharpEditorService : IWorkflowCSharpEditorService
 {
-    private const string GeneratedTypeClassName = "GeneratedTypes";
+    private const string _generatedTypeClassName = "GeneratedTypes";
 
     private readonly ILogger<WorkflowCSharpEditorService> _logger;
     private readonly ICSharpTypeDefinitionService _cSharpTypeDefinitionService;
@@ -33,7 +34,7 @@ public WorkflowCSharpEditorService(ILogger<WorkflowCSharpEditorService> logger,
         _cSharpScriptWorkspace = cSharpScriptWorkspace;
     }
 
-    public async Task<WorkflowCSharpEditorCodeAnalysisResult> GetCodeAnalysisAsync(WorkflowDefinition workflowDefinition, string textId, string text, CancellationToken cancellationToken = default)
+    protected async Task<ICSharpScriptProject> GetProjectAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default)
     {
         var generated = await _cSharpTypeDefinitionService.GenerateAsync(workflowDefinition, cancellationToken);
 
@@ -41,13 +42,28 @@ public async Task<WorkflowCSharpEditorCodeAnalysisResult> GetCodeAnalysisAsync(W
 
         var project = _cSharpScriptWorkspace.GetOrCreateProject(projectName);
 
-        project.CreateOrUpdateDocument(GeneratedTypeClassName, generated.Text);
+        // add default
+        _ = project.CreateOrUpdateDocument(_generatedTypeClassName, generated.Text);
+
+        _ = project.AddImports(generated.Imports)
+            .AddReferences(generated.Assemblies);
+
+        return project;
+    }
+
+    public async Task<WorkflowCSharpEditorCodeAnalysisResult> GetCodeAnalysisAsync(WorkflowDefinition workflowDefinition, string textId, string text, CancellationToken cancellationToken = default)
+    {
+        var project = await GetProjectAsync(workflowDefinition, cancellationToken);
 
         project.CreateOrUpdateDocument(textId, text);
 
+#if DEBUG
+        await project.SaveAsync();
+#endif
+
         var tmpFile = Path.GetTempFileName();
 
-        var compilation = await _cSharpScriptWorkspace.CreateCompilationAsync(project, cancellationToken);
+        var compilation = await _cSharpScriptWorkspace.CreateCompilationAsync(project, true, cancellationToken);
 
         var emitResult = compilation.Emit(tmpFile, cancellationToken: cancellationToken);
 
@@ -55,7 +71,7 @@ public async Task<WorkflowCSharpEditorCodeAnalysisResult> GetCodeAnalysisAsync(W
 
         if (emitResult?.Success == false)
         {
-            foreach (var diagnostic in emitResult.Diagnostics)
+            foreach (var diagnostic in emitResult.Diagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning))
             {
                 var severity = MapDiagnosticSeverity(diagnostic);
 
@@ -77,11 +93,15 @@ public async Task<WorkflowCSharpEditorCodeAnalysisResult> GetCodeAnalysisAsync(W
 
     public async Task<WorkflowCSharpEditorFormatterResult> CodeFormatterAsync(string textId, string text, CancellationToken cancellationToken = default)
     {
-        var project = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "tmp", "tmp", LanguageNames.CSharp);
-        var documentInfo = DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "tmp");
+        using var workspce = new AdhocWorkspace();
+
+        var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "tmp", "tmp", LanguageNames.CSharp);
 
-        using AdhocWorkspace workspce = new AdhocWorkspace();
-        var document = workspce.AddDocument(documentInfo);
+        var project = workspce.AddProject(projectInfo);
+
+        var document = workspce.AddDocument(project.Id, "tmp", SourceText.From(text));
+
+        _ = workspce.TryApplyChanges(workspce.CurrentSolution);
 
         var formattedDocument = await Formatter.FormatAsync(document, cancellationToken: cancellationToken);
         var sourceText = await formattedDocument.GetTextAsync(cancellationToken);
@@ -94,23 +114,28 @@ public async Task<WorkflowCSharpEditorFormatterResult> CodeFormatterAsync(string
 
     public async Task<WorkflowCSharpEditorCompletionResult> GetCompletionAsync(WorkflowDefinition workflowDefinition, string textId, string text, int position, CancellationToken cancellationToken = default)
     {
-        var generated = await _cSharpTypeDefinitionService.GenerateAsync(workflowDefinition, cancellationToken);
+        var project = await GetProjectAsync(workflowDefinition, cancellationToken);
 
-        var projectName = workflowDefinition.DefinitionId.Replace("-", null);
+        if (position > text.Length)
+        {
+            position = text.Length;
+        }
 
-        var project = _cSharpScriptWorkspace.GetOrCreateProject(projectName);
+        var document = project.CreateOrUpdateDocument(textId, text);
 
-        project.CreateOrUpdateDocument(GeneratedTypeClassName, generated.Text);
+#if DEBUG
+        await project.SaveAsync();
+#endif
 
-        var document = project.CreateOrUpdateDocument(textId, text);
+        await _cSharpScriptWorkspace.RestoreReferenceAsync(project, cancellationToken);
 
-        var completionItems = await project.GetCompletionsAsync(document, position);
+        var completionItems = await _cSharpScriptWorkspace.GetCompletionsAsync(project, document.Id, position, cancellationToken: cancellationToken);
 
         var result = new List<WorkflowCSharpEditorCompletionItem>();
 
         foreach (var item in completionItems)
         {
-            SymbolKind symbolKind = SymbolKind.Local;
+            var symbolKind = SymbolKind.Local;
             if (item.Properties.TryGetValue(nameof(SymbolKind), out var kindValue))
             {
                 symbolKind = Enum.Parse<SymbolKind>(kindValue);
@@ -129,44 +154,33 @@ public async Task<WorkflowCSharpEditorCompletionResult> GetCompletionAsync(Workf
 
         return new WorkflowCSharpEditorCompletionResult(result);
 
-        WorkflowCSharpEditorCompletionItemKind MapKind(SymbolKind symbolKind)
+        static WorkflowCSharpEditorCompletionItemKind MapKind(SymbolKind symbolKind)
         {
-            switch (symbolKind)
+            return symbolKind switch
             {
-                case SymbolKind.Field:
-                    return WorkflowCSharpEditorCompletionItemKind.Field;
-
-                case SymbolKind.Property:
-                    return WorkflowCSharpEditorCompletionItemKind.Property;
-
-                case SymbolKind.Local:
-                    return WorkflowCSharpEditorCompletionItemKind.Variable;
-
-                case SymbolKind.Method:
-                    return WorkflowCSharpEditorCompletionItemKind.Function;
-
-                case SymbolKind.NamedType:
-                    return WorkflowCSharpEditorCompletionItemKind.Class;
-
-                default:
-                    return WorkflowCSharpEditorCompletionItemKind.Others;
-            }
+                SymbolKind.Field => WorkflowCSharpEditorCompletionItemKind.Field,
+                SymbolKind.Property => WorkflowCSharpEditorCompletionItemKind.Property,
+                SymbolKind.Local => WorkflowCSharpEditorCompletionItemKind.Variable,
+                SymbolKind.Method => WorkflowCSharpEditorCompletionItemKind.Function,
+                SymbolKind.NamedType => WorkflowCSharpEditorCompletionItemKind.Class,
+                _ => WorkflowCSharpEditorCompletionItemKind.Others,
+            };
         }
     }
 
     public async Task<WorkflowCSharpEditorHoverInfoResult> GetHoverInfoAsync(WorkflowDefinition workflowDefinition, string textId, string text, int position, CancellationToken cancellationToken = default)
     {
-        var generated = await _cSharpTypeDefinitionService.GenerateAsync(workflowDefinition, cancellationToken);
-
-        var projectName = workflowDefinition.DefinitionId.Replace("-", null);
+        var project = await GetProjectAsync(workflowDefinition, cancellationToken);
 
-        var project = _cSharpScriptWorkspace.GetOrCreateProject(projectName);
+        var document = project.CreateOrUpdateDocument(textId, text);
 
-        project.CreateOrUpdateDocument(GeneratedTypeClassName, generated.Text);
+#if DEBUG
+        await project.SaveAsync();
+#endif
 
-        var document = project.CreateOrUpdateDocument(textId, text);
+        await _cSharpScriptWorkspace.RestoreReferenceAsync(project, cancellationToken);
 
-        var compilation = await _cSharpScriptWorkspace.CreateCompilationAsync(project, cancellationToken);
+        var compilation = await _cSharpScriptWorkspace.CreateCompilationAsync(project, false, cancellationToken);
 
         var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken);
 
@@ -178,7 +192,7 @@ public async Task<WorkflowCSharpEditorHoverInfoResult> GetHoverInfoAsync(Workflo
         TypeInfo typeInfo;
         if (expressionNode is VariableDeclaratorSyntax)
         {
-            SyntaxNode childNode = expressionNode.ChildNodes()?.FirstOrDefault()?.ChildNodes()?.FirstOrDefault();
+            var childNode = expressionNode.ChildNodes()?.FirstOrDefault()?.ChildNodes()?.FirstOrDefault();
             if (childNode != null)
             {
                 typeInfo = semanticModel.GetTypeInfo(childNode, cancellationToken: cancellationToken);
@@ -249,29 +263,33 @@ public async Task<WorkflowCSharpEditorHoverInfoResult> GetHoverInfoAsync(Workflo
 
     public async Task<WorkflowCSharpEditorSignatureResult> GetSignaturesAsync(WorkflowDefinition workflowDefinition, string textId, string text, int position, CancellationToken cancellationToken = default)
     {
-        var generated = await _cSharpTypeDefinitionService.GenerateAsync(workflowDefinition, cancellationToken);
-
-        var projectName = workflowDefinition.DefinitionId.Replace("-", null);
-
-        var project = _cSharpScriptWorkspace.GetOrCreateProject(projectName);
-
-        project.CreateOrUpdateDocument(GeneratedTypeClassName, generated.Text);
+        var project = await GetProjectAsync(workflowDefinition, cancellationToken);
 
         var document = project.CreateOrUpdateDocument(textId, text);
 
-        var compilation = await _cSharpScriptWorkspace.CreateCompilationAsync(project, cancellationToken);
+#if DEBUG
+        await project.SaveAsync();
+#endif
+        await _cSharpScriptWorkspace.RestoreReferenceAsync(project, cancellationToken);
+
+        var compilation = await _cSharpScriptWorkspace.CreateCompilationAsync(project, false, cancellationToken);
 
         var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken);
         var semanticModel = compilation.GetSemanticModel(syntaxTree, true);
 
         var invocation = await InvocationContext.GetInvocation(document, position);
-        if (invocation == null) return null;
+        if (invocation == null)
+        {
+            return null;
+        }
 
-        int activeParameter = 0;
+        var activeParameter = 0;
         foreach (var comma in invocation.Separators)
         {
             if (comma.Span.Start > invocation.Position)
+            {
                 break;
+            }
 
             activeParameter++;
         }
@@ -290,7 +308,7 @@ public async Task<WorkflowCSharpEditorSignatureResult> GetSignaturesAsync(Workfl
             var typeInfo = semanticModel.GetTypeInfo(throughExpression, cancellationToken: cancellationToken);
             throughSymbol = invocation.SemanticModel.GetSpeculativeSymbolInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsExpression).Symbol;
             throughType = invocation.SemanticModel.GetSpeculativeTypeInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsTypeOrNamespace).Type;
-            var includeInstance = (throughSymbol != null && !(throughSymbol is ITypeSymbol)) ||
+            var includeInstance = (throughSymbol != null && throughSymbol is not ITypeSymbol) ||
                 throughExpression is LiteralExpressionSyntax ||
                 throughExpression is TypeOfExpressionSyntax;
             var includeStatic = throughSymbol is INamedTypeSymbol || throughType != null;
@@ -344,35 +362,52 @@ private static string HoverInfoBuild(SymbolInfo symbolInfo)
         {
             var sb = new StringBuilder().Append("(method) ").Append(methodsymbol.DeclaredAccessibility.ToString().ToLower(System.Globalization.CultureInfo.CurrentCulture)).Append(' ');
             if (methodsymbol.IsStatic)
-                sb.Append("static").Append(' ');
-            sb.Append(methodsymbol.Name).Append('(');
+            {
+                sb = sb.Append("static").Append(' ');
+            }
+
+            sb = sb.Append(methodsymbol.Name).Append('(');
             for (var i = 0; i < methodsymbol.Parameters.Length; i++)
             {
-                sb.Append(methodsymbol.Parameters[i].Type).Append(' ').Append(methodsymbol.Parameters[i].Name);
-                if (i < methodsymbol.Parameters.Length - 1) sb.Append(", ");
+                sb = sb.Append(methodsymbol.Parameters[i].Type).Append(' ').Append(methodsymbol.Parameters[i].Name);
+                if (i < methodsymbol.Parameters.Length - 1)
+                {
+                    sb = sb.Append(", ");
+                }
             }
-            sb.Append(") : ")
-                .Append(methodsymbol.ReturnType).ToString();
+            sb = sb.Append(") : ").Append(methodsymbol.ReturnType);
             return sb.ToString();
         }
         if (symbolInfo.Symbol is ILocalSymbol localsymbol)
         {
             var sb = new StringBuilder().Append(localsymbol.Name).Append(" : ");
             if (localsymbol.IsConst)
-                sb.Append("const").Append(' ');
-            sb.Append(localsymbol.Type);
+            {
+                sb = sb.Append("const").Append(' ');
+            }
+
+            sb = sb.Append(localsymbol.Type);
             return sb.ToString();
         }
         if (symbolInfo.Symbol is IFieldSymbol fieldSymbol)
         {
             var sb = new StringBuilder().Append(fieldSymbol.Name).Append(" : ").Append(fieldSymbol.DeclaredAccessibility.ToString().ToLower(System.Globalization.CultureInfo.CurrentCulture)).Append(' ');
             if (fieldSymbol.IsStatic)
-                sb.Append("static").Append(' ');
+            {
+                sb = sb.Append("static").Append(' ');
+            }
+
             if (fieldSymbol.IsReadOnly)
-                sb.Append("readonly").Append(' ');
+            {
+                sb = sb.Append("readonly").Append(' ');
+            }
+
             if (fieldSymbol.IsConst)
-                sb.Append("const").Append(' ');
-            sb.Append(fieldSymbol.Type).ToString();
+            {
+                sb = sb.Append("const").Append(' ');
+            }
+
+            sb = sb.Append(fieldSymbol.Type);
             return sb.ToString();
         }
 
@@ -398,7 +433,9 @@ private static int InvocationScore(IMethodSymbol symbol, IEnumerable<TypeInfo> t
     {
         var parameters = symbol.Parameters;
         if (parameters.Length < types.Count())
+        {
             return int.MinValue;
+        }
 
         var score = 0;
         var invocationEnum = types.GetEnumerator();
@@ -406,9 +443,13 @@ private static int InvocationScore(IMethodSymbol symbol, IEnumerable<TypeInfo> t
         while (invocationEnum.MoveNext() && definitionEnum.MoveNext())
         {
             if (invocationEnum.Current.ConvertedType == null)
+            {
                 score++;
+            }
             else if (SymbolEqualityComparer.Default.Equals(invocationEnum.Current.ConvertedType, definitionEnum.Current.Type))
+            {
                 score += 2;
+            }
         }
         return score;
     }
@@ -417,7 +458,7 @@ public class InvocationContext
     {
         public static async Task<InvocationContext> GetInvocation(Document document, int position)
         {
-            var sourceText = await document.GetTextAsync();
+            _ = await document.GetTextAsync();
             var tree = await document.GetSyntaxTreeAsync();
             var root = await tree.GetRootAsync();
             var node = root.FindToken(position).Parent;
diff --git a/src/Passingwind.CSharpScript/CSharpScriptContextState.cs b/src/Passingwind.CSharpScript/CSharpScriptContextState.cs
index 5c56b352..ec65db8b 100644
--- a/src/Passingwind.CSharpScript/CSharpScriptContextState.cs
+++ b/src/Passingwind.CSharpScript/CSharpScriptContextState.cs
@@ -4,12 +4,11 @@ namespace Passingwind.CSharpScriptEngine;
 
 public class CSharpScriptContextState
 {
-    public CSharpScriptContext Context { get; }
+    public CSharpScriptContext Context { get; } = null!;
+    public Script Script { get; set; } = null!;
 
     public CSharpScriptContextState(CSharpScriptContext context)
     {
         Context = context;
     }
-
-    public Script Script { get; set; }
 }
diff --git a/src/Passingwind.CSharpScript/CSharpScriptEngineOptions.cs b/src/Passingwind.CSharpScript/CSharpScriptEngineOptions.cs
index 2d6a6d72..2b18d6ba 100644
--- a/src/Passingwind.CSharpScript/CSharpScriptEngineOptions.cs
+++ b/src/Passingwind.CSharpScript/CSharpScriptEngineOptions.cs
@@ -6,11 +6,11 @@ namespace Passingwind.CSharpScriptEngine;
 public class CSharpScriptEngineOptions
 {
     public string NuGetCachePath { get; set; }
-    public List<string> NuGetServer { get; }
+    public List<string> NuGetServers { get; }
 
     public CSharpScriptEngineOptions()
     {
-        NuGetServer = new List<string>();
+        NuGetServers = new List<string>();
 #if DEBUG
         NuGetCachePath = System.IO.Path.Combine(AppContext.BaseDirectory, ".nuget");
 #else
diff --git a/src/Passingwind.CSharpScript/CSharpScriptHost.cs b/src/Passingwind.CSharpScript/CSharpScriptHost.cs
index a80326bc..4ad76893 100644
--- a/src/Passingwind.CSharpScript/CSharpScriptHost.cs
+++ b/src/Passingwind.CSharpScript/CSharpScriptHost.cs
@@ -31,7 +31,10 @@ public class CSharpScriptHost : ICSharpScriptHost, IDisposable
     public static ParseOptions DefaultParseOptions => CSharpParseOptions
         .Default
         .WithPreprocessorSymbols(PreprocessorSymbols)
-        .WithKind(SourceCodeKind.Script);
+        .WithDocumentationMode(DocumentationMode.Parse)
+        .WithLanguageVersion(LanguageVersion.Latest)
+        .WithKind(SourceCodeKind.Script)
+        .CommonWithKind(SourceCodeKind.Script);
 
 #if NET8_0
     public static ImmutableArray<MetadataReference> StandardMetadataReference = ImmutableArray.CreateRange(Basic.Reference.Assemblies.Net80.References.All.Select(GetMetadataReference));
@@ -66,22 +69,15 @@ public class CSharpScriptHost : ICSharpScriptHost, IDisposable
             "System.Collections",
             "System.Collections.Concurrent",
             "System.Collections.Generic",
-            "System.Console",
             "System.Dynamic",
             "System.Globalization",
             "System.IO",
             "System.Linq",
             "System.Reflection",
             "System.Text",
-            "System.Text",
-            "System.Text.Encoding",
-            "System.Text.RegularExpressions",
             "System.Text.RegularExpressions",
             "System.Threading",
-            "System.Threading.Tasks",
-            "System.Threading.Tasks.Parallel",
-            "System.Threading.Thread",
-            "System.ValueTuple",
+            "System.Threading.Tasks"
         }.ToImmutableArray();
 
     private static readonly ConcurrentDictionary<string, CSharpScriptContextState> ScriptStateCache = new ConcurrentDictionary<string, CSharpScriptContextState>();
diff --git a/src/Passingwind.CSharpScript/CSharpScriptProject.cs b/src/Passingwind.CSharpScript/CSharpScriptProject.cs
index 2ff5e3dd..749c6729 100644
--- a/src/Passingwind.CSharpScript/CSharpScriptProject.cs
+++ b/src/Passingwind.CSharpScript/CSharpScriptProject.cs
@@ -1,12 +1,10 @@
 using System.Collections.Generic;
-using System.Collections.Immutable;
 using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Completion;
 using Microsoft.CodeAnalysis.Text;
 
 namespace Passingwind.CSharpScriptEngine;
@@ -16,24 +14,25 @@ public class CSharpScriptProject : ICSharpScriptProject
     private readonly List<Assembly> _references = new List<Assembly>();
     private readonly List<string> _imports = new List<string>();
 
+    private Project _project = null!;
+
     public string Id { get; }
     public string Name { get; }
-
-    public Project Project { get; private set; }
-
+    public ProjectId ProjectId { get; }
     protected AdhocWorkspace Workspace { get; }
 
-    public CSharpScriptProject(AdhocWorkspace workspace, Project project)
+    public CSharpScriptProject(AdhocWorkspace workspace, ProjectId projectId, string projectName)
     {
-        Id = project.Id.Id.ToString();
-        Name = project.Name;
+        Id = projectId.Id.ToString();
+        Name = projectName;
         Workspace = workspace;
-        Project = project;
+        ProjectId = projectId;
+        ReloadProject();
     }
 
-    public void Refresh()
+    public void ReloadProject()
     {
-        Project = Workspace.CurrentSolution.GetProject(Project.Id)!;
+        _project = Workspace.CurrentSolution.GetProject(ProjectId)!;
     }
 
     public IReadOnlyList<string> GetImports()
@@ -46,14 +45,20 @@ public IReadOnlyList<Assembly> GetReferences()
         return _references;
     }
 
-    public void AddReferences(IEnumerable<Assembly> assemblies)
+    public ICSharpScriptProject AddReferences(IEnumerable<Assembly> assemblies)
     {
         _references.AddRange(assemblies);
+
+        _project = _project.AddMetadataReferences(assemblies.Select(x => MetadataReference.CreateFromFile(x.Location)));
+
+        return this;
     }
 
-    public void AddImports(IEnumerable<string> usings)
+    public ICSharpScriptProject AddImports(IEnumerable<string> usings)
     {
         _imports.AddRange(usings);
+
+        return this;
     }
 
     public Document CreateOrUpdateDocument(string fileName, string sourceText)
@@ -62,62 +67,44 @@ public Document CreateOrUpdateDocument(string fileName, string sourceText)
         {
             var name = Path.GetFileNameWithoutExtension(fileName);
 
-            var document = Project.Documents.FirstOrDefault(x => x.Name == name);
+            var document = _project.Documents.FirstOrDefault(x => x.Name == name);
 
             if (document != null)
             {
-                var solution = Workspace.CurrentSolution.WithDocumentText(document.Id, SourceText.From(sourceText, Encoding.UTF8));
-                // Workspace.TryApplyChanges(solution);
-            }
-            else
-            {
-                document = Workspace.AddDocument(Project.Id, name, SourceText.From(sourceText));
-                Workspace.TryApplyChanges(Project.Solution);
+                _ = Workspace.CurrentSolution.RemoveDocument(document.Id);
             }
 
-            Refresh();
+            document = Workspace.AddDocument(_project.Id, name, SourceText.From(sourceText, Encoding.UTF8));
+
+            Workspace.TryApplyChanges(Workspace.CurrentSolution);
+
+            ReloadProject();
 
             return document;
         }
     }
 
-    public async Task<IReadOnlyList<CompletionItem>> GetCompletionsAsync(Document document, int position)
+    public async Task SaveAsync()
     {
-        var completionService = CompletionService.GetService(document);
+        var root = _project.FilePath;
 
-        if (completionService == null)
+        if (string.IsNullOrWhiteSpace(root))
         {
-            return new List<CompletionItem>();
+            return;
         }
 
-        var completionResult = await completionService.GetCompletionsAsync(document, position, CompletionTrigger.Invoke);
-
-        var text = await document.GetTextAsync();
-
-        var textSpanToText = new Dictionary<TextSpan, string>();
-
-        return completionResult.ItemsList.Where(item => MatchesFilterText(completionService, document, item, text, textSpanToText)).ToList();
-    }
-
-    private static bool MatchesFilterText(CompletionService completionService, Document document, CompletionItem item, SourceText text, Dictionary<TextSpan, string> textSpanToText)
-    {
-        var filterText = GetFilterText(item, text, textSpanToText);
-        if (string.IsNullOrEmpty(filterText))
+        if (!Directory.Exists(root))
         {
-            return true;
+            Directory.CreateDirectory(root);
         }
 
-        return completionService.FilterItems(document, ImmutableArray.Create(item), filterText).Length > 0;
-    }
-
-    private static string GetFilterText(CompletionItem item, SourceText text, Dictionary<TextSpan, string> textSpanToText)
-    {
-        var textSpan = item.Span;
-        if (!textSpanToText.TryGetValue(textSpan, out var filterText))
+        foreach (var document in _project.Documents)
         {
-            filterText = text.GetSubText(textSpan).ToString();
-            textSpanToText[textSpan] = filterText;
+            var file = Path.Combine(root, document.FilePath ?? document.Name + ".cs");
+            var text = await document.GetTextAsync();
+            await File.WriteAllTextAsync(file, text?.ToString());
         }
-        return filterText;
+        // TODO
+        // project file ?
     }
 }
diff --git a/src/Passingwind.CSharpScript/CSharpScriptWorkspace.cs b/src/Passingwind.CSharpScript/CSharpScriptWorkspace.cs
index 1d792b0e..886c7392 100644
--- a/src/Passingwind.CSharpScript/CSharpScriptWorkspace.cs
+++ b/src/Passingwind.CSharpScript/CSharpScriptWorkspace.cs
@@ -10,11 +10,13 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Completion;
 using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.Diagnostics;
 using Microsoft.CodeAnalysis.Emit;
 using Microsoft.CodeAnalysis.Host;
 using Microsoft.CodeAnalysis.Host.Mef;
+using Microsoft.CodeAnalysis.Text;
 using Roslyn.Utilities;
 
 namespace Passingwind.CSharpScriptEngine;
@@ -40,11 +42,7 @@ public class CSharpScriptWorkspace : ICSharpScriptWorkspace, IDisposable
 
     //public static IEnumerable<Type> GetDiagnosticCompositionTypes() => typeof(AdhocWorkspace).Assembly.GetExportedTypes().Where(x => x.Namespace.StartsWith("Microsoft.CodeAnalysis.Diagnostics") || x.Namespace.StartsWith("Microsoft.CodeAnalysis.CodeFixes")).ToList();
 
-    public static ParseOptions DefaultParseOptions => CSharpParseOptions
-        .Default
-        .WithPreprocessorSymbols(PreprocessorSymbols)
-        .WithKind(SourceCodeKind.Script)
-        .CommonWithKind(SourceCodeKind.Regular);
+    public static ParseOptions DefaultParseOptions => CSharpScriptHost.DefaultParseOptions;
 
     public static ImmutableArray<string> DefaultSuppressedDiagnostics => ImmutableArray.Create("CS1701", "CS1702", "CS1705", "CS7011", "CS8097");
 
@@ -93,7 +91,7 @@ public ICSharpScriptProject GetOrCreateProject(string projectId)
         {
             var compilationOptions = CreateDefaultCompilationOptions();
             var csProject = CreateProject(_workspace, _, compilationOptions);
-            return new CSharpScriptProject(_workspace, csProject);
+            return new CSharpScriptProject(_workspace, csProject.Id, csProject.Name);
         });
     }
 
@@ -105,47 +103,31 @@ protected Project CreateProject(AdhocWorkspace workspace, string projectName, CS
 
         var projectId = ProjectId.CreateNewId();
 
-        var root = GetProjectFolder(projectId);
-        var file = Path.Combine(root, projectId.Id.ToString());
+        var root = GetProjectFolder(projectName);
+        var outputFilePath = Path.Combine(root, "bin", projectName + ".dll");
 
         var projectInfo = ProjectInfo.Create(
-            projectId,
-            VersionStamp.Create(),
-            projectName,
-            projectName,
-            LanguageNames.CSharp,
-            filePath: $"{file}.dll",
-            outputFilePath: file,
+            id: projectId,
+            version: VersionStamp.Create(),
+            name: projectName,
+            assemblyName: projectName,
+            language: LanguageNames.CSharp,
+            filePath: root,
+            outputFilePath: outputFilePath,
             compilationOptions: compilationOptions,
             parseOptions: DefaultParseOptions,
             metadataReferences: references,
             analyzerReferences: analyzerReferences
         );
 
-        return workspace.AddProject(projectInfo);
+        var project = workspace.AddProject(projectInfo);
 
-        //if (compilationOptions.Usings.Length > 0)
-        //{
-        //    var globalUsingCode = string.Join("\n", compilationOptions.Usings.Select(x => $"global using {x};"));
-        //    CreateDocument(project.Id, "GeneratedUsings", globalUsingCode);
-        //} 
-    }
+        // auto add global using 
+        workspace.AddDocument(projectId, "GlobalUsings", SourceText.From(CSharpScriptWorkspace.GenerateGlobalUsings(compilationOptions.Usings.ToArray())));
 
-    protected CSharpCompilationOptions CreateDefaultCompilationOptions(IEnumerable<string>? AdditionalImports = null)
-    {
-        var hostImports = DefaultImports.Concat(AdditionalImports ?? Array.Empty<string>());
+        workspace.TryApplyChanges(workspace.CurrentSolution);
 
-        return new CSharpCompilationOptions(
-            OutputKind.DynamicallyLinkedLibrary,
-            reportSuppressedDiagnostics: false,
-            usings: hostImports,
-            checkOverflow: true,
-            allowUnsafe: false,
-            generalDiagnosticOption: ReportDiagnostic.Warn,
-            specificDiagnosticOptions: _specificDiagnosticOptions,
-            concurrentBuild: false,
-            metadataReferenceResolver: CSharpScriptMetadataReferenceResolver.Instance,
-            nullableContextOptions: NullableContextOptions.Enable);
+        return project;
     }
 
     protected virtual IEnumerable<AnalyzerReference> GetSolutionAnalyzerReferences()
@@ -157,9 +139,9 @@ protected virtual IEnumerable<AnalyzerReference> GetSolutionAnalyzerReferences()
         yield return new AnalyzerFileReference(typeof(CSharpFeaturesResources).Assembly.Location, loader);
     }
 
-    private static string GetProjectFolder(ProjectId projectId)
+    private static string GetProjectFolder(string project)
     {
-        var root = Path.Combine(Path.GetTempPath(), "roslyns", projectId.Id.ToString());
+        var root = Path.Combine(Path.GetTempPath(), "workflow", "roslyns", project);
         if (!Directory.Exists(root))
         {
             Directory.CreateDirectory(root);
@@ -176,65 +158,173 @@ public void Dispose()
         _compositionHost.Dispose();
     }
 
-    public async Task<CSharpCompilation> CreateCompilationAsync(ICSharpScriptProject scriptProject, CancellationToken cancellationToken = default)
+    protected static string GenerateGlobalUsings(params string[] imports)
+    {
+        return string.Join("\r\n", imports.Select(x => $"global using {x};"));
+    }
+
+    protected CSharpCompilationOptions CreateDefaultCompilationOptions(IEnumerable<string>? additionalImports = null)
+    {
+        var imports = DefaultImports.Concat(additionalImports ?? Array.Empty<string>());
+
+        return new CSharpCompilationOptions(
+            OutputKind.DynamicallyLinkedLibrary,
+            reportSuppressedDiagnostics: false,
+            scriptClassName: "Program",
+            usings: imports,
+            checkOverflow: true,
+            allowUnsafe: false,
+            // generalDiagnosticOption: ReportDiagnostic.Default,
+            specificDiagnosticOptions: _specificDiagnosticOptions,
+            concurrentBuild: false,
+            metadataReferenceResolver: CSharpScriptMetadataReferenceResolver.Instance,
+            nullableContextOptions: NullableContextOptions.Enable);
+    }
+
+    public async Task<CSharpCompilation> CreateCompilationAsync(ICSharpScriptProject scriptProject, bool removeReferenceDirective = false, CancellationToken cancellationToken = default)
     {
         var scriptOptions = CSharpScriptHost.CreateScriptOptions(scriptProject.GetImports(), scriptProject.GetReferences());
         var parseOptions = CSharpScriptHost.CreateParseOptions();
 
         scriptOptions = scriptOptions.AddReferences(CSharpScriptHost.StandardPortableReference);
 
+        var project = _workspace.CurrentSolution.GetProject(scriptProject.ProjectId) ?? throw new InvalidOperationException("Project not found.");
+
         var syntaxTrees = new List<SyntaxTree>();
 
-        foreach (var item in scriptProject.Project.Documents)
+        foreach (var item in project.Documents)
         {
-            var sourceText = (await item.GetTextAsync()).ToString();
+            var sourceText = (await item.GetTextAsync(cancellationToken)).ToString();
 
-            scriptOptions.AddReferences(await _scriptReferenceResolver.ResolveReferencesAsync(sourceText));
+            // resolve references
+            scriptOptions = scriptOptions.AddReferences(await _scriptReferenceResolver.ResolveReferencesAsync(sourceText, cancellationToken));
 
-            var syntaxTree = SyntaxFactory.ParseSyntaxTree(sourceText, options: parseOptions, encoding: Encoding.UTF8, cancellationToken: cancellationToken);
+            var syntaxTree = await item.GetSyntaxTreeAsync(cancellationToken);
 
-            // remove reference directive
-            syntaxTree = syntaxTree.RemoveReferenceDirectives(parseOptions, cancellationToken: cancellationToken);
+            if (removeReferenceDirective)
+            {
+                syntaxTree = syntaxTree!.RemoveReferenceDirectives(parseOptions, cancellationToken: cancellationToken);
+            }
 
-            syntaxTrees.Add(syntaxTree);
+            syntaxTrees.Add(syntaxTree!);
         }
 
         var name = scriptProject.Name;
 
-        var compilationOptions = new CSharpCompilationOptions(
-            outputKind: OutputKind.DynamicallyLinkedLibrary,
-            scriptClassName: "Program",
-            usings: scriptOptions.Imports,
-            checkOverflow: scriptOptions.CheckOverflow,
-            allowUnsafe: scriptOptions.AllowUnsafe,
-            metadataReferenceResolver: scriptOptions.MetadataResolver,
-            nullableContextOptions: NullableContextOptions.Enable);
+        var compilationOptions = CreateDefaultCompilationOptions(scriptOptions.Imports);
 
-        return CSharpCompilation.Create(
-            name,
-            syntaxTrees: syntaxTrees,
-            references: scriptOptions.MetadataReferences,
-            options: compilationOptions);
+        return CSharpCompilation.Create(name, syntaxTrees: syntaxTrees, references: scriptOptions.MetadataReferences, options: compilationOptions);
     }
 
     public async Task<EmitResult> CompileAsync(ICSharpScriptProject scriptProject, CancellationToken cancellationToken = default)
     {
         var name = scriptProject.Name;
 
-        var compilation = await CreateCompilationAsync(scriptProject, cancellationToken);
+        var project = _workspace.CurrentSolution.GetProject(scriptProject.ProjectId) ?? throw new InvalidOperationException("Project not found.");
+
+        var compilation = await CreateCompilationAsync(scriptProject, true, cancellationToken);
 
-        var rootFolder = Path.Combine(Path.GetTempPath(), "workflow", "csharp", name);
+        var rootFolder = GetProjectFolder(name);
 
-        if (!Directory.Exists(rootFolder))
+        string outputFilePath = project.OutputFilePath ?? Path.Combine(rootFolder, "bin", $"{name}.dll");
+
+        if (!Directory.Exists(Path.GetDirectoryName(outputFilePath)))
         {
-            Directory.CreateDirectory(rootFolder);
+            Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath)!);
         }
 
-        var file = Path.Combine(rootFolder, name);
-
-        await using var peStream = File.OpenWrite($"{file}.dll");
-        await using var pdbStream = File.OpenWrite($"{file}.pdb");
+        await using var peStream = File.OpenWrite(outputFilePath);
+        await using var pdbStream = File.OpenWrite(Path.ChangeExtension(outputFilePath, ".pdb"));
 
         return compilation.Emit(peStream, pdbStream, options: new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb), cancellationToken: cancellationToken);
     }
+
+    public async Task RestoreReferenceAsync(ICSharpScriptProject scriptProject, CancellationToken cancellationToken = default)
+    {
+        var projectId = scriptProject.ProjectId;
+        var project = _workspace.CurrentSolution.GetProject(scriptProject.ProjectId) ?? throw new InvalidOperationException("Project not found.");
+
+        foreach (var document in project.Documents)
+        {
+            var sourceText = (await document.GetTextAsync(cancellationToken)).ToString();
+
+            var references = await _scriptReferenceResolver.ResolveReferencesAsync(sourceText, cancellationToken);
+
+            foreach (var item in references)
+            {
+                if (!project.MetadataReferences.Any(x => IsSameMetadataReference(x, item)))
+                {
+                    var solution = _workspace.CurrentSolution.AddMetadataReferences(projectId, references);
+
+                    _workspace.TryApplyChanges(solution);
+                }
+            }
+        }
+
+        scriptProject.ReloadProject();
+
+        bool IsSameMetadataReference(MetadataReference a, MetadataReference b)
+        {
+            if (a.GetType() != b.GetType())
+            {
+                return false;
+            }
+
+            return a is PortableExecutableReference executableReferenceA && b is PortableExecutableReference executableReferenceB && executableReferenceA.FilePath == executableReferenceB.FilePath;
+        }
+    }
+
+    public async Task<IReadOnlyList<CompletionItem>> GetCompletionsAsync(ICSharpScriptProject scriptProject, DocumentId documentId, int position, bool filter = true, CancellationToken cancellationToken = default)
+    {
+        var projectId = scriptProject.ProjectId;
+        var project = _workspace.CurrentSolution.GetProject(scriptProject.ProjectId) ?? throw new InvalidOperationException("Project not found.");
+
+        var document = await project.GetDocumentAsync(documentId, cancellationToken: cancellationToken) ?? throw new InvalidOperationException("The document not found.");
+        var completionService = CompletionService.GetService(document);
+
+        if (completionService == null)
+        {
+            return new List<CompletionItem>();
+        }
+
+        var completionResult = await completionService.GetCompletionsAsync(document, position, cancellationToken: cancellationToken);
+
+        var text = await document.GetTextAsync(cancellationToken);
+
+        var textSpanToText = new Dictionary<TextSpan, string>();
+
+        if (!filter)
+        {
+            return completionResult.ItemsList;
+        }
+
+        return completionResult.ItemsList.Where(item => MatchesFilterText(completionService, document, item, text, textSpanToText)).ToList();
+    }
+
+    private static bool MatchesFilterText(CompletionService completionService, Document document, CompletionItem item, SourceText text, Dictionary<TextSpan, string> textSpanToText)
+    {
+        var filterText = GetFilterText(item, text, textSpanToText);
+        if (string.IsNullOrEmpty(filterText))
+        {
+            return true;
+        }
+
+        return completionService.FilterItems(document, ImmutableArray.Create(item), filterText).Length > 0;
+    }
+
+    private static string GetFilterText(CompletionItem item, SourceText text, Dictionary<TextSpan, string> textSpanToText)
+    {
+        var textSpan = item.Span;
+        if (!textSpanToText.TryGetValue(textSpan, out var filterText))
+        {
+            filterText = text.GetSubText(textSpan).ToString();
+            textSpanToText[textSpan] = filterText;
+        }
+        return filterText;
+    }
+
+    public async Task<Document?> GetDocumentAsync(DocumentId documentId)
+    {
+        return await _workspace.CurrentSolution.GetDocumentAsync(documentId);
+    }
 }
diff --git a/src/Passingwind.CSharpScript/DefaultNuGetLocalPackageAssemblyResolver.cs b/src/Passingwind.CSharpScript/DefaultNuGetLocalPackageAssemblyResolver.cs
new file mode 100644
index 00000000..50e4bbab
--- /dev/null
+++ b/src/Passingwind.CSharpScript/DefaultNuGetLocalPackageAssemblyResolver.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
+using NuGet.Frameworks;
+using NuGet.Packaging;
+using NuGet.Packaging.Core;
+using NuGet.Repositories;
+
+namespace Passingwind.CSharpScriptEngine;
+
+public class DefaultNuGetLocalPackageAssemblyResolver : INuGetLocalPackageAssemblyResolver
+{
+    private readonly NuGetv3LocalRepository _localRepository;
+
+    private readonly CSharpScriptEngineOptions _engineOptions;
+
+    public DefaultNuGetLocalPackageAssemblyResolver(IOptions<CSharpScriptEngineOptions> engineOptions)
+    {
+        _engineOptions = engineOptions.Value;
+
+        _localRepository = new NuGetv3LocalRepository(_engineOptions.NuGetCachePath);
+    }
+
+    public async Task<IEnumerable<string>> GetReferencesAsync(PackageIdentity package, NuGetFramework framework, CancellationToken cancellationToken = default)
+    {
+        if (!_localRepository.Exists(package.Id, package.Version))
+        {
+            throw new InvalidOperationException($"The package '{package}' not found.");
+        }
+
+        var packageInfo = _localRepository.FindPackage(package.Id, package.Version);
+
+        var file = packageInfo.ZipPath!;
+
+        var root = Path.GetDirectoryName(file);
+
+        using var archiveReader = new PackageArchiveReader(file);
+
+        var supportedFrameworks = await archiveReader.GetSupportedFrameworksAsync(cancellationToken);
+        var referenceItemGroups = await archiveReader.GetReferenceItemsAsync(cancellationToken);
+        // var dependencyGroups = await archiveReader.GetPackageDependenciesAsync(cancellationToken);
+
+        var packageTargetFramework = NuGetFrameworkUtility.GetNearest(supportedFrameworks, framework, x => x);
+
+        var targetReferenceItemGroup = referenceItemGroups.FirstOrDefault(x => x.TargetFramework == packageTargetFramework);
+
+        if (targetReferenceItemGroup == null)
+        {
+            return new List<string>();
+        }
+
+        var referenceFiles = targetReferenceItemGroup.Items?.Select(x => Path.Combine(root!, x)).ToList();
+
+        return referenceFiles ?? new List<string>();
+    }
+}
diff --git a/src/Passingwind.CSharpScript/DefaultNuGetPackageService.cs b/src/Passingwind.CSharpScript/DefaultNuGetPackageService.cs
new file mode 100644
index 00000000..585bdcf1
--- /dev/null
+++ b/src/Passingwind.CSharpScript/DefaultNuGetPackageService.cs
@@ -0,0 +1,257 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using NuGet.Configuration;
+using NuGet.Frameworks;
+using NuGet.Packaging;
+using NuGet.Packaging.Core;
+using NuGet.Protocol;
+using NuGet.Protocol.Core.Types;
+using NuGet.Repositories;
+using NuGet.Versioning;
+
+namespace Passingwind.CSharpScriptEngine;
+
+public class DefaultNuGetPackageService : INuGetPackageService
+{
+    protected IReadOnlyList<SourceRepository> Repositories { get; }
+
+    private readonly NuGetv3LocalRepository _localRepository;
+    private readonly SourceCacheContext _sourceCacheContext;
+    private readonly string _nuGetCacheFolder;
+
+    private readonly CSharpScriptEngineOptions _engineOptions;
+    private readonly ILogger<DefaultNuGetPackageService> _logger;
+    private readonly NuGet.Common.ILogger _nuGetLogger = NuGet.Common.NullLogger.Instance;
+    private readonly INuGetLocalPackageAssemblyResolver _nuGetPackageAssemblyResolver;
+
+    public DefaultNuGetPackageService(IOptions<CSharpScriptEngineOptions> engineOptions, ILogger<DefaultNuGetPackageService> logger, NuGet.Common.ILogger nuGetLogger, INuGetLocalPackageAssemblyResolver nuGetPackageAssemblyResolver)
+    {
+        _engineOptions = engineOptions.Value;
+        _logger = logger;
+        _nuGetLogger = nuGetLogger;
+        _nuGetPackageAssemblyResolver = nuGetPackageAssemblyResolver;
+
+        Repositories = GetSourceRepositories();
+        _sourceCacheContext = new SourceCacheContext() { IgnoreFailedSources = true, MaxAge = System.DateTimeOffset.Now.AddHours(1), };
+        _localRepository = new NuGetv3LocalRepository(_engineOptions.NuGetCachePath);
+        _nuGetCacheFolder = _engineOptions.NuGetCachePath;
+    }
+
+    public async Task<IReadOnlyList<string>> GetReferencesAsync(string packageId, string version, string targetFramework, bool resolveDependency = true, CancellationToken cancellationToken = default)
+    {
+        var package = new PackageIdentity(packageId, NuGetVersion.Parse(version));
+
+        var framework = NuGetFramework.Parse(targetFramework);
+
+        return await GetReferencesAsync(package, framework, resolveDependency, cancellationToken);
+    }
+
+    public async Task<IReadOnlyList<string>> GetReferencesAsync(PackageIdentity package, NuGetFramework targetFramework, bool resolveDependency = true, CancellationToken cancellationToken = default)
+    {
+        await DownloadAsync(package, cancellationToken);
+
+        var references = new List<string>();
+        references.AddRange(await _nuGetPackageAssemblyResolver.GetReferencesAsync(package, targetFramework, cancellationToken));
+
+        // dependency
+        if (resolveDependency)
+        {
+            var dependencies = await GetDependenciesAsync(package, targetFramework, cancellationToken);
+
+            foreach (var item in dependencies)
+            {
+                references.AddRange(await GetReferencesAsync(item, targetFramework, resolveDependency, cancellationToken));
+            }
+        }
+
+        return references;
+    }
+
+    public async Task<IReadOnlyList<PackageIdentity>> GetDependenciesAsync(string packageId, string version, string targetFramework, CancellationToken cancellationToken = default)
+    {
+        var package = new PackageIdentity(packageId, NuGetVersion.Parse(version));
+
+        return await GetDependenciesAsync(package, NuGetFramework.Parse(targetFramework), cancellationToken);
+    }
+
+    protected async Task<IReadOnlyList<PackageIdentity>> GetDependenciesAsync(PackageIdentity package, NuGetFramework targetFramework, CancellationToken cancellationToken = default)
+    {
+        await DownloadAsync(package, cancellationToken);
+
+        var file = GetPackageFile(package);
+
+        if (!File.Exists(file))
+        {
+            throw new FileNotFoundException(file);
+        }
+
+        var reader = new PackageArchiveReader(file);
+
+        return await GetDependenciesAsync(reader, targetFramework, cancellationToken);
+    }
+
+    protected async Task<List<PackageIdentity>> GetDependenciesAsync(PackageArchiveReader archiveReader, NuGetFramework targetFramework, CancellationToken cancellationToken = default)
+    {
+        var dependencyGroups = await archiveReader.GetPackageDependenciesAsync(cancellationToken);
+
+        var packageDependencyGroup = NuGetFrameworkUtility.GetNearest(dependencyGroups, targetFramework);
+
+        var result = new List<PackageIdentity>();
+
+        if (packageDependencyGroup?.Packages?.Any() == true)
+        {
+            foreach (var packageDependency in packageDependencyGroup.Packages)
+            {
+                // TODO
+                var package = new PackageIdentity(packageDependency.Id, packageDependency.VersionRange.MinVersion);
+
+                result.Add(package);
+            }
+        }
+
+        return result;
+    }
+
+    public async Task DownloadAsync(string packageId, string version, CancellationToken cancellationToken = default)
+    {
+        var package = new PackageIdentity(packageId, NuGetVersion.Parse(version));
+
+        await DownloadAsync(package, cancellationToken);
+    }
+
+    public async Task DownloadAsync(PackageIdentity package, CancellationToken cancellationToken = default)
+    {
+        if (IsPackageSaved(package))
+        {
+            // _logger.LogDebug("Package '{Package}' found in local ", package);
+            return;
+        }
+
+        await DownloadAndSaveAsync(package, cancellationToken);
+    }
+
+    protected async Task DownloadAndSaveAsync(PackageIdentity package, CancellationToken cancellationToken = default)
+    {
+        _logger.LogDebug("Downloading package '{Package}' ", package);
+
+        var packageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Compress, null, _nuGetLogger);
+
+        foreach (var repository in Repositories)
+        {
+            var resource = await repository.GetResourceAsync<FindPackageByIdResource>();
+            if (resource == null)
+            {
+                continue;
+            }
+
+            var _packageId = package;
+            var _resource = resource;
+
+            await SavePackageAsync(_resource, _packageId, packageExtractionContext, cancellationToken);
+        }
+    }
+
+    protected async Task SavePackageAsync(FindPackageByIdResource resource, PackageIdentity package, PackageExtractionContext packageExtractionContext, CancellationToken cancellationToken = default)
+    {
+        if (IsPackageSaved(package))
+        {
+            return;
+        }
+
+        if (await resource.DoesPackageExistAsync(package.Id, package.Version, _sourceCacheContext, _nuGetLogger, cancellationToken))
+        {
+            _logger.LogDebug("Extracting package '{Package}' ", package);
+
+            var downloader = await resource.GetPackageDownloaderAsync(package, _sourceCacheContext, _nuGetLogger, cancellationToken);
+
+            await PackageExtractor.InstallFromSourceAsync(package, downloader, new VersionFolderPathResolver(_nuGetCacheFolder), packageExtractionContext, cancellationToken);
+
+            _logger.LogDebug("Package '{Package}' installed to '{NuGetCacheFolder}' ", package, _nuGetCacheFolder);
+        }
+        else
+        {
+            _logger.LogError("Package '{Package}' not found int repository", package);
+        }
+    }
+
+    public async Task<IReadOnlyList<string>> GetVersionsAsync(string packageId, CancellationToken cancellationToken = default)
+    {
+        var tasks = Repositories.Select(x => GetPackageVersionsAsync(x, packageId, cancellationToken));
+
+        var result = await Task.WhenAll(tasks);
+
+        return (IReadOnlyList<string>)result.SelectMany(x => x).Distinct().OrderByDescending(x => x);
+    }
+
+    private async Task<IReadOnlyList<string>> GetPackageVersionsAsync(SourceRepository repository, string packageId, CancellationToken cancellationToken = default)
+    {
+        _logger.LogError("Fech package '{PackageId}' versions in repository '{repository}'", packageId, repository);
+
+        var resource = await repository.GetResourceAsync<FindPackageByIdResource>();
+
+        var allVersion = await resource.GetAllVersionsAsync(packageId, _sourceCacheContext, _nuGetLogger, cancellationToken);
+
+        return (IReadOnlyList<string>)allVersion.Select(x => x.Version.ToString());
+    }
+
+    public async Task<IReadOnlyList<string>> SearchAsync(string filter, int resultCount = 10, CancellationToken cancellationToken = default)
+    {
+        var tasks = Repositories.Select(x => SearchAsync(x, filter, resultCount, cancellationToken));
+
+        var result = await Task.WhenAll(tasks);
+
+        return (IReadOnlyList<string>)result.SelectMany(x => x).Distinct().OrderBy(x => x);
+    }
+
+    private async Task<IReadOnlyList<string>> SearchAsync(SourceRepository repository, string filter, int resultCount = 10, CancellationToken cancellationToken = default)
+    {
+        _logger.LogError("Search '{Filter}' in repository '{repository}'", filter, repository);
+
+        var resource = await repository.GetResourceAsync<PackageSearchResource>();
+
+        var result = await resource.SearchAsync(filter, new SearchFilter(true, null), 0, resultCount, _nuGetLogger, cancellationToken);
+
+        return result.Select(x => x.Identity.Id).ToList();
+    }
+
+    protected bool IsPackageSaved(PackageIdentity package)
+    {
+        return _localRepository.Exists(package.Id, package.Version);
+    }
+
+    protected string? GetPackageFile(PackageIdentity packageId)
+    {
+        var package = _localRepository.FindPackage(packageId.Id, packageId.Version);
+
+        return package?.ZipPath;
+    }
+
+    protected IReadOnlyList<SourceRepository> GetSourceRepositories()
+    {
+        var settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory());
+
+        var packageSourceProvider = new PackageSourceProvider(settings);
+
+        var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, Repository.Provider.GetCoreV3());
+
+        var originSources = sourceRepositoryProvider.GetRepositories();
+
+        var result = new List<SourceRepository>();
+        result.AddRange(originSources);
+
+        if (_engineOptions.NuGetServers.Any())
+        {
+            foreach (var item in _engineOptions.NuGetServers)
+            {
+                result.Add(Repository.Factory.GetCoreV3(item));
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/src/Passingwind.CSharpScript/ICSharpScriptProject.cs b/src/Passingwind.CSharpScript/ICSharpScriptProject.cs
index 945ed4db..694633c4 100644
--- a/src/Passingwind.CSharpScript/ICSharpScriptProject.cs
+++ b/src/Passingwind.CSharpScript/ICSharpScriptProject.cs
@@ -1,5 +1,6 @@
 using System.Collections.Generic;
 using System.Reflection;
+using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.Completion;
@@ -11,17 +12,17 @@ public interface ICSharpScriptProject
     string Id { get; }
     string Name { get; }
 
-    Project Project { get; }
+    ProjectId ProjectId { get; }
 
-    void Refresh();
+    void ReloadProject();
 
     Document CreateOrUpdateDocument(string fileName, string sourceText);
 
-    Task<IReadOnlyList<CompletionItem>> GetCompletionsAsync(Document document, int position);
-
-    void AddReferences(IEnumerable<Assembly> assemblies);
-    void AddImports(IEnumerable<string> usings);
+    ICSharpScriptProject AddReferences(IEnumerable<Assembly> assemblies);
+    ICSharpScriptProject AddImports(IEnumerable<string> usings);
 
     IReadOnlyList<string> GetImports();
     IReadOnlyList<Assembly> GetReferences();
+
+    Task SaveAsync();
 }
diff --git a/src/Passingwind.CSharpScript/ICSharpScriptWorkspace.cs b/src/Passingwind.CSharpScript/ICSharpScriptWorkspace.cs
index 4221d97a..44dd4e28 100644
--- a/src/Passingwind.CSharpScript/ICSharpScriptWorkspace.cs
+++ b/src/Passingwind.CSharpScript/ICSharpScriptWorkspace.cs
@@ -1,5 +1,8 @@
-using System.Threading;
+using System.Collections.Generic;
+using System.Threading;
 using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Completion;
 using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.Emit;
 
@@ -11,7 +14,13 @@ public interface ICSharpScriptWorkspace
 
     ICSharpScriptProject GetOrCreateProject(string projectId);
 
-    Task<CSharpCompilation> CreateCompilationAsync(ICSharpScriptProject scriptProject, CancellationToken cancellationToken = default);
+    Task<CSharpCompilation> CreateCompilationAsync(ICSharpScriptProject scriptProject, bool removeReferenceDirective = false, CancellationToken cancellationToken = default);
 
     Task<EmitResult> CompileAsync(ICSharpScriptProject scriptProject, CancellationToken cancellationToken = default);
+
+    Task<IReadOnlyList<CompletionItem>> GetCompletionsAsync(ICSharpScriptProject scriptProject, DocumentId documentId, int position, bool filter = true, CancellationToken cancellationToken = default);
+
+    Task RestoreReferenceAsync(ICSharpScriptProject scriptProject, CancellationToken cancellationToken = default);
+
+    Task<Document?> GetDocumentAsync(DocumentId documentId);
 }
diff --git a/src/Passingwind.CSharpScript/INuGetLocalPackageAssemblyResolver.cs b/src/Passingwind.CSharpScript/INuGetLocalPackageAssemblyResolver.cs
new file mode 100644
index 00000000..0f889d51
--- /dev/null
+++ b/src/Passingwind.CSharpScript/INuGetLocalPackageAssemblyResolver.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using NuGet.Frameworks;
+using NuGet.Packaging.Core;
+
+namespace Passingwind.CSharpScriptEngine;
+
+public interface INuGetLocalPackageAssemblyResolver
+{
+    Task<IEnumerable<string>> GetReferencesAsync(PackageIdentity package, NuGetFramework framework, CancellationToken cancellationToken = default);
+}
diff --git a/src/Passingwind.CSharpScript/INuGetPackageService.cs b/src/Passingwind.CSharpScript/INuGetPackageService.cs
index 2191934f..063d894a 100644
--- a/src/Passingwind.CSharpScript/INuGetPackageService.cs
+++ b/src/Passingwind.CSharpScript/INuGetPackageService.cs
@@ -1,13 +1,34 @@
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
+using NuGet.Packaging.Core;
 
 namespace Passingwind.CSharpScriptEngine;
 
 public interface INuGetPackageService
 {
-    Task<IEnumerable<string>> SearchAsync(string name, int resultCount = 10, CancellationToken cancellationToken = default);
-    Task DownloadAsync(string packageId, string version, string tagetFrameworkName, bool dependency = false, CancellationToken cancellationToken = default);
-    Task<IEnumerable<string>> GetPackageVersionsAsync(string packageId, CancellationToken cancellationToken = default);
-    Task<IEnumerable<string>> GetReferencesAsync(string packageId, string version, string tagetFrameworkName, bool resolveDependency = false, bool downloadPackage = false, CancellationToken cancellationToken = default);
+    /// <summary>
+    ///  Search packages from repositores
+    /// </summary>
+    Task<IReadOnlyList<string>> SearchAsync(string filter, int resultCount = 10, CancellationToken cancellationToken = default);
+
+    /// <summary>
+    ///  Get package all version from repositores
+    /// </summary>
+    Task<IReadOnlyList<string>> GetVersionsAsync(string packageId, CancellationToken cancellationToken = default);
+
+    /// <summary>
+    ///  Download package into local from repositores
+    /// </summary>
+    Task DownloadAsync(string packageId, string version, CancellationToken cancellationToken = default);
+
+    /// <summary>
+    ///  Get package dependencies to the specified framework
+    /// </summary>
+    Task<IReadOnlyList<PackageIdentity>> GetDependenciesAsync(string packageId, string version, string targetFramework, CancellationToken cancellationToken = default);
+
+    /// <summary>
+    ///  Get package references to the specified framework
+    /// </summary>
+    Task<IReadOnlyList<string>> GetReferencesAsync(string packageId, string version, string targetFramework, bool resolveDependency = true, CancellationToken cancellationToken = default);
 }
diff --git a/src/Passingwind.CSharpScript/NuGetLogger.cs b/src/Passingwind.CSharpScript/NuGetLogger.cs
index ae763f51..b7214368 100644
--- a/src/Passingwind.CSharpScript/NuGetLogger.cs
+++ b/src/Passingwind.CSharpScript/NuGetLogger.cs
@@ -6,11 +6,11 @@ namespace Passingwind.CSharpScriptEngine;
 
 public class NuGetLogger : LoggerBase
 {
-    private readonly ILogger<NuGetLogger> _logger;
+    private readonly Microsoft.Extensions.Logging.ILogger _logger;
 
-    public NuGetLogger(ILogger<NuGetLogger> logger)
+    public NuGetLogger(ILoggerFactory loggerFactory)
     {
-        _logger = logger;
+        _logger = loggerFactory.CreateLogger("NuGet");
     }
 
     public override void Log(ILogMessage message)
diff --git a/src/Passingwind.CSharpScript/NuGetPackageService.cs b/src/Passingwind.CSharpScript/NuGetPackageService.cs
deleted file mode 100644
index 3e111ac8..00000000
--- a/src/Passingwind.CSharpScript/NuGetPackageService.cs
+++ /dev/null
@@ -1,382 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using NuGet.Configuration;
-using NuGet.Frameworks;
-using NuGet.Packaging;
-using NuGet.Packaging.Core;
-using NuGet.Protocol;
-using NuGet.Protocol.Core.Types;
-using NuGet.Repositories;
-using NuGet.Versioning;
-
-namespace Passingwind.CSharpScriptEngine;
-
-public class NuGetPackageService : INuGetPackageService
-{
-    private readonly NuGetv3LocalRepository _localRepository;
-    private readonly NuGet.Common.ILogger _nuGetLogger = NuGet.Common.NullLogger.Instance;
-    private readonly SourceCacheContext _sourceCacheContext;
-    private readonly string _nuGetCacheFolder;
-
-    private readonly ILogger<NuGetPackageService> _logger;
-    private readonly CSharpScriptEngineOptions _engineOptions;
-
-    protected IEnumerable<SourceRepository> Repositories { get; }
-
-    public NuGetPackageService(NuGetLogger nuGetPackageLogger, ILogger<NuGetPackageService> logger, IOptions<CSharpScriptEngineOptions> engineOptions)
-    {
-        _logger = logger;
-        _engineOptions = engineOptions.Value;
-        _nuGetLogger = nuGetPackageLogger;
-
-        Repositories = GetSourceRepositories();
-        _sourceCacheContext = new SourceCacheContext() { IgnoreFailedSources = true, MaxAge = System.DateTimeOffset.Now.AddHours(1), };
-        _localRepository = new NuGetv3LocalRepository(_engineOptions.NuGetCachePath);
-        _nuGetCacheFolder = _engineOptions.NuGetCachePath;
-    }
-
-    public async Task<IEnumerable<string>> GetReferencesAsync(string packageId, string version, string tagetFrameworkName, bool resolveDependency = false, bool downloadPackage = false, CancellationToken cancellationToken = default)
-    {
-        var packageIdentity = new PackageIdentity(packageId, NuGetVersion.Parse(version));
-        // project target framework
-        var targetFramework = NuGetFramework.Parse(tagetFrameworkName);
-
-        _logger.LogDebug("Starting resolve package '{packageId}' references ", packageIdentity);
-
-        var reposities = Repositories;
-
-        await using MemoryStream nupkgStream = await GetNupkgStreamAsync(reposities, packageIdentity, cancellationToken);
-
-        if (nupkgStream.Length == 0)
-        {
-            throw new Exception($"The nuget package {packageIdentity} not found.");
-        }
-
-        var nuGetAllReferences = new List<NuGetReference>();
-
-        await GetReferencesAsync(nuGetAllReferences, reposities, nupkgStream, packageIdentity, targetFramework, resolveDependency, downloadPackage, cancellationToken);
-
-        // TODO 
-        var result = new List<NuGetReference>();
-        foreach (var item in nuGetAllReferences)
-        {
-            if (!result.Any(x => x.Identity.Id == item.Identity.Id && x.Identity.Version >= item.Identity.Version))
-            {
-                result.Add(item);
-            }
-        }
-
-        _logger.LogDebug("Resolved package '{packageId}' references, count: {count} ", packageIdentity, result.Count);
-
-        return result.SelectMany(x => x.References);
-    }
-
-    public async Task<IEnumerable<string>> SearchAsync(string name, int resultCount = 10, CancellationToken cancellationToken = default)
-    {
-        var tasks = Repositories.Select(x => SearchAsync(x, name, resultCount, cancellationToken));
-
-        var result = await Task.WhenAll(tasks);
-
-        return result.SelectMany(x => x).Distinct().OrderBy(x => x);
-    }
-
-    private async Task<IEnumerable<string>> SearchAsync(SourceRepository repository, string name, int resultCount = 10, CancellationToken cancellationToken = default)
-    {
-        var resource = await repository.GetResourceAsync<PackageSearchResource>();
-
-        var result = await resource.SearchAsync(name, new SearchFilter(true, null), 0, resultCount, _nuGetLogger, cancellationToken);
-
-        return result.Select(x => x.Identity.Id).ToList();
-    }
-
-    public async Task<IEnumerable<string>> GetPackageVersionsAsync(string packageId, CancellationToken cancellationToken = default)
-    {
-        var tasks = Repositories.Select(x => GetPackageVersionsAsync(x, packageId, cancellationToken));
-
-        var result = await Task.WhenAll(tasks);
-
-        return result.SelectMany(x => x).Distinct().OrderByDescending(x => x);
-    }
-
-    private async Task<IEnumerable<string>> GetPackageVersionsAsync(SourceRepository repository, string packageId, CancellationToken cancellationToken = default)
-    {
-        var resource = await repository.GetResourceAsync<FindPackageByIdResource>();
-
-        var allVersion = await resource.GetAllVersionsAsync(packageId, _sourceCacheContext, _nuGetLogger, cancellationToken);
-
-        return allVersion.Select(x => x.Version.ToString());
-    }
-
-    public async Task DownloadAsync(string packageId, string version, string tagetFrameworkName, bool dependency = false, CancellationToken cancellationToken = default)
-    {
-        var packageIdentity = new PackageIdentity(packageId, NuGetVersion.Parse(version));
-        var targetFramework = NuGetFramework.Parse(tagetFrameworkName);
-
-        _logger.LogDebug("Starting download and extracte package '{packageId}'", packageIdentity);
-
-        var reposities = Repositories;
-
-        // local cache 
-        var nupkgFile = GetNupkgFileFromCache(packageIdentity);
-
-        if (!string.IsNullOrWhiteSpace(nupkgFile))
-        {
-            _logger.LogDebug("Find package '{packageId}' nupkg from file: {nupkgFile} ", packageIdentity, nupkgFile);
-        }
-        // not found.
-        else
-        {
-            _logger.LogDebug("Package '{packageId}' in local cache folder not found, try find from repositories.", packageIdentity);
-
-            var packageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.None, null, _nuGetLogger);
-
-            var tasks = new List<Task>();
-
-            // download from repositiy
-            foreach (var repository in reposities)
-            {
-                var resource = await repository.GetResourceAsync<FindPackageByIdResource>();
-                if (resource == null)
-                    continue;
-
-                tasks.Add(Task.Factory.StartNew(async () =>
-                {
-                    var _packageId = packageIdentity;
-                    var _resource = resource;
-
-                    // download & extract
-                    await DownloadAndExtracteAsync(_resource, _packageId, packageExtractionContext, cancellationToken);
-                }));
-            }
-
-            Task.WaitAll(tasks.ToArray(), cancellationToken);
-        }
-
-        // dependency
-        if (dependency)
-        {
-            var dependencyPackages = new List<PackageIdentity>();
-
-            // resolve 
-            await ResoveDependencyPackagesAsync(dependencyPackages, reposities, packageIdentity, targetFramework, cancellationToken);
-
-            var tasks = new List<Task>();
-            foreach (var item in dependencyPackages.Distinct())
-            {
-                tasks.Add(Task.Factory.StartNew(async () =>
-                {
-                    var id = item.Id;
-                    var version = item.Version;
-                    var package2 = new PackageIdentity(id, version);
-
-                    // do not resolve dependencies
-                    await DownloadAsync(id, version.ToNormalizedString(), tagetFrameworkName, false, cancellationToken);
-                }));
-            }
-
-            Task.WaitAll(tasks.ToArray(), cancellationToken);
-        }
-
-        _logger.LogDebug("Download and extracte package '{packageId}' done", packageIdentity);
-    }
-
-    private async Task DownloadAndExtracteAsync(FindPackageByIdResource resource, PackageIdentity packageId, PackageExtractionContext packageExtractionContext, CancellationToken cancellationToken = default)
-    {
-        if (await resource.DoesPackageExistAsync(packageId.Id, packageId.Version, _sourceCacheContext, _nuGetLogger, cancellationToken))
-        {
-            var downloader = await resource.GetPackageDownloaderAsync(packageId, _sourceCacheContext, _nuGetLogger, cancellationToken);
-
-            await PackageExtractor.InstallFromSourceAsync(packageId, downloader, new VersionFolderPathResolver(_nuGetCacheFolder), packageExtractionContext, cancellationToken);
-
-            _logger.LogDebug("Package '{packageId}' installed to '{NuGetCacheFolder}' ", packageId, _nuGetCacheFolder);
-        }
-        else
-        {
-            _logger.LogError("Package '{packageId}' not found", packageId);
-        }
-    }
-
-    private async Task ResoveDependencyPackagesAsync(List<PackageIdentity> packages, IEnumerable<SourceRepository> repositories, PackageIdentity packageId, NuGetFramework targetFramework, CancellationToken cancellationToken = default)
-    {
-        foreach (var repository in repositories)
-        {
-            var resource = repository.GetResource<DependencyInfoResource>();
-
-            var dependencies = await ResoveDependenciesAsync(packages, packageId, targetFramework, resource, cancellationToken);
-
-            if (dependencies?.Any() == true)
-            {
-                foreach (var item in dependencies)
-                {
-                    if (packages.Any(x => x.Id == item.Id && x.Version == item.VersionRange.MinVersion))
-                        continue;
-
-                    var dp = new PackageIdentity(item.Id, item.VersionRange.MinVersion);
-                    packages.Add(dp);
-
-                    await ResoveDependencyPackagesAsync(packages, repositories, dp, targetFramework, cancellationToken);
-                }
-            }
-        }
-    }
-
-    private async Task<IEnumerable<PackageDependency>?> ResoveDependenciesAsync(List<PackageIdentity> packages, PackageIdentity packageId, NuGetFramework targetFramework, DependencyInfoResource resource, CancellationToken cancellationToken = default)
-    {
-        var packageDependencyInfo = await resource.ResolvePackage(packageId, targetFramework, _sourceCacheContext, _nuGetLogger, cancellationToken);
-
-        if (packageDependencyInfo != null)
-        {
-            packages.Add(new PackageIdentity(packageDependencyInfo.Id, packageDependencyInfo.Version));
-
-            return packageDependencyInfo.Dependencies;
-        }
-
-        return null;
-    }
-
-    private async Task GetReferencesAsync(List<NuGetReference> result, IEnumerable<SourceRepository> reposities, Stream nupkgStream, PackageIdentity packageId, NuGetFramework targetFramework, bool resolveDependency = false, bool downloadPackage = false, CancellationToken cancellationToken = default)
-    {
-        _logger.LogDebug("Starting resolve package '{packageId}' references from nupkg ", packageId);
-
-        using PackageArchiveReader archiveReader = new PackageArchiveReader(nupkgStream);
-
-        var referenceItemGroups = await archiveReader.GetReferenceItemsAsync(cancellationToken);
-        var supportedFrameworks = await archiveReader.GetSupportedFrameworksAsync(cancellationToken);
-        var dependencyGroups = await archiveReader.GetPackageDependenciesAsync(cancellationToken);
-
-        // find package target framework 
-        var packageTargetFramework = NuGetFrameworkUtility.GetNearest(supportedFrameworks, targetFramework, x => x);
-
-        var targetReferenceItemGroup = referenceItemGroups.FirstOrDefault(x => x.TargetFramework == packageTargetFramework);
-
-        if (targetReferenceItemGroup == null)
-            return;
-
-        var referenceFiles = targetReferenceItemGroup.Items?.Select(x => Path.Combine(_nuGetCacheFolder, packageId.Id.ToLowerInvariant(), packageId.Version.ToNormalizedString(), x)).ToList();
-
-        if (referenceFiles != null)
-        {
-            result.Add(new NuGetReference(packageId, referenceFiles.ToImmutableArray()));
-
-            if (referenceFiles.Any(x => !File.Exists(x)) && downloadPackage)
-            {
-                await DownloadAsync(packageId.Id, packageId.Version.ToNormalizedString(), targetFramework.GetShortFolderName(), false, cancellationToken);
-            }
-        }
-
-        // var packagePathResolver = new PackagePathResolver(Path.GetFullPath("packages"));
-
-        if (resolveDependency && dependencyGroups.Any())
-        {
-            await ResolveDependencyReferenceAsync(result, reposities, dependencyGroups, targetFramework, downloadPackage, cancellationToken);
-        }
-    }
-
-    private async Task ResolveDependencyReferenceAsync(List<NuGetReference> result, IEnumerable<SourceRepository> reposities, IEnumerable<PackageDependencyGroup> dependencyGroups, NuGetFramework targetFramework, bool downloadPackage = false, CancellationToken cancellationToken = default)
-    {
-        var packageDependencyGroup = NuGetFrameworkUtility.GetNearest(dependencyGroups, targetFramework);
-
-        if (packageDependencyGroup?.Packages?.Any() == true)
-        {
-            foreach (var packageDependency in packageDependencyGroup.Packages)
-            {
-                // TODO: VersionRange
-                var packageId = new PackageIdentity(packageDependency.Id, packageDependency.VersionRange.MinVersion);
-
-                var packageStream = await GetNupkgStreamAsync(reposities, packageId, cancellationToken);
-
-                if (packageStream.Length == 0)
-                {
-                    throw new Exception($"The nuget package {packageId} not found.");
-                }
-
-                await GetReferencesAsync(result, reposities, packageStream, packageId, targetFramework, true, downloadPackage, cancellationToken);
-            }
-        }
-    }
-
-    private async Task<MemoryStream> GetNupkgStreamAsync(IEnumerable<SourceRepository> reposities, PackageIdentity packageId, CancellationToken cancellationToken = default)
-    {
-        _logger.LogDebug("Starting download package '{packageId}' nupkg ", packageId);
-
-        MemoryStream nupkgStream = new MemoryStream();
-
-        //  local cache
-        var nupkgFile = GetNupkgFileFromCache(packageId);
-        if (!string.IsNullOrWhiteSpace(nupkgFile))
-        {
-            var fileBytes = File.ReadAllBytes(nupkgFile);
-            nupkgStream = new MemoryStream(fileBytes);
-
-            _logger.LogDebug("Find package '{packageId}' nupkg from file: {nupkgFile} ", packageId, nupkgFile);
-        }
-        // from reposity
-        else
-        {
-            foreach (var repository in reposities)
-            {
-                var resource = await repository.GetResourceAsync<FindPackageByIdResource>();
-                if (resource == null)
-                    continue;
-
-                if (await resource.CopyNupkgToStreamAsync(packageId.Id, packageId.Version, nupkgStream, _sourceCacheContext, _nuGetLogger, cancellationToken))
-                {
-                    _logger.LogDebug("Download package '{packageId}' nupkg from '{repository}' ", packageId, repository);
-
-                    break;
-                }
-            }
-        }
-
-        return nupkgStream;
-    }
-
-    private string? GetNupkgFileFromCache(PackageIdentity packageId)
-    {
-        var package = _localRepository.FindPackage(packageId.Id, packageId.Version);
-
-        return package?.ZipPath;
-    }
-
-    //protected SourceRepository GetSourceRepository()
-    //{
-    //    var settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory());
-
-    //    var packageSourceProvider = new PackageSourceProvider(settings);
-
-    //    var packageSource = packageSourceProvider.LoadPackageSources().First();
-
-    //    return Repository.Factory.GetCoreV3(packageSource);
-    //}
-
-    protected IEnumerable<SourceRepository> GetSourceRepositories()
-    {
-        var settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory());
-
-        var packageSourceProvider = new PackageSourceProvider(settings);
-
-        var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, Repository.Provider.GetCoreV3());
-
-        var originSources = sourceRepositoryProvider.GetRepositories();
-
-        var result = new List<SourceRepository>();
-        result.AddRange(originSources);
-
-        if (_engineOptions.NuGetServer.Any())
-        {
-            foreach (var item in _engineOptions.NuGetServer)
-            {
-                result.Add(Repository.Factory.GetCoreV3(item));
-            }
-        }
-
-        return result;
-    }
-}
diff --git a/src/Passingwind.CSharpScript/References/NuGetReferenceResolver.cs b/src/Passingwind.CSharpScript/References/NuGetReferenceResolver.cs
index d7d291b8..3b752941 100644
--- a/src/Passingwind.CSharpScript/References/NuGetReferenceResolver.cs
+++ b/src/Passingwind.CSharpScript/References/NuGetReferenceResolver.cs
@@ -23,16 +23,14 @@ public async Task<ImmutableArray<MetadataReference>> GetReferencesAsync(NuGetDir
             throw new ArgumentNullException(nameof(reference));
         }
 
-        // TODO
         var files = await _nuGetPackageService.GetReferencesAsync(
             packageId: reference.PackageId,
             version: reference.Version,
-            tagetFrameworkName: CSharpEnvironment.GetCurrentShortTargetFramework(),
+            targetFramework: AppContext.TargetFrameworkName!,
             resolveDependency: true,
-            downloadPackage: false,
             cancellationToken: cancellationToken);
 
-        if (files?.Any() == true)
+        if (files.Any())
         {
             return files.Select(x => MetadataReference.CreateFromFile(x)).ToImmutableArray<MetadataReference>();
         }
diff --git a/src/Passingwind.CSharpScript/ServiceCollectionExtensions.cs b/src/Passingwind.CSharpScript/ServiceCollectionExtensions.cs
index b47f2745..3b658516 100644
--- a/src/Passingwind.CSharpScript/ServiceCollectionExtensions.cs
+++ b/src/Passingwind.CSharpScript/ServiceCollectionExtensions.cs
@@ -19,8 +19,10 @@ public static IServiceCollection AddCSharpScriptEngine(this IServiceCollection s
 
         services.TryAddSingleton<ICSharpScriptWorkspace, CSharpScriptWorkspace>();
 
+        services.TryAddSingleton<NuGet.Common.ILogger, NuGetLogger>();
         services.TryAddSingleton<NuGetLogger>();
-        services.TryAddSingleton<INuGetPackageService, NuGetPackageService>();
+        services.TryAddSingleton<INuGetPackageService, DefaultNuGetPackageService>();
+        services.TryAddSingleton<INuGetLocalPackageAssemblyResolver, DefaultNuGetLocalPackageAssemblyResolver>();
 
         return services;
     }