about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-01-31 18:50:16 +0100
committerRory& <root@rory.gay>2024-01-31 18:50:16 +0100
commitd133a168c17d605236e967ff63728420ddb0ed98 (patch)
treeac467c42591db6fb6b920682dd54da1f707f8c0c
parentCapabilities (diff)
downloadLibMatrix-d133a168c17d605236e967ff63728420ddb0ed98.tar.xz
Repo split
-rw-r--r--.editorconfig1805
m---------ExampleBots/LibMatrix.ExampleBot0
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs72
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/Commands/HelpCommand.cs22
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/Commands/PingCommand.cs13
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs38
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs11
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/ICommand.cs12
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/RMUBot.cs114
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/RMUBotConfiguration.cs12
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs69
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj32
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Program.cs30
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/Properties/launchSettings.json26
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/appsettings.Development.json9
-rw-r--r--ExampleBots/LibMatrix.ExampleBot/appsettings.json13
m---------ExampleBots/ModerationBot0
-rw-r--r--ExampleBots/ModerationBot/AccountData/BotData.cs14
-rw-r--r--ExampleBots/ModerationBot/Commands/BanMediaCommand.cs111
-rw-r--r--ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs58
-rw-r--r--ExampleBots/ModerationBot/Commands/DbgAniRainbowTest.cs48
-rw-r--r--ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs38
-rw-r--r--ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs69
-rw-r--r--ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs49
-rw-r--r--ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs73
-rw-r--r--ExampleBots/ModerationBot/Commands/ReloadPoliciesCommand.cs37
-rw-r--r--ExampleBots/ModerationBot/FirstRunTasks.cs83
-rw-r--r--ExampleBots/ModerationBot/ModerationBot.cs303
-rw-r--r--ExampleBots/ModerationBot/ModerationBot.csproj32
-rw-r--r--ExampleBots/ModerationBot/ModerationBotConfiguration.cs10
-rw-r--r--ExampleBots/ModerationBot/PolicyEngine.cs268
-rw-r--r--ExampleBots/ModerationBot/PolicyList.cs16
-rw-r--r--ExampleBots/ModerationBot/Program.cs40
-rw-r--r--ExampleBots/ModerationBot/Properties/launchSettings.json26
-rw-r--r--ExampleBots/ModerationBot/StateEventTypes/Policies/BasePolicy.cs53
-rw-r--r--ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyFile.cs16
-rw-r--r--ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyHomeserver.cs10
-rw-r--r--ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MessagePolicyContainsText.cs10
-rw-r--r--ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/UnknownPolicy.cs7
-rw-r--r--ExampleBots/ModerationBot/appsettings.Development.json24
-rw-r--r--ExampleBots/ModerationBot/appsettings.json9
m---------ExampleBots/PluralContactBotPoC0
-rw-r--r--ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs16
-rw-r--r--ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs15
-rw-r--r--ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs57
-rw-r--r--ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs102
-rw-r--r--ExampleBots/PluralContactBotPoC/Bot/PluralContactBotConfiguration.cs9
-rw-r--r--ExampleBots/PluralContactBotPoC/PluralContactBotPoC.csproj35
-rw-r--r--ExampleBots/PluralContactBotPoC/Program.cs72
-rw-r--r--ExampleBots/PluralContactBotPoC/Properties/launchSettings.json26
-rw-r--r--ExampleBots/PluralContactBotPoC/appsettings.Development.json17
-rw-r--r--ExampleBots/PluralContactBotPoC/appsettings.json9
52 files changed, 1805 insertions, 2235 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e98e832
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,1805 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+trim_trailing_whitespace = true
+insert_final_newline = true
+tab_width = 4
+
+# Microsoft .NET properties
+csharp_indent_braces = false
+csharp_indent_switch_labels = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = false
+csharp_new_line_before_open_brace = none
+csharp_new_line_between_query_expression_clauses = true
+csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
+csharp_preserve_single_line_blocks = true
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+csharp_style_expression_bodied_accessors = true:suggestion
+csharp_style_expression_bodied_constructors = true:none
+csharp_style_expression_bodied_methods = true:none
+csharp_style_expression_bodied_properties = true:suggestion
+csharp_style_namespace_declarations = file_scoped:error
+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
+csharp_using_directive_placement = outside_namespace:silent
+dotnet_diagnostic.bc40000.severity = warning
+dotnet_diagnostic.bc400005.severity = warning
+dotnet_diagnostic.bc40008.severity = warning
+dotnet_diagnostic.bc40056.severity = warning
+dotnet_diagnostic.bc42016.severity = warning
+dotnet_diagnostic.bc42024.severity = warning
+dotnet_diagnostic.bc42025.severity = warning
+dotnet_diagnostic.bc42104.severity = warning
+dotnet_diagnostic.bc42105.severity = warning
+dotnet_diagnostic.bc42106.severity = warning
+dotnet_diagnostic.bc42107.severity = warning
+dotnet_diagnostic.bc42304.severity = warning
+dotnet_diagnostic.bc42309.severity = warning
+dotnet_diagnostic.bc42322.severity = warning
+dotnet_diagnostic.bc42349.severity = warning
+dotnet_diagnostic.bc42353.severity = warning
+dotnet_diagnostic.bc42354.severity = warning
+dotnet_diagnostic.bc42355.severity = warning
+dotnet_diagnostic.bc42356.severity = warning
+dotnet_diagnostic.bc42358.severity = warning
+dotnet_diagnostic.bc42504.severity = warning
+dotnet_diagnostic.bc42505.severity = warning
+dotnet_diagnostic.ca2252.severity = error
+dotnet_diagnostic.cs0067.severity = warning
+dotnet_diagnostic.cs0078.severity = warning
+dotnet_diagnostic.cs0108.severity = warning
+dotnet_diagnostic.cs0109.severity = warning
+dotnet_diagnostic.cs0114.severity = warning
+dotnet_diagnostic.cs0162.severity = warning
+dotnet_diagnostic.cs0164.severity = warning
+dotnet_diagnostic.cs0168.severity = warning
+dotnet_diagnostic.cs0169.severity = warning
+dotnet_diagnostic.cs0183.severity = warning
+dotnet_diagnostic.cs0184.severity = warning
+dotnet_diagnostic.cs0197.severity = warning
+dotnet_diagnostic.cs0219.severity = warning
+dotnet_diagnostic.cs0252.severity = warning
+dotnet_diagnostic.cs0253.severity = warning
+dotnet_diagnostic.cs0414.severity = warning
+dotnet_diagnostic.cs0420.severity = warning
+dotnet_diagnostic.cs0458.severity = warning
+dotnet_diagnostic.cs0464.severity = warning
+dotnet_diagnostic.cs0465.severity = warning
+dotnet_diagnostic.cs0469.severity = warning
+dotnet_diagnostic.cs0472.severity = warning
+dotnet_diagnostic.cs0612.severity = warning
+dotnet_diagnostic.cs0618.severity = warning
+dotnet_diagnostic.cs0628.severity = warning
+dotnet_diagnostic.cs0642.severity = warning
+dotnet_diagnostic.cs0649.severity = warning
+dotnet_diagnostic.cs0652.severity = warning
+dotnet_diagnostic.cs0657.severity = warning
+dotnet_diagnostic.cs0658.severity = warning
+dotnet_diagnostic.cs0659.severity = warning
+dotnet_diagnostic.cs0660.severity = warning
+dotnet_diagnostic.cs0661.severity = warning
+dotnet_diagnostic.cs0665.severity = warning
+dotnet_diagnostic.cs0672.severity = warning
+dotnet_diagnostic.cs0675.severity = warning
+dotnet_diagnostic.cs0693.severity = warning
+dotnet_diagnostic.cs1030.severity = warning
+dotnet_diagnostic.cs1058.severity = warning
+dotnet_diagnostic.cs1066.severity = warning
+dotnet_diagnostic.cs1522.severity = warning
+dotnet_diagnostic.cs1570.severity = warning
+dotnet_diagnostic.cs1571.severity = warning
+dotnet_diagnostic.cs1572.severity = warning
+dotnet_diagnostic.cs1573.severity = warning
+dotnet_diagnostic.cs1574.severity = warning
+dotnet_diagnostic.cs1580.severity = warning
+dotnet_diagnostic.cs1581.severity = warning
+dotnet_diagnostic.cs1584.severity = warning
+dotnet_diagnostic.cs1587.severity = warning
+dotnet_diagnostic.cs1589.severity = warning
+dotnet_diagnostic.cs1590.severity = warning
+dotnet_diagnostic.cs1591.severity = warning
+dotnet_diagnostic.cs1592.severity = warning
+dotnet_diagnostic.cs1710.severity = warning
+dotnet_diagnostic.cs1711.severity = warning
+dotnet_diagnostic.cs1712.severity = warning
+dotnet_diagnostic.cs1717.severity = warning
+dotnet_diagnostic.cs1723.severity = warning
+dotnet_diagnostic.cs1911.severity = warning
+dotnet_diagnostic.cs1957.severity = warning
+dotnet_diagnostic.cs1981.severity = warning
+dotnet_diagnostic.cs1998.severity = warning
+dotnet_diagnostic.cs4014.severity = warning
+dotnet_diagnostic.cs7022.severity = warning
+dotnet_diagnostic.cs7023.severity = warning
+dotnet_diagnostic.cs7095.severity = warning
+dotnet_diagnostic.cs8073.severity = warning
+dotnet_diagnostic.cs8094.severity = warning
+dotnet_diagnostic.cs8123.severity = warning
+dotnet_diagnostic.cs8321.severity = warning
+dotnet_diagnostic.cs8383.severity = warning
+dotnet_diagnostic.cs8416.severity = warning
+dotnet_diagnostic.cs8417.severity = warning
+dotnet_diagnostic.cs8424.severity = warning
+dotnet_diagnostic.cs8425.severity = warning
+dotnet_diagnostic.cs8500.severity = warning
+dotnet_diagnostic.cs8509.severity = warning
+dotnet_diagnostic.cs8524.severity = warning
+dotnet_diagnostic.cs8597.severity = warning
+dotnet_diagnostic.cs8600.severity = warning
+dotnet_diagnostic.cs8601.severity = warning
+dotnet_diagnostic.cs8602.severity = warning
+dotnet_diagnostic.cs8603.severity = warning
+dotnet_diagnostic.cs8604.severity = warning
+dotnet_diagnostic.cs8605.severity = warning
+dotnet_diagnostic.cs8607.severity = warning
+dotnet_diagnostic.cs8608.severity = warning
+dotnet_diagnostic.cs8609.severity = warning
+dotnet_diagnostic.cs8610.severity = warning
+dotnet_diagnostic.cs8611.severity = warning
+dotnet_diagnostic.cs8612.severity = warning
+dotnet_diagnostic.cs8613.severity = warning
+dotnet_diagnostic.cs8614.severity = warning
+dotnet_diagnostic.cs8615.severity = warning
+dotnet_diagnostic.cs8616.severity = warning
+dotnet_diagnostic.cs8617.severity = warning
+dotnet_diagnostic.cs8618.severity = warning
+dotnet_diagnostic.cs8619.severity = warning
+dotnet_diagnostic.cs8620.severity = warning
+dotnet_diagnostic.cs8621.severity = warning
+dotnet_diagnostic.cs8622.severity = warning
+dotnet_diagnostic.cs8624.severity = warning
+dotnet_diagnostic.cs8625.severity = warning
+dotnet_diagnostic.cs8629.severity = warning
+dotnet_diagnostic.cs8631.severity = warning
+dotnet_diagnostic.cs8632.severity = warning
+dotnet_diagnostic.cs8633.severity = warning
+dotnet_diagnostic.cs8634.severity = warning
+dotnet_diagnostic.cs8643.severity = warning
+dotnet_diagnostic.cs8644.severity = warning
+dotnet_diagnostic.cs8645.severity = warning
+dotnet_diagnostic.cs8655.severity = warning
+dotnet_diagnostic.cs8656.severity = warning
+dotnet_diagnostic.cs8667.severity = warning
+dotnet_diagnostic.cs8669.severity = warning
+dotnet_diagnostic.cs8670.severity = warning
+dotnet_diagnostic.cs8714.severity = warning
+dotnet_diagnostic.cs8762.severity = warning
+dotnet_diagnostic.cs8763.severity = warning
+dotnet_diagnostic.cs8764.severity = warning
+dotnet_diagnostic.cs8765.severity = warning
+dotnet_diagnostic.cs8766.severity = warning
+dotnet_diagnostic.cs8767.severity = warning
+dotnet_diagnostic.cs8768.severity = warning
+dotnet_diagnostic.cs8769.severity = warning
+dotnet_diagnostic.cs8770.severity = warning
+dotnet_diagnostic.cs8774.severity = warning
+dotnet_diagnostic.cs8775.severity = warning
+dotnet_diagnostic.cs8776.severity = warning
+dotnet_diagnostic.cs8777.severity = warning
+dotnet_diagnostic.cs8794.severity = warning
+dotnet_diagnostic.cs8819.severity = warning
+dotnet_diagnostic.cs8824.severity = warning
+dotnet_diagnostic.cs8825.severity = warning
+dotnet_diagnostic.cs8846.severity = warning
+dotnet_diagnostic.cs8847.severity = warning
+dotnet_diagnostic.cs8851.severity = warning
+dotnet_diagnostic.cs8860.severity = warning
+dotnet_diagnostic.cs8892.severity = warning
+dotnet_diagnostic.cs8907.severity = warning
+dotnet_diagnostic.cs8947.severity = warning
+dotnet_diagnostic.cs8960.severity = warning
+dotnet_diagnostic.cs8961.severity = warning
+dotnet_diagnostic.cs8962.severity = warning
+dotnet_diagnostic.cs8963.severity = warning
+dotnet_diagnostic.cs8965.severity = warning
+dotnet_diagnostic.cs8966.severity = warning
+dotnet_diagnostic.cs8971.severity = warning
+dotnet_diagnostic.cs8981.severity = warning
+dotnet_diagnostic.cs9042.severity = warning
+dotnet_diagnostic.cs9073.severity = warning
+dotnet_diagnostic.cs9074.severity = warning
+dotnet_diagnostic.cs9080.severity = warning
+dotnet_diagnostic.cs9081.severity = warning
+dotnet_diagnostic.cs9082.severity = warning
+dotnet_diagnostic.cs9083.severity = warning
+dotnet_diagnostic.cs9084.severity = warning
+dotnet_diagnostic.cs9085.severity = warning
+dotnet_diagnostic.cs9086.severity = warning
+dotnet_diagnostic.cs9087.severity = warning
+dotnet_diagnostic.cs9088.severity = warning
+dotnet_diagnostic.cs9089.severity = warning
+dotnet_diagnostic.cs9090.severity = warning
+dotnet_diagnostic.cs9091.severity = warning
+dotnet_diagnostic.cs9092.severity = warning
+dotnet_diagnostic.cs9093.severity = warning
+dotnet_diagnostic.cs9094.severity = warning
+dotnet_diagnostic.cs9095.severity = warning
+dotnet_diagnostic.cs9097.severity = warning
+dotnet_diagnostic.wme006.severity = warning
+dotnet_naming_rule.constants_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.constants_rule.severity = warning
+dotnet_naming_rule.constants_rule.style = upper_camel_case_style
+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 = upper_camel_case_style
+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 = i_upper_camel_case_style
+dotnet_naming_rule.interfaces_rule.symbols = interfaces_symbols
+dotnet_naming_rule.locals_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.locals_rule.severity = warning
+dotnet_naming_rule.locals_rule.style = lower_camel_case_style_1
+dotnet_naming_rule.locals_rule.symbols = locals_symbols
+dotnet_naming_rule.local_constants_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.local_constants_rule.severity = warning
+dotnet_naming_rule.local_constants_rule.style = lower_camel_case_style_1
+dotnet_naming_rule.local_constants_rule.symbols = local_constants_symbols
+dotnet_naming_rule.local_functions_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.local_functions_rule.severity = warning
+dotnet_naming_rule.local_functions_rule.style = upper_camel_case_style
+dotnet_naming_rule.local_functions_rule.symbols = local_functions_symbols
+dotnet_naming_rule.method_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.method_rule.severity = warning
+dotnet_naming_rule.method_rule.style = upper_camel_case_style
+dotnet_naming_rule.method_rule.symbols = method_symbols
+dotnet_naming_rule.parameters_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.parameters_rule.severity = warning
+dotnet_naming_rule.parameters_rule.style = lower_camel_case_style_1
+dotnet_naming_rule.parameters_rule.symbols = parameters_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 = upper_camel_case_style
+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 = lower_camel_case_style
+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 = lower_camel_case_style
+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 = upper_camel_case_style
+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 = upper_camel_case_style
+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 = upper_camel_case_style
+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 = upper_camel_case_style
+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 = upper_camel_case_style
+dotnet_naming_rule.types_and_namespaces_rule.symbols = types_and_namespaces_symbols
+dotnet_naming_rule.type_parameters_rule.import_to_resharper = as_predefined
+dotnet_naming_rule.type_parameters_rule.severity = warning
+dotnet_naming_rule.type_parameters_rule.style = t_upper_camel_case_style
+dotnet_naming_rule.type_parameters_rule.symbols = type_parameters_symbols
+dotnet_naming_style.i_upper_camel_case_style.capitalization = pascal_case
+dotnet_naming_style.i_upper_camel_case_style.required_prefix = I
+dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
+dotnet_naming_style.lower_camel_case_style.required_prefix = _
+dotnet_naming_style.lower_camel_case_style_1.capitalization = camel_case
+dotnet_naming_style.t_upper_camel_case_style.capitalization = pascal_case
+dotnet_naming_style.t_upper_camel_case_style.required_prefix = T
+dotnet_naming_style.upper_camel_case_style.capitalization = pascal_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.locals_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.locals_symbols.applicable_kinds = local
+dotnet_naming_symbols.local_constants_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.local_constants_symbols.applicable_kinds = local
+dotnet_naming_symbols.local_constants_symbols.required_modifiers = const
+dotnet_naming_symbols.local_functions_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.local_functions_symbols.applicable_kinds = local_function
+dotnet_naming_symbols.method_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.method_symbols.applicable_kinds = method
+dotnet_naming_symbols.parameters_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.parameters_symbols.applicable_kinds = parameter
+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.type_parameters_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity: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:error
+file_header_template =  # ReSharper properties
+
+resharper_alignment_tab_fill_style = use_spaces
+resharper_align_first_arg_by_paren = false
+resharper_align_linq_query = false
+resharper_align_multiline_array_and_object_initializer = false
+resharper_align_multiline_array_initializer = true
+resharper_align_multiline_binary_patterns = false
+resharper_align_multiline_ctor_init = true
+resharper_align_multiline_expression_braces = false
+resharper_align_multiline_implements_list = true
+resharper_align_multiline_list_pattern = false
+resharper_align_multiline_property_pattern = false
+resharper_align_multiline_statement_conditions = true
+resharper_align_multiline_switch_expression = false
+resharper_align_multiline_type_argument = true
+resharper_align_multiline_type_parameter = true
+resharper_align_multline_type_parameter_constrains = false
+resharper_align_multline_type_parameter_list = false
+resharper_align_ternary = align_not_nested
+resharper_align_tuple_components = false
+resharper_allow_alias = true
+resharper_allow_comment_after_lbrace = false
+resharper_always_use_end_of_line_brace_style = false
+resharper_apply_auto_detected_rules = false
+resharper_apply_on_completion = false
+resharper_arguments_anonymous_function = positional
+resharper_arguments_literal = positional
+resharper_arguments_named = positional
+resharper_arguments_other = positional
+resharper_arguments_skip_single = false
+resharper_arguments_string_literal = positional
+resharper_attribute_style = do_not_touch
+resharper_autodetect_indent_settings = true
+resharper_blank_lines_after_access_specifier = 0
+resharper_blank_lines_after_block_statements = 1
+resharper_blank_lines_after_case = 0
+resharper_blank_lines_after_control_transfer_statements = 0
+resharper_blank_lines_after_file_scoped_namespace_directive = 1
+resharper_blank_lines_after_imports = 1
+resharper_blank_lines_after_multiline_statements = 0
+resharper_blank_lines_after_options = 1
+resharper_blank_lines_after_start_comment = 1
+resharper_blank_lines_after_using_list = 1
+resharper_blank_lines_around_accessor = 0
+resharper_blank_lines_around_auto_property = 1
+resharper_blank_lines_around_block_case_section = 0
+resharper_blank_lines_around_class_definition = 1
+resharper_blank_lines_around_field = 1
+resharper_blank_lines_around_function_declaration = 0
+resharper_blank_lines_around_function_definition = 1
+resharper_blank_lines_around_global_attribute = 0
+resharper_blank_lines_around_invocable = 1
+resharper_blank_lines_around_local_method = 1
+resharper_blank_lines_around_multiline_case_section = 0
+resharper_blank_lines_around_namespace = 1
+resharper_blank_lines_around_other_declaration = 0
+resharper_blank_lines_around_property = 1
+resharper_blank_lines_around_razor_functions = 1
+resharper_blank_lines_around_razor_helpers = 1
+resharper_blank_lines_around_razor_sections = 1
+resharper_blank_lines_around_region = 1
+resharper_blank_lines_around_single_line_accessor = 0
+resharper_blank_lines_around_single_line_auto_property = 0
+resharper_blank_lines_around_single_line_field = 0
+resharper_blank_lines_around_single_line_function_definition = 0
+resharper_blank_lines_around_single_line_invocable = 0
+resharper_blank_lines_around_single_line_local_method = 0
+resharper_blank_lines_around_single_line_property = 0
+resharper_blank_lines_around_single_line_type = 1
+resharper_blank_lines_around_type = 1
+resharper_blank_lines_before_access_specifier = 1
+resharper_blank_lines_before_block_statements = 0
+resharper_blank_lines_before_case = 0
+resharper_blank_lines_before_control_transfer_statements = 0
+resharper_blank_lines_before_multiline_statements = 0
+resharper_blank_lines_before_single_line_comment = 0
+resharper_blank_lines_inside_namespace = 0
+resharper_blank_lines_inside_region = 1
+resharper_blank_lines_inside_type = 0
+resharper_blank_line_after_pi = true
+resharper_braces_for_dowhile = required
+resharper_braces_for_fixed = required
+resharper_braces_for_for = not_required
+resharper_braces_for_foreach = not_required
+resharper_braces_for_ifelse = not_required
+resharper_braces_for_lock = required
+resharper_braces_for_using = required
+resharper_braces_for_while = not_required
+resharper_braces_redundant = true
+resharper_break_template_declaration = line_break
+resharper_builtin_type_apply_to_native_integer = false
+resharper_can_use_global_alias = true
+resharper_configure_await_analysis_mode = disabled
+resharper_continuous_indent_multiplier = 1
+resharper_continuous_line_indent = single
+public virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualresharper_csharp_align_multiline_argument = false
+resharper_csharp_align_multiline_binary_expressions_chain = true
+resharper_csharp_align_multiline_calls_chain = false
+resharper_csharp_align_multiline_expression = false
+resharper_csharp_align_multiline_extends_list = false
+resharper_csharp_align_multiline_for_stmt = false
+resharper_csharp_align_multiline_parameter = false
+resharper_csharp_align_multiple_declaration = false
+resharper_csharp_allow_far_alignment = true
+resharper_csharp_empty_block_style = together_same_line
+resharper_csharp_insert_final_newline = false
+resharper_csharp_keep_blank_lines_in_code = 1
+resharper_csharp_keep_blank_lines_in_declarations = 1
+resharper_csharp_max_line_length = 180
+resharper_csharp_naming_rule.constants = AaBb
+resharper_csharp_naming_rule.enum_member = AaBb
+resharper_csharp_naming_rule.local_constants = aaBb
+resharper_csharp_naming_rule.method_property_event = AaBb
+resharper_csharp_naming_rule.other = AaBb
+resharper_csharp_naming_rule.private_constants = AaBb
+resharper_csharp_naming_rule.private_static_fields = _ + aaBb
+resharper_csharp_naming_rule.private_static_readonly = AaBb
+resharper_csharp_naming_rule.static_readonly = AaBb
+resharper_csharp_new_line_before_while = false
+resharper_csharp_prefer_qualified_reference = false
+resharper_csharp_space_after_unary_operator = false
+resharper_csharp_stick_comment = false
+resharper_csharp_wrap_lines = true
+resharper_cxxcli_property_declaration_braces = next_line
+resharper_default_exception_variable_name = e
+resharper_default_value_when_type_evident = default_literal
+resharper_default_value_when_type_not_evident = default_literal
+resharper_delete_quotes_from_solid_values = false
+resharper_disable_blank_line_changes = false
+resharper_disable_formatter = false
+resharper_disable_indenter = false
+resharper_disable_int_align = false
+resharper_disable_line_break_changes = false
+resharper_disable_line_break_removal = false
+resharper_disable_space_changes = false
+resharper_disable_space_changes_before_trailing_comment = false
+resharper_dont_remove_extra_blank_lines = false
+resharper_enable_wrapping = false
+resharper_enforce_line_ending_style = false
+resharper_event_handler_pattern_long = $object$On$event$
+resharper_event_handler_pattern_short = On$event$
+resharper_export_declaration_braces = next_line
+resharper_expression_braces = inside
+resharper_expression_pars = inside
+resharper_extra_spaces = remove_all
+resharper_force_attribute_style = separate
+resharper_force_chop_compound_do_expression = false
+resharper_force_chop_compound_if_expression = false
+resharper_force_chop_compound_while_expression = false
+resharper_formatter_off_tag = @formatter:off
+resharper_formatter_on_tag = @formatter:on
+resharper_formatter_tags_accept_regexp = false
+resharper_formatter_tags_enabled = true
+resharper_format_leading_spaces_decl = false
+resharper_free_block_braces = next_line
+resharper_function_declaration_return_type_style = do_not_change
+resharper_function_definition_return_type_style = do_not_change
+resharper_generator_mode = false
+resharper_html_allow_far_alignment = true
+resharper_html_attribute_indent = align_by_first_attribute
+resharper_html_insert_final_newline = false
+resharper_html_linebreak_before_elements = body, div, p, form, h1, h2, h3
+resharper_html_max_blank_lines_between_tags = 2
+resharper_html_max_line_length = 180
+resharper_html_pi_attribute_style = on_single_line
+resharper_html_space_before_self_closing = false
+resharper_html_wrap_lines = true
+resharper_ignore_space_preservation = false
+resharper_include_prefix_comment_in_indent = false
+resharper_indent_access_specifiers_from_class = false
+resharper_indent_aligned_ternary = true
+resharper_indent_anonymous_method_block = false
+resharper_indent_braces_inside_statement_conditions = true
+resharper_indent_case_from_select = true
+resharper_indent_child_elements = OneIndent
+resharper_indent_class_members_from_access_specifiers = false
+resharper_indent_comment = true
+resharper_indent_export_declaration_members = true
+resharper_indent_inside_namespace = true
+resharper_indent_invocation_pars = inside
+resharper_indent_method_decl_pars = inside
+resharper_indent_nested_fixed_stmt = true
+resharper_indent_nested_foreach_stmt = true
+resharper_indent_nested_for_stmt = true
+resharper_indent_nested_lock_stmt = true
+resharper_indent_nested_usings_stmt = true
+resharper_indent_nested_while_stmt = true
+resharper_indent_pars = inside
+resharper_indent_preprocessor_directives = none
+resharper_indent_preprocessor_if = no_indent
+resharper_indent_preprocessor_other = no_indent
+resharper_indent_preprocessor_region = no_indent
+resharper_indent_statement_pars = inside
+resharper_indent_text = OneIndent
+resharper_indent_typearg_angles = inside
+resharper_indent_typeparam_angles = inside
+resharper_indent_type_constraints = true
+resharper_indent_wrapped_function_names = false
+resharper_instance_members_qualify_declared_in = this_class, base_class
+resharper_int_align = false
+resharper_int_align_comments = false
+resharper_int_align_declaration_names = false
+resharper_int_align_enum_initializers = false
+resharper_int_align_eq = false
+resharper_int_align_fix_in_adjacent = true
+resharper_keep_existing_attribute_arrangement = false
+resharper_keep_existing_declaration_block_arrangement = false
+resharper_keep_existing_declaration_parens_arrangement = true
+resharper_keep_existing_embedded_arrangement = true
+resharper_keep_existing_embedded_block_arrangement = false
+resharper_keep_existing_enum_arrangement = false
+resharper_keep_existing_expr_member_arrangement = true
+resharper_keep_existing_invocation_parens_arrangement = true
+resharper_keep_existing_list_patterns_arrangement = true
+resharper_keep_existing_property_patterns_arrangement = true
+resharper_keep_existing_switch_expression_arrangement = true
+resharper_keep_nontrivial_alias = true
+resharper_keep_user_linebreaks = true
+resharper_keep_user_wrapping = true
+resharper_linebreaks_around_razor_statements = true
+resharper_linebreaks_inside_tags_for_elements_longer_than = 2147483647
+resharper_linebreaks_inside_tags_for_elements_with_child_elements = true
+resharper_linebreaks_inside_tags_for_multiline_elements = true
+resharper_linebreak_before_all_elements = false
+resharper_linebreak_before_multiline_elements = true
+resharper_linebreak_before_singleline_elements = false
+resharper_line_break_after_colon_in_member_initializer_lists = do_not_change
+resharper_line_break_after_comma_in_member_initializer_lists = false
+resharper_line_break_after_init_statement = do_not_change
+resharper_line_break_before_comma_in_member_initializer_lists = false
+resharper_line_break_before_requires_clause = do_not_change
+resharper_linkage_specification_braces = end_of_line
+resharper_linkage_specification_indentation = none
+resharper_local_function_body = expression_body
+resharper_macro_block_begin = 
+resharper_macro_block_end = 
+resharper_max_array_initializer_elements_on_line = 10000
+resharper_max_attribute_length_for_same_line = 38
+resharper_max_enum_members_on_line = 3
+resharper_max_formal_parameters_on_line = 10000
+resharper_max_initializer_elements_on_line = 4
+resharper_max_invocation_arguments_on_line = 10000
+resharper_member_initializer_list_style = do_not_change
+resharper_namespace_declaration_braces = next_line
+resharper_namespace_indentation = all
+resharper_nested_ternary_style = autodetect
+resharper_new_line_before_catch = true
+resharper_new_line_before_else = true
+resharper_new_line_before_enumerators = true
+resharper_normalize_tag_names = false
+resharper_no_indent_inside_elements = 
+resharper_no_indent_inside_if_element_longer_than = 2000000
+resharper_null_checking_pattern_style = not_null_pattern
+resharper_object_creation_when_type_evident = target_typed
+resharper_object_creation_when_type_not_evident = explicitly_typed
+resharper_old_engine = false
+resharper_outdent_binary_ops = false
+resharper_outdent_binary_pattern_ops = false
+resharper_outdent_commas = false
+resharper_outdent_dots = false
+resharper_outdent_namespace_member = false
+resharper_outdent_statement_labels = true
+resharper_outdent_ternary_ops = false
+resharper_parentheses_non_obvious_operations = none, shift, bitwise_and, bitwise_exclusive_or, bitwise_inclusive_or, bitwise
+resharper_parentheses_redundancy_style = remove_if_not_clarifies_precedence
+resharper_parentheses_same_type_operations = true
+resharper_pi_attributes_indent = align_by_first_attribute
+resharper_place_accessorholder_attribute_on_same_line = false
+resharper_place_accessor_attribute_on_same_line = if_owner_is_single_line
+resharper_place_comments_at_first_column = false
+resharper_place_constructor_initializer_on_same_line = true
+resharper_place_event_attribute_on_same_line = false
+resharper_place_expr_accessor_on_single_line = if_owner_is_single_line
+resharper_place_expr_method_on_single_line = if_owner_is_single_line
+resharper_place_expr_property_on_single_line = if_owner_is_single_line
+resharper_place_field_attribute_on_same_line = true
+resharper_place_linq_into_on_new_line = true
+resharper_place_method_attribute_on_same_line = false
+resharper_place_namespace_definitions_on_same_line = false
+resharper_place_property_attribute_on_same_line = false
+resharper_place_record_field_attribute_on_same_line = if_owner_is_single_line
+resharper_place_simple_case_statement_on_same_line = false
+resharper_place_simple_embedded_statement_on_same_line = if_owner_is_single_line
+resharper_place_simple_initializer_on_single_line = true
+resharper_place_simple_list_pattern_on_single_line = true
+resharper_place_simple_property_pattern_on_single_line = true
+resharper_place_simple_switch_expression_on_single_line = false
+resharper_place_type_attribute_on_same_line = false
+resharper_place_type_constraints_on_same_line = true
+resharper_prefer_explicit_discard_declaration = false
+resharper_prefer_separate_deconstructed_variables_declaration = false
+resharper_preserve_spaces_inside_tags = pre, textarea
+resharper_qualified_using_at_nested_scope = false
+resharper_quote_style = doublequoted
+resharper_razor_prefer_qualified_reference = true
+resharper_remove_blank_lines_near_braces = false
+resharper_remove_blank_lines_near_braces_in_code = true
+resharper_remove_blank_lines_near_braces_in_declarations = true
+resharper_remove_this_qualifier = true
+resharper_requires_expression_braces = next_line
+resharper_resx_allow_far_alignment = false
+resharper_resx_attribute_indent = single_indent
+resharper_resx_insert_final_newline = false
+resharper_resx_linebreak_before_elements = 
+resharper_resx_max_blank_lines_between_tags = 0
+resharper_resx_max_line_length = 2147483647
+resharper_resx_pi_attribute_style = do_not_touch
+resharper_resx_space_before_self_closing = false
+resharper_resx_wrap_lines = false
+resharper_resx_wrap_tags_and_pi = false
+resharper_resx_wrap_text = false
+resharper_show_autodetect_configure_formatting_tip = true
+resharper_simple_block_style = do_not_change
+resharper_simple_case_statement_style = do_not_change
+resharper_simple_embedded_statement_style = do_not_change
+resharper_sort_attributes = false
+resharper_sort_class_selectors = false
+resharper_sort_usings = true
+resharper_sort_usings_lowercase_first = false
+resharper_spaces_around_eq_in_attribute = false
+resharper_spaces_around_eq_in_pi_attribute = false
+resharper_spaces_inside_tags = false
+resharper_space_after_attributes = true
+resharper_space_after_attribute_target_colon = true
+resharper_space_after_cast = false
+resharper_space_after_colon = true
+resharper_space_after_colon_in_case = true
+resharper_space_after_colon_in_inheritance_clause = true
+resharper_space_after_comma = true
+resharper_space_after_ellipsis_in_parameter_pack = true
+resharper_space_after_for_colon = true
+resharper_space_after_keywords_in_control_flow_statements = true
+resharper_space_after_last_attribute = false
+resharper_space_after_last_pi_attribute = false
+resharper_space_after_operator_keyword = true
+resharper_space_after_operator_not = false
+resharper_space_after_ptr_in_data_member = true
+resharper_space_after_ptr_in_data_members = false
+resharper_space_after_ptr_in_method = true
+resharper_space_after_ptr_in_nested_declarator = false
+resharper_space_after_ref_in_data_member = true
+resharper_space_after_ref_in_data_members = false
+resharper_space_after_ref_in_method = true
+resharper_space_after_semicolon_in_for_statement = true
+resharper_space_after_ternary_colon = true
+resharper_space_after_ternary_quest = true
+resharper_space_after_triple_slash = true
+resharper_space_after_type_parameter_constraint_colon = true
+resharper_space_around_additive_op = true
+resharper_space_around_alias_eq = true
+resharper_space_around_assignment_op = true
+resharper_space_around_assignment_operator = true
+resharper_space_around_deref_in_trailing_return_type = true
+resharper_space_around_lambda_arrow = true
+resharper_space_around_member_access_operator = false
+resharper_space_around_relational_op = true
+resharper_space_around_shift_op = true
+resharper_space_around_stmt_colon = true
+resharper_space_around_ternary_operator = true
+resharper_space_before_array_rank_parentheses = false
+resharper_space_before_attribute_target_colon = false
+resharper_space_before_checked_parentheses = false
+resharper_space_before_colon = false
+resharper_space_before_colon_in_case = false
+resharper_space_before_colon_in_inheritance_clause = true
+resharper_space_before_comma = false
+resharper_space_before_default_parentheses = false
+resharper_space_before_ellipsis_in_parameter_pack = false
+resharper_space_before_empty_invocation_parentheses = false
+resharper_space_before_empty_method_parentheses = false
+resharper_space_before_for_colon = true
+resharper_space_before_initializer_braces = false
+resharper_space_before_invocation_parentheses = false
+resharper_space_before_label_colon = false
+resharper_space_before_lambda_parentheses = false
+resharper_space_before_method_parentheses = false
+resharper_space_before_nameof_parentheses = false
+resharper_space_before_new_parentheses = false
+resharper_space_before_nullable_mark = false
+resharper_space_before_open_square_brackets = false
+resharper_space_before_pointer_asterik_declaration = false
+resharper_space_before_postfix_operator = false
+resharper_space_before_ptr_in_abstract_decl = false
+resharper_space_before_ptr_in_data_member = false
+resharper_space_before_ptr_in_data_members = true
+resharper_space_before_ptr_in_method = false
+resharper_space_before_ref_in_abstract_decl = false
+resharper_space_before_ref_in_data_member = false
+resharper_space_before_ref_in_data_members = true
+resharper_space_before_ref_in_method = false
+resharper_space_before_semicolon = false
+resharper_space_before_semicolon_in_for_statement = false
+resharper_space_before_singleline_accessorholder = true
+resharper_space_before_sizeof_parentheses = false
+resharper_space_before_template_args = false
+resharper_space_before_template_params = true
+resharper_space_before_ternary_colon = true
+resharper_space_before_ternary_quest = true
+resharper_space_before_trailing_comment = true
+resharper_space_before_typeof_parentheses = false
+resharper_space_before_type_argument_angle = false
+resharper_space_before_type_parameter_angle = false
+resharper_space_before_type_parameter_constraint_colon = true
+resharper_space_before_type_parameter_parentheses = true
+resharper_space_between_accessors_in_singleline_property = true
+resharper_space_between_attribute_sections = true
+resharper_space_between_closing_angle_brackets_in_template_args = false
+resharper_space_between_keyword_and_expression = true
+resharper_space_between_keyword_and_type = true
+resharper_space_between_method_call_empty_parameter_list_parentheses = false
+resharper_space_between_method_call_name_and_opening_parenthesis = false
+resharper_space_between_method_call_parameter_list_parentheses = false
+resharper_space_between_method_declaration_empty_parameter_list_parentheses = false
+resharper_space_between_method_declaration_name_and_open_parenthesis = false
+resharper_space_between_method_declaration_parameter_list_parentheses = false
+resharper_space_between_parentheses_of_control_flow_statements = false
+resharper_space_between_square_brackets = false
+resharper_space_between_typecast_parentheses = false
+resharper_space_in_singleline_accessorholder = true
+resharper_space_in_singleline_anonymous_method = true
+resharper_space_in_singleline_method = true
+resharper_space_near_postfix_and_prefix_op = false
+resharper_space_within_array_initialization_braces = false
+resharper_space_within_array_rank_empty_parentheses = false
+resharper_space_within_array_rank_parentheses = false
+resharper_space_within_attribute_angles = false
+resharper_space_within_checked_parentheses = false
+resharper_space_within_declaration_parentheses = false
+resharper_space_within_default_parentheses = false
+resharper_space_within_empty_braces = true
+resharper_space_within_empty_initializer_braces = false
+resharper_space_within_empty_invocation_parentheses = false
+resharper_space_within_empty_method_parentheses = false
+resharper_space_within_empty_template_params = false
+resharper_space_within_expression_parentheses = false
+resharper_space_within_initializer_braces = false
+resharper_space_within_invocation_parentheses = false
+resharper_space_within_method_parentheses = false
+resharper_space_within_nameof_parentheses = false
+resharper_space_within_new_parentheses = false
+resharper_space_within_parentheses = false
+resharper_space_within_single_line_array_initializer_braces = true
+resharper_space_within_sizeof_parentheses = false
+resharper_space_within_slice_pattern = true
+resharper_space_within_template_args = false
+resharper_space_within_template_params = false
+resharper_space_within_tuple_parentheses = false
+resharper_space_within_typeof_parentheses = false
+resharper_space_within_type_argument_angles = false
+resharper_space_within_type_parameter_angles = false
+resharper_space_within_type_parameter_parentheses = false
+resharper_special_else_if_treatment = true
+resharper_static_members_qualify_members = none
+resharper_static_members_qualify_with = declared_type
+resharper_support_vs_event_naming_pattern = true
+resharper_t4_allow_far_alignment = false
+resharper_t4_insert_final_newline = false
+resharper_t4_max_line_length = 180
+resharper_t4_wrap_lines = true
+resharper_toplevel_function_declaration_return_type_style = do_not_change
+resharper_toplevel_function_definition_return_type_style = do_not_change
+resharper_trailing_comma_in_multiline_lists = false
+resharper_trailing_comma_in_singleline_lists = false
+resharper_use_continuous_indent_inside_initializer_braces = false
+resharper_use_continuous_indent_inside_parens = true
+resharper_use_continuous_line_indent_in_expression_braces = false
+resharper_use_continuous_line_indent_in_method_pars = false
+resharper_use_indents_from_main_language_in_file = true
+resharper_use_indent_from_previous_element = true
+resharper_use_indent_from_vs = false
+resharper_use_roslyn_logic_for_evident_types = false
+public virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualresharper_wrap_after_binary_opsign = true
+resharper_wrap_after_declaration_lpar = false
+resharper_wrap_after_dot = false
+resharper_wrap_after_dot_in_method_calls = false
+resharper_wrap_after_expression_lbrace = true
+resharper_wrap_after_invocation_lpar = false
+resharper_wrap_arguments_style = wrap_if_long
+resharper_wrap_around_elements = true
+resharper_wrap_array_initializer_style = wrap_if_long
+resharper_wrap_base_clause_style = wrap_if_long
+resharper_wrap_before_arrow_with_expressions = false
+resharper_wrap_before_binary_opsign = false
+resharper_wrap_before_binary_pattern_op = true
+resharper_wrap_before_colon = false
+resharper_wrap_before_comma = false
+resharper_wrap_before_comma_in_base_clause = false
+resharper_wrap_before_declaration_lpar = false
+resharper_wrap_before_declaration_rpar = false
+resharper_wrap_before_eq = false
+resharper_wrap_before_expression_rbrace = true
+resharper_wrap_before_extends_colon = false
+resharper_wrap_before_first_type_parameter_constraint = false
+resharper_wrap_before_invocation_lpar = false
+resharper_wrap_before_invocation_rpar = false
+resharper_wrap_before_linq_expression = false
+resharper_wrap_before_ternary_opsigns = true
+resharper_wrap_before_type_parameter_langle = false
+resharper_wrap_braced_init_list_style = wrap_if_long
+resharper_wrap_chained_binary_expressions = wrap_if_long
+resharper_wrap_chained_binary_patterns = wrap_if_long
+resharper_wrap_chained_method_calls = wrap_if_long
+resharper_wrap_ctor_initializer_style = wrap_if_long
+resharper_wrap_enumeration_style = chop_if_long
+resharper_wrap_enum_declaration = chop_always
+resharper_wrap_extends_list_style = wrap_if_long
+resharper_wrap_for_stmt_header_style = chop_if_long
+resharper_wrap_list_pattern = wrap_if_long
+resharper_wrap_multiple_declaration_style = chop_if_long
+resharper_wrap_multiple_type_parameter_constraints_style = chop_if_long
+resharper_wrap_object_and_collection_initializer_style = chop_if_long
+resharper_wrap_parameters_style = wrap_if_long
+resharper_wrap_property_pattern = chop_if_long
+resharper_wrap_switch_expression = chop_always
+resharper_wrap_ternary_expr_style = chop_if_long
+resharper_wrap_verbatim_interpolated_strings = no_wrap
+resharper_xmldoc_allow_far_alignment = false
+resharper_xmldoc_attribute_indent = single_indent
+resharper_xmldoc_insert_final_newline = false
+resharper_xmldoc_linebreak_before_elements = summary, remarks, example, returns, param, typeparam, value, para
+resharper_xmldoc_max_blank_lines_between_tags = 0
+resharper_xmldoc_max_line_length = 180
+resharper_xmldoc_pi_attribute_style = do_not_touch
+resharper_xmldoc_space_before_self_closing = true
+resharper_xmldoc_wrap_lines = true
+resharper_xmldoc_wrap_tags_and_pi = true
+resharper_xmldoc_wrap_text = true
+resharper_xml_allow_far_alignment = false
+resharper_xml_attribute_indent = align_by_first_attribute
+resharper_xml_insert_final_newline = false
+resharper_xml_linebreak_before_elements = 
+resharper_xml_max_blank_lines_between_tags = 2
+resharper_xml_max_line_length = 180
+resharper_xml_pi_attribute_style = do_not_touch
+resharper_xml_space_before_self_closing = true
+resharper_xml_wrap_lines = true
+resharper_xml_wrap_tags_and_pi = true
+resharper_xml_wrap_text = false
+
+# ReSharper inspection severities
+resharper_access_rights_in_text_highlighting = warning
+resharper_access_to_disposed_closure_highlighting = warning
+resharper_access_to_for_each_variable_in_closure_highlighting = warning
+resharper_access_to_modified_closure_highlighting = warning
+resharper_access_to_static_member_via_derived_type_highlighting = warning
+resharper_address_of_marshal_by_ref_object_highlighting = warning
+resharper_angular_html_banana_highlighting = warning
+resharper_annotate_can_be_null_parameter_highlighting = none
+resharper_annotate_can_be_null_type_member_highlighting = none
+resharper_annotate_not_null_parameter_highlighting = none
+resharper_annotate_not_null_type_member_highlighting = none
+resharper_annotation_conflict_in_hierarchy_highlighting = warning
+resharper_annotation_redundancy_at_value_type_highlighting = warning
+resharper_annotation_redundancy_in_hierarchy_highlighting = warning
+resharper_anonymous_object_destructuring_problem_highlighting = warning
+resharper_arguments_style_anonymous_function_highlighting = none
+resharper_arguments_style_literal_highlighting = none
+resharper_arguments_style_named_expression_highlighting = none
+resharper_arguments_style_other_highlighting = none
+resharper_arguments_style_string_literal_highlighting = none
+resharper_arrange_attributes_highlighting = none
+resharper_arrange_default_value_when_type_evident_highlighting = suggestion
+resharper_arrange_default_value_when_type_not_evident_highlighting = hint
+resharper_arrange_local_function_body_highlighting = none
+resharper_arrange_null_checking_pattern_highlighting = hint
+resharper_arrange_object_creation_when_type_evident_highlighting = suggestion
+resharper_arrange_object_creation_when_type_not_evident_highlighting = hint
+resharper_arrange_redundant_parentheses_highlighting = hint
+resharper_arrange_static_member_qualifier_highlighting = hint
+resharper_arrange_this_qualifier_highlighting = hint
+resharper_arrange_trailing_comma_in_multiline_lists_highlighting = hint
+resharper_arrange_trailing_comma_in_singleline_lists_highlighting = hint
+resharper_arrange_var_keywords_in_deconstructing_declaration_highlighting = suggestion
+resharper_asp_content_placeholder_not_resolved_highlighting = error
+resharper_asp_custom_page_parser_filter_type_highlighting = warning
+resharper_asp_dead_code_highlighting = warning
+resharper_asp_entity_highlighting = warning
+resharper_asp_image_highlighting = warning
+resharper_asp_invalid_control_type_highlighting = error
+resharper_asp_not_resolved_highlighting = error
+resharper_asp_ods_method_reference_resolve_error_highlighting = error
+resharper_asp_resolve_warning_highlighting = warning
+resharper_asp_skin_not_resolved_highlighting = error
+resharper_asp_tag_attribute_with_optional_value_highlighting = warning
+resharper_asp_theme_not_resolved_highlighting = error
+resharper_asp_unused_register_directive_highlighting_highlighting = warning
+resharper_asp_warning_highlighting = warning
+resharper_assignment_in_conditional_expression_highlighting = warning
+resharper_assignment_is_fully_discarded_highlighting = warning
+resharper_assign_null_to_not_null_attribute_highlighting = warning
+resharper_asxx_path_error_highlighting = warning
+resharper_async_iterator_invocation_without_await_foreach_highlighting = warning
+resharper_async_void_lambda_highlighting = warning
+resharper_async_void_method_highlighting = error
+resharper_auto_property_can_be_made_get_only_global_highlighting = suggestion
+resharper_auto_property_can_be_made_get_only_local_highlighting = suggestion
+resharper_bad_attribute_brackets_spaces_highlighting = none
+resharper_bad_braces_spaces_highlighting = none
+resharper_bad_child_statement_indent_highlighting = warning
+resharper_bad_colon_spaces_highlighting = none
+resharper_bad_comma_spaces_highlighting = none
+resharper_bad_control_braces_indent_highlighting = suggestion
+resharper_bad_control_braces_line_breaks_highlighting = none
+resharper_bad_declaration_braces_indent_highlighting = none
+resharper_bad_declaration_braces_line_breaks_highlighting = none
+resharper_bad_empty_braces_line_breaks_highlighting = none
+resharper_bad_expression_braces_indent_highlighting = none
+resharper_bad_expression_braces_line_breaks_highlighting = none
+resharper_bad_generic_brackets_spaces_highlighting = none
+resharper_bad_indent_highlighting = none
+resharper_bad_linq_line_breaks_highlighting = none
+resharper_bad_list_line_breaks_highlighting = none
+resharper_bad_member_access_spaces_highlighting = none
+resharper_bad_namespace_braces_indent_highlighting = none
+resharper_bad_parens_line_breaks_highlighting = none
+resharper_bad_parens_spaces_highlighting = none
+resharper_bad_preprocessor_indent_highlighting = none
+resharper_bad_semicolon_spaces_highlighting = none
+resharper_bad_spaces_after_keyword_highlighting = none
+resharper_bad_square_brackets_spaces_highlighting = none
+resharper_bad_switch_braces_indent_highlighting = none
+resharper_bad_symbol_spaces_highlighting = none
+resharper_base_member_has_params_highlighting = warning
+resharper_base_method_call_with_default_parameter_highlighting = warning
+resharper_base_object_equals_is_object_equals_highlighting = warning
+resharper_base_object_get_hash_code_call_in_get_hash_code_highlighting = warning
+resharper_bitwise_operator_on_enum_without_flags_highlighting = warning
+resharper_blazor_editor_required_highlighting = warning
+resharper_built_in_type_reference_style_for_member_access_highlighting = hint
+resharper_built_in_type_reference_style_highlighting = hint
+resharper_by_ref_argument_is_volatile_field_highlighting = warning
+resharper_cannot_apply_equality_operator_to_type_highlighting = warning
+resharper_can_simplify_dictionary_lookup_with_try_add_highlighting = warning
+resharper_can_simplify_dictionary_lookup_with_try_get_value_highlighting = warning
+resharper_center_tag_is_obsolete_highlighting = warning
+resharper_check_for_reference_equality_instead_1_highlighting = suggestion
+resharper_check_for_reference_equality_instead_2_highlighting = suggestion
+resharper_check_for_reference_equality_instead_3_highlighting = suggestion
+resharper_check_for_reference_equality_instead_4_highlighting = suggestion
+resharper_check_namespace_highlighting = warning
+resharper_class_cannot_be_instantiated_highlighting = warning
+resharper_class_can_be_sealed_global_highlighting = none
+resharper_class_can_be_sealed_local_highlighting = none
+resharper_class_never_instantiated_global_highlighting = suggestion
+resharper_class_never_instantiated_local_highlighting = suggestion
+resharper_class_with_virtual_members_never_inherited_global_highlighting = suggestion
+resharper_class_with_virtual_members_never_inherited_local_highlighting = suggestion
+resharper_clear_attribute_is_obsolete_all_highlighting = warning
+resharper_clear_attribute_is_obsolete_highlighting = warning
+resharper_cognitive_complexity_highlighting = warning
+resharper_collection_never_queried_global_highlighting = warning
+resharper_collection_never_queried_local_highlighting = warning
+resharper_collection_never_updated_global_highlighting = warning
+resharper_collection_never_updated_local_highlighting = warning
+resharper_comment_typo_highlighting = suggestion
+resharper_compare_non_constrained_generic_with_null_highlighting = none
+resharper_compare_of_floats_by_equality_operator_highlighting = warning
+resharper_complex_object_destructuring_problem_highlighting = warning
+resharper_complex_object_in_context_destructuring_problem_highlighting = warning
+resharper_conditional_access_qualifier_is_non_nullable_according_to_api_contract_highlighting = warning
+resharper_conditional_ternary_equal_branch_highlighting = warning
+resharper_condition_is_always_true_or_false_according_to_nullable_api_contract_highlighting = warning
+resharper_condition_is_always_true_or_false_highlighting = warning
+resharper_confusing_char_as_integer_in_constructor_highlighting = warning
+resharper_constant_conditional_access_qualifier_highlighting = warning
+resharper_constant_null_coalescing_condition_highlighting = warning
+resharper_constructor_initializer_loop_highlighting = warning
+resharper_container_annotation_redundancy_highlighting = warning
+resharper_contextual_logger_problem_highlighting = warning
+resharper_context_value_is_provided_highlighting = none
+resharper_contract_annotation_not_parsed_highlighting = warning
+resharper_convert_closure_to_method_group_highlighting = suggestion
+resharper_convert_conditional_ternary_expression_to_switch_expression_highlighting = hint
+resharper_convert_if_do_to_while_highlighting = suggestion
+resharper_convert_if_statement_to_conditional_ternary_expression_highlighting = suggestion
+resharper_convert_if_statement_to_null_coalescing_assignment_highlighting = suggestion
+resharper_convert_if_statement_to_null_coalescing_expression_highlighting = suggestion
+resharper_convert_if_statement_to_return_statement_highlighting = hint
+resharper_convert_if_statement_to_switch_statement_highlighting = hint
+resharper_convert_if_to_or_expression_highlighting = suggestion
+resharper_convert_nullable_to_short_form_highlighting = suggestion
+resharper_convert_switch_statement_to_switch_expression_highlighting = hint
+resharper_convert_to_auto_property_highlighting = suggestion
+resharper_convert_to_auto_property_when_possible_highlighting = hint
+resharper_convert_to_auto_property_with_private_setter_highlighting = hint
+resharper_convert_to_compound_assignment_highlighting = hint
+resharper_convert_to_constant_global_highlighting = hint
+resharper_convert_to_constant_local_highlighting = hint
+resharper_convert_to_lambda_expression_highlighting = suggestion
+resharper_convert_to_local_function_highlighting = suggestion
+resharper_convert_to_null_coalescing_compound_assignment_highlighting = suggestion
+resharper_convert_to_primary_constructor_highlighting = suggestion
+resharper_convert_to_static_class_highlighting = suggestion
+resharper_convert_to_using_declaration_highlighting = suggestion
+resharper_convert_to_vb_auto_property_highlighting = suggestion
+resharper_convert_to_vb_auto_property_when_possible_highlighting = hint
+resharper_convert_to_vb_auto_property_with_private_setter_highlighting = hint
+resharper_convert_type_check_pattern_to_null_check_highlighting = warning
+resharper_convert_type_check_to_null_check_highlighting = none
+resharper_co_variant_array_conversion_highlighting = warning
+public virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualresharper_c_declaration_with_implicit_int_type_highlighting = warning
+resharper_c_sharp_build_cs_invalid_module_name_highlighting = warning
+resharper_c_sharp_missing_plugin_dependency_highlighting = warning
+resharper_default_value_attribute_for_optional_parameter_highlighting = warning
+resharper_double_negation_in_pattern_highlighting = suggestion
+resharper_double_negation_operator_highlighting = suggestion
+resharper_duplicate_resource_highlighting = warning
+resharper_empty_constructor_highlighting = warning
+resharper_empty_destructor_highlighting = warning
+resharper_empty_embedded_statement_highlighting = warning
+resharper_empty_for_statement_highlighting = warning
+resharper_empty_general_catch_clause_highlighting = warning
+resharper_empty_namespace_highlighting = warning
+resharper_empty_region_highlighting = suggestion
+resharper_empty_statement_highlighting = warning
+resharper_empty_title_tag_highlighting = hint
+resharper_enforce_do_while_statement_braces_highlighting = none
+resharper_enforce_fixed_statement_braces_highlighting = none
+resharper_enforce_foreach_statement_braces_highlighting = none
+resharper_enforce_for_statement_braces_highlighting = none
+resharper_enforce_if_statement_braces_highlighting = none
+resharper_enforce_lock_statement_braces_highlighting = none
+resharper_enforce_using_statement_braces_highlighting = none
+resharper_enforce_while_statement_braces_highlighting = none
+resharper_entity_name_captured_only_global_highlighting = warning
+resharper_entity_name_captured_only_local_highlighting = warning
+resharper_enumerable_sum_in_explicit_unchecked_context_highlighting = warning
+resharper_enum_underlying_type_is_int_highlighting = warning
+resharper_equal_expression_comparison_highlighting = warning
+resharper_escaped_keyword_highlighting = warning
+resharper_event_never_invoked_global_highlighting = suggestion
+resharper_event_never_subscribed_to_global_highlighting = suggestion
+resharper_event_never_subscribed_to_local_highlighting = suggestion
+resharper_event_unsubscription_via_anonymous_delegate_highlighting = warning
+resharper_exception_passed_as_template_argument_problem_highlighting = warning
+resharper_explicit_caller_info_argument_highlighting = warning
+resharper_expression_is_always_null_highlighting = warning
+resharper_extract_common_property_pattern_highlighting = hint
+resharper_field_can_be_made_read_only_global_highlighting = suggestion
+resharper_field_can_be_made_read_only_local_highlighting = suggestion
+resharper_field_hides_interface_property_with_default_implementation_highlighting = warning
+resharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlighting = hint
+resharper_foreach_can_be_partly_converted_to_query_using_another_get_enumerator_highlighting = hint
+resharper_format_string_placeholders_mismatch_highlighting = warning
+resharper_format_string_problem_highlighting = warning
+resharper_for_can_be_converted_to_foreach_highlighting = suggestion
+resharper_for_statement_condition_is_true_highlighting = warning
+resharper_function_complexity_overflow_highlighting = none
+resharper_function_never_returns_highlighting = warning
+resharper_function_recursive_on_all_paths_highlighting = warning
+resharper_gc_suppress_finalize_for_type_without_destructor_highlighting = warning
+resharper_generic_enumerator_not_disposed_highlighting = warning
+resharper_heuristic_unreachable_code_highlighting = warning
+resharper_html_attributes_quotes_highlighting = hint
+resharper_html_attribute_not_resolved_highlighting = warning
+resharper_html_attribute_value_not_resolved_highlighting = warning
+resharper_html_dead_code_highlighting = warning
+resharper_html_event_not_resolved_highlighting = warning
+resharper_html_id_duplication_highlighting = warning
+resharper_html_id_not_resolved_highlighting = warning
+resharper_html_obsolete_highlighting = warning
+resharper_html_path_error_highlighting = warning
+resharper_html_tag_not_closed_highlighting = error
+resharper_html_tag_not_resolved_highlighting = warning
+resharper_html_tag_should_be_self_closed_highlighting = warning
+resharper_html_tag_should_not_be_self_closed_highlighting = warning
+resharper_html_warning_highlighting = warning
+resharper_identifier_typo_highlighting = suggestion
+resharper_ignored_directive_highlighting = warning
+resharper_inactive_preprocessor_branch_highlighting = warning
+resharper_inconsistently_synchronized_field_highlighting = warning
+resharper_inconsistent_context_log_property_naming_highlighting = warning
+resharper_inconsistent_log_property_naming_highlighting = warning
+resharper_inconsistent_naming_highlighting = warning
+resharper_inconsistent_order_of_locks_highlighting = warning
+resharper_incorrect_blank_lines_near_braces_highlighting = none
+resharper_indexing_by_invalid_range_highlighting = warning
+resharper_inheritdoc_consider_usage_highlighting = none
+resharper_inheritdoc_invalid_usage_highlighting = warning
+resharper_inline_out_variable_declaration_highlighting = suggestion
+resharper_inline_temporary_variable_highlighting = hint
+resharper_internal_or_private_member_not_documented_highlighting = none
+resharper_interpolated_string_expression_is_not_i_formattable_highlighting = warning
+resharper_introduce_optional_parameters_global_highlighting = suggestion
+resharper_introduce_optional_parameters_local_highlighting = suggestion
+resharper_int_division_by_zero_highlighting = warning
+resharper_int_variable_overflow_highlighting = warning
+resharper_int_variable_overflow_in_checked_context_highlighting = warning
+resharper_int_variable_overflow_in_unchecked_context_highlighting = warning
+resharper_invalid_value_type_highlighting = warning
+resharper_invalid_xml_doc_comment_highlighting = warning
+resharper_invert_condition_1_highlighting = hint
+resharper_invert_if_highlighting = hint
+resharper_invocation_is_skipped_highlighting = hint
+resharper_invoke_as_extension_method_highlighting = suggestion
+resharper_is_expression_always_false_highlighting = warning
+resharper_is_expression_always_true_highlighting = warning
+resharper_iterator_method_result_is_ignored_highlighting = warning
+resharper_iterator_never_returns_highlighting = warning
+resharper_join_declaration_and_initializer_highlighting = suggestion
+resharper_join_null_check_with_usage_highlighting = suggestion
+resharper_lambda_expression_can_be_made_static_highlighting = none
+resharper_lambda_expression_must_be_static_highlighting = suggestion
+resharper_lambda_should_not_capture_context_highlighting = warning
+resharper_localizable_element_highlighting = warning
+resharper_local_function_can_be_made_static_highlighting = none
+resharper_local_function_hides_method_highlighting = warning
+resharper_local_variable_hides_member_highlighting = warning
+resharper_log_message_is_sentence_problem_highlighting = warning
+resharper_long_literal_ending_lower_l_highlighting = warning
+resharper_loop_can_be_converted_to_query_highlighting = hint
+resharper_loop_can_be_partly_converted_to_query_highlighting = none
+resharper_loop_variable_is_never_changed_inside_loop_highlighting = warning
+resharper_markup_attribute_typo_highlighting = suggestion
+resharper_markup_text_typo_highlighting = suggestion
+resharper_math_abs_method_is_redundant_highlighting = warning
+resharper_math_clamp_min_greater_than_max_highlighting = warning
+resharper_meaningless_default_parameter_value_highlighting = warning
+resharper_member_can_be_file_local_highlighting = none
+resharper_member_can_be_internal_highlighting = none
+resharper_member_can_be_made_static_global_highlighting = hint
+resharper_member_can_be_made_static_local_highlighting = hint
+resharper_member_can_be_private_global_highlighting = suggestion
+resharper_member_can_be_private_local_highlighting = suggestion
+resharper_member_can_be_protected_global_highlighting = suggestion
+resharper_member_can_be_protected_local_highlighting = suggestion
+resharper_member_hides_interface_member_with_default_implementation_highlighting = warning
+resharper_member_hides_static_from_outer_class_highlighting = warning
+resharper_member_initializer_value_ignored_highlighting = warning
+resharper_merge_and_pattern_highlighting = suggestion
+resharper_merge_cast_with_type_check_highlighting = suggestion
+resharper_merge_conditional_expression_highlighting = suggestion
+resharper_merge_into_logical_pattern_highlighting = hint
+resharper_merge_into_negated_pattern_highlighting = hint
+resharper_merge_into_pattern_highlighting = suggestion
+resharper_merge_nested_property_patterns_highlighting = suggestion
+resharper_merge_sequential_checks_highlighting = hint
+resharper_method_has_async_overload_highlighting = suggestion
+resharper_method_has_async_overload_with_cancellation_highlighting = suggestion
+resharper_method_overload_with_optional_parameter_highlighting = warning
+resharper_method_supports_cancellation_highlighting = suggestion
+resharper_missing_alt_attribute_in_img_tag_highlighting = hint
+resharper_missing_blank_lines_highlighting = none
+resharper_missing_body_tag_highlighting = warning
+resharper_missing_head_and_body_tags_highlighting = warning
+resharper_missing_head_tag_highlighting = warning
+resharper_missing_indent_highlighting = none
+resharper_missing_linebreak_highlighting = none
+resharper_missing_space_highlighting = none
+resharper_more_specific_foreach_variable_type_available_highlighting = suggestion
+resharper_move_to_existing_positional_deconstruction_pattern_highlighting = hint
+resharper_move_variable_declaration_inside_loop_condition_highlighting = suggestion
+resharper_multiple_nullable_attributes_usage_highlighting = warning
+resharper_multiple_order_by_highlighting = warning
+resharper_multiple_resolve_candidates_in_text_highlighting = warning
+resharper_multiple_spaces_highlighting = none
+resharper_multiple_statements_on_one_line_highlighting = none
+resharper_multiple_type_members_on_one_line_highlighting = none
+resharper_must_use_return_value_highlighting = warning
+resharper_mvc_action_not_resolved_highlighting = error
+resharper_mvc_area_not_resolved_highlighting = error
+resharper_mvc_controller_not_resolved_highlighting = error
+resharper_mvc_invalid_model_type_highlighting = error
+resharper_mvc_masterpage_not_resolved_highlighting = error
+resharper_mvc_partial_view_not_resolved_highlighting = error
+resharper_mvc_template_not_resolved_highlighting = error
+resharper_mvc_view_component_not_resolved_highlighting = error
+resharper_mvc_view_component_view_not_resolved_highlighting = error
+resharper_mvc_view_not_resolved_highlighting = error
+resharper_negation_of_relational_pattern_highlighting = suggestion
+resharper_negative_equality_expression_highlighting = suggestion
+resharper_negative_index_highlighting = warning
+resharper_nested_string_interpolation_highlighting = suggestion
+resharper_non_atomic_compound_operator_highlighting = warning
+resharper_non_constant_equality_expression_has_constant_result_highlighting = warning
+resharper_non_parsable_element_highlighting = warning
+resharper_non_readonly_member_in_get_hash_code_highlighting = warning
+resharper_non_volatile_field_in_double_check_locking_highlighting = warning
+resharper_not_accessed_field_global_highlighting = suggestion
+resharper_not_accessed_field_local_highlighting = warning
+resharper_not_accessed_out_parameter_variable_highlighting = warning
+resharper_not_accessed_positional_property_global_highlighting = warning
+resharper_not_accessed_positional_property_local_highlighting = warning
+resharper_not_accessed_variable_highlighting = warning
+resharper_not_assigned_out_parameter_highlighting = warning
+resharper_not_declared_in_parent_culture_highlighting = warning
+resharper_not_null_or_required_member_is_not_initialized_highlighting = warning
+resharper_not_observable_annotation_redundancy_highlighting = warning
+resharper_not_overridden_in_specific_culture_highlighting = warning
+resharper_not_resolved_in_text_highlighting = warning
+resharper_no_support_for_vb_highlighting = warning
+resharper_nullable_warning_suppression_is_used_highlighting = none
+resharper_null_coalescing_condition_is_always_not_null_according_to_api_contract_highlighting = warning
+resharper_n_unit_async_method_must_be_task_highlighting = warning
+resharper_n_unit_attribute_produces_too_many_tests_highlighting = none
+resharper_n_unit_auto_fixture_incorrect_argument_type_highlighting = warning
+resharper_n_unit_auto_fixture_missed_test_attribute_highlighting = warning
+resharper_n_unit_auto_fixture_missed_test_or_test_fixture_attribute_highlighting = warning
+resharper_n_unit_auto_fixture_redundant_argument_in_inline_auto_data_attribute_highlighting = warning
+resharper_n_unit_duplicate_values_highlighting = warning
+resharper_n_unit_ignored_parameter_attribute_highlighting = warning
+resharper_n_unit_implicit_unspecified_null_values_highlighting = warning
+resharper_n_unit_incorrect_argument_type_highlighting = warning
+resharper_n_unit_incorrect_expected_result_type_highlighting = warning
+resharper_n_unit_incorrect_range_bounds_highlighting = warning
+resharper_n_unit_method_with_parameters_and_test_attribute_highlighting = warning
+resharper_n_unit_missing_arguments_in_test_case_attribute_highlighting = warning
+resharper_n_unit_non_public_method_with_test_attribute_highlighting = warning
+resharper_n_unit_no_values_provided_highlighting = warning
+resharper_n_unit_parameter_type_is_not_compatible_with_attribute_highlighting = warning
+resharper_n_unit_range_attribute_bounds_are_out_of_range_highlighting = warning
+resharper_n_unit_range_step_sign_mismatch_highlighting = warning
+resharper_n_unit_range_step_value_must_not_be_zero_highlighting = warning
+resharper_n_unit_range_to_value_is_not_reachable_highlighting = warning
+resharper_n_unit_redundant_argument_instead_of_expected_result_highlighting = warning
+resharper_n_unit_redundant_argument_in_test_case_attribute_highlighting = warning
+resharper_n_unit_redundant_expected_result_in_test_case_attribute_highlighting = warning
+resharper_n_unit_test_case_attribute_requires_expected_result_highlighting = warning
+resharper_n_unit_test_case_result_property_duplicates_expected_result_highlighting = warning
+resharper_n_unit_test_case_result_property_is_obsolete_highlighting = warning
+resharper_n_unit_test_case_source_cannot_be_resolved_highlighting = warning
+resharper_n_unit_test_case_source_must_be_field_property_method_highlighting = warning
+resharper_n_unit_test_case_source_must_be_static_highlighting = warning
+resharper_n_unit_test_case_source_should_implement_i_enumerable_highlighting = warning
+resharper_object_creation_as_statement_highlighting = warning
+resharper_obsolete_element_error_highlighting = error
+resharper_obsolete_element_highlighting = warning
+resharper_one_way_operation_contract_with_return_type_highlighting = warning
+resharper_operation_contract_without_service_contract_highlighting = warning
+resharper_operator_is_can_be_used_highlighting = warning
+resharper_operator_without_matched_checked_operator_highlighting = warning
+resharper_optional_parameter_hierarchy_mismatch_highlighting = warning
+resharper_optional_parameter_ref_out_highlighting = warning
+resharper_other_tags_inside_script1_highlighting = error
+resharper_other_tags_inside_script2_highlighting = error
+resharper_other_tags_inside_unclosed_script_highlighting = error
+resharper_outdent_is_off_prev_level_highlighting = none
+resharper_out_parameter_value_is_always_discarded_global_highlighting = suggestion
+resharper_out_parameter_value_is_always_discarded_local_highlighting = warning
+resharper_overridden_with_empty_value_highlighting = warning
+resharper_overridden_with_same_value_highlighting = suggestion
+resharper_parameter_hides_member_highlighting = warning
+resharper_parameter_only_used_for_precondition_check_global_highlighting = suggestion
+resharper_parameter_only_used_for_precondition_check_local_highlighting = warning
+resharper_parameter_type_can_be_enumerable_global_highlighting = hint
+resharper_parameter_type_can_be_enumerable_local_highlighting = hint
+resharper_partial_method_parameter_name_mismatch_highlighting = warning
+resharper_partial_method_with_single_part_highlighting = warning
+resharper_partial_type_with_single_part_highlighting = warning
+resharper_pass_string_interpolation_highlighting = hint
+resharper_pattern_always_matches_highlighting = warning
+resharper_pattern_is_always_true_or_false_highlighting = warning
+resharper_pattern_is_redundant_highlighting = warning
+resharper_pattern_never_matches_highlighting = warning
+resharper_place_assignment_expression_into_block_highlighting = none
+resharper_polymorphic_field_like_event_invocation_highlighting = warning
+resharper_positional_property_used_problem_highlighting = warning
+resharper_possible_infinite_inheritance_highlighting = warning
+resharper_possible_intended_rethrow_highlighting = warning
+resharper_possible_interface_member_ambiguity_highlighting = warning
+resharper_possible_invalid_cast_exception_highlighting = warning
+resharper_possible_invalid_cast_exception_in_foreach_loop_highlighting = warning
+resharper_possible_invalid_operation_exception_highlighting = warning
+resharper_possible_loss_of_fraction_highlighting = warning
+resharper_possible_mistaken_argument_highlighting = warning
+resharper_possible_mistaken_call_to_get_type_1_highlighting = warning
+resharper_possible_mistaken_call_to_get_type_2_highlighting = warning
+resharper_possible_multiple_enumeration_highlighting = warning
+resharper_possible_multiple_write_access_in_double_check_locking_highlighting = warning
+resharper_possible_null_reference_exception_highlighting = warning
+resharper_possible_struct_member_modification_of_non_variable_struct_highlighting = warning
+resharper_possible_unintended_linear_search_in_set_highlighting = warning
+resharper_possible_unintended_queryable_as_enumerable_highlighting = suggestion
+resharper_possible_unintended_reference_comparison_highlighting = warning
+resharper_possible_write_to_me_highlighting = warning
+resharper_possibly_impure_method_call_on_readonly_variable_highlighting = warning
+resharper_possibly_missing_indexer_initializer_comma_highlighting = warning
+resharper_possibly_mistaken_use_of_interpolated_string_insert_highlighting = warning
+resharper_private_field_can_be_converted_to_local_variable_highlighting = warning
+resharper_property_can_be_made_init_only_global_highlighting = suggestion
+resharper_property_can_be_made_init_only_local_highlighting = suggestion
+resharper_property_field_keyword_is_never_assigned_highlighting = warning
+resharper_property_field_keyword_is_never_used_highlighting = warning
+resharper_property_not_resolved_highlighting = error
+resharper_public_constructor_in_abstract_class_highlighting = suggestion
+resharper_pure_attribute_on_void_method_highlighting = warning
+resharper_razor_layout_not_resolved_highlighting = error
+resharper_razor_section_not_resolved_highlighting = error
+resharper_read_access_in_double_check_locking_highlighting = warning
+resharper_redundant_abstract_modifier_highlighting = warning
+resharper_redundant_accessor_body_highlighting = suggestion
+resharper_redundant_always_match_subpattern_highlighting = suggestion
+resharper_redundant_anonymous_type_property_name_highlighting = warning
+resharper_redundant_argument_default_value_highlighting = warning
+resharper_redundant_array_creation_expression_highlighting = hint
+resharper_redundant_array_lower_bound_specification_highlighting = warning
+resharper_redundant_assignment_highlighting = warning
+resharper_redundant_attribute_parentheses_highlighting = hint
+resharper_redundant_attribute_suffix_highlighting = warning
+resharper_redundant_attribute_usage_property_highlighting = suggestion
+resharper_redundant_base_constructor_call_highlighting = warning
+resharper_redundant_base_qualifier_highlighting = warning
+resharper_redundant_blank_lines_highlighting = none
+resharper_redundant_bool_compare_highlighting = warning
+resharper_redundant_caller_argument_expression_default_value_highlighting = warning
+resharper_redundant_case_label_highlighting = warning
+resharper_redundant_cast_highlighting = warning
+resharper_redundant_catch_clause_highlighting = warning
+resharper_redundant_check_before_assignment_highlighting = warning
+resharper_redundant_collection_initializer_element_braces_highlighting = hint
+resharper_redundant_configure_await_highlighting = suggestion
+resharper_redundant_declaration_semicolon_highlighting = hint
+resharper_redundant_default_member_initializer_highlighting = warning
+resharper_redundant_delegate_creation_highlighting = warning
+resharper_redundant_dictionary_contains_key_before_adding_highlighting = warning
+resharper_redundant_disable_warning_comment_highlighting = warning
+resharper_redundant_discard_designation_highlighting = suggestion
+resharper_redundant_empty_case_else_highlighting = warning
+resharper_redundant_empty_finally_block_highlighting = warning
+resharper_redundant_empty_object_creation_argument_list_highlighting = hint
+resharper_redundant_empty_object_or_collection_initializer_highlighting = warning
+resharper_redundant_empty_switch_section_highlighting = warning
+resharper_redundant_enumerable_cast_call_highlighting = warning
+resharper_redundant_enum_case_label_for_default_section_highlighting = none
+resharper_redundant_explicit_array_creation_highlighting = warning
+resharper_redundant_explicit_array_size_highlighting = warning
+resharper_redundant_explicit_nullable_creation_highlighting = warning
+resharper_redundant_explicit_params_array_creation_highlighting = suggestion
+resharper_redundant_explicit_positional_property_declaration_highlighting = warning
+resharper_redundant_explicit_tuple_component_name_highlighting = warning
+resharper_redundant_extends_list_entry_highlighting = warning
+resharper_redundant_fixed_pointer_declaration_highlighting = suggestion
+resharper_redundant_if_else_block_highlighting = hint
+resharper_redundant_if_statement_then_keyword_highlighting = none
+resharper_redundant_immediate_delegate_invocation_highlighting = suggestion
+resharper_redundant_include_highlighting = warning
+resharper_redundant_is_before_relational_pattern_highlighting = suggestion
+resharper_redundant_iterator_keyword_highlighting = warning
+resharper_redundant_jump_statement_highlighting = warning
+resharper_redundant_lambda_parameter_type_highlighting = warning
+resharper_redundant_lambda_signature_parentheses_highlighting = hint
+resharper_redundant_linebreak_highlighting = none
+resharper_redundant_logical_conditional_expression_operand_highlighting = warning
+resharper_redundant_me_qualifier_highlighting = warning
+resharper_redundant_my_base_qualifier_highlighting = warning
+resharper_redundant_my_class_qualifier_highlighting = warning
+resharper_redundant_name_qualifier_highlighting = warning
+resharper_redundant_not_null_constraint_highlighting = warning
+resharper_redundant_nullable_annotation_on_reference_type_constraint_highlighting = warning
+resharper_redundant_nullable_annotation_on_type_constraint_has_non_nullable_base_type_highlighting = warning
+resharper_redundant_nullable_annotation_on_type_constraint_has_non_nullable_type_kind_highlighting = warning
+resharper_redundant_nullable_flow_attribute_highlighting = warning
+resharper_redundant_nullable_type_mark_highlighting = warning
+resharper_redundant_nullness_attribute_with_nullable_reference_types_highlighting = warning
+resharper_redundant_overflow_checking_context_highlighting = warning
+resharper_redundant_overload_global_highlighting = suggestion
+resharper_redundant_overload_local_highlighting = suggestion
+resharper_redundant_overridden_member_highlighting = warning
+resharper_redundant_params_highlighting = warning
+resharper_redundant_parentheses_highlighting = none
+resharper_redundant_pattern_parentheses_highlighting = hint
+resharper_redundant_property_parentheses_highlighting = hint
+resharper_redundant_property_pattern_clause_highlighting = suggestion
+resharper_redundant_qualifier_highlighting = warning
+resharper_redundant_query_order_by_ascending_keyword_highlighting = hint
+resharper_redundant_range_bound_highlighting = suggestion
+resharper_redundant_readonly_modifier_highlighting = suggestion
+resharper_redundant_record_body_highlighting = warning
+resharper_redundant_record_class_keyword_highlighting = warning
+resharper_redundant_scoped_parameter_modifier_highlighting = warning
+resharper_redundant_setter_value_parameter_declaration_highlighting = hint
+resharper_redundant_set_contains_before_adding_highlighting = warning
+resharper_redundant_space_highlighting = none
+resharper_redundant_string_format_call_highlighting = warning
+resharper_redundant_string_interpolation_highlighting = suggestion
+resharper_redundant_string_to_char_array_call_highlighting = warning
+resharper_redundant_string_type_highlighting = suggestion
+resharper_redundant_suppress_nullable_warning_expression_highlighting = warning
+resharper_redundant_ternary_expression_highlighting = warning
+resharper_redundant_to_string_call_for_value_type_highlighting = hint
+resharper_redundant_to_string_call_highlighting = warning
+resharper_redundant_type_arguments_of_method_highlighting = warning
+resharper_redundant_type_check_in_pattern_highlighting = warning
+resharper_redundant_unsafe_context_highlighting = warning
+resharper_redundant_using_directive_global_highlighting = warning
+resharper_redundant_using_directive_highlighting = warning
+resharper_redundant_verbatim_prefix_highlighting = suggestion
+resharper_redundant_verbatim_string_prefix_highlighting = suggestion
+resharper_redundant_virtual_modifier_highlighting = warning
+resharper_redundant_with_expression_highlighting = suggestion
+resharper_reference_equals_with_value_type_highlighting = warning
+resharper_reg_exp_inspections_highlighting = warning
+resharper_remove_constructor_invocation_highlighting = none
+resharper_remove_redundant_braces_highlighting = none
+resharper_remove_redundant_or_statement_false_highlighting = suggestion
+resharper_remove_redundant_or_statement_true_highlighting = suggestion
+resharper_remove_to_list_1_highlighting = suggestion
+resharper_remove_to_list_2_highlighting = suggestion
+resharper_replace_auto_property_with_computed_property_highlighting = hint
+resharper_replace_conditional_expression_with_null_coalescing_highlighting = suggestion
+resharper_replace_object_pattern_with_var_pattern_highlighting = suggestion
+resharper_replace_sequence_equal_with_constant_pattern_highlighting = suggestion
+resharper_replace_slice_with_range_indexer_highlighting = hint
+resharper_replace_substring_with_range_indexer_highlighting = hint
+resharper_replace_with_field_keyword_highlighting = suggestion
+resharper_replace_with_first_or_default_1_highlighting = suggestion
+resharper_replace_with_first_or_default_2_highlighting = suggestion
+resharper_replace_with_first_or_default_3_highlighting = suggestion
+resharper_replace_with_first_or_default_4_highlighting = suggestion
+resharper_replace_with_last_or_default_1_highlighting = suggestion
+resharper_replace_with_last_or_default_2_highlighting = suggestion
+resharper_replace_with_last_or_default_3_highlighting = suggestion
+resharper_replace_with_last_or_default_4_highlighting = suggestion
+resharper_replace_with_of_type_1_highlighting = suggestion
+resharper_replace_with_of_type_2_highlighting = suggestion
+resharper_replace_with_of_type_3_highlighting = suggestion
+resharper_replace_with_of_type_any_1_highlighting = suggestion
+resharper_replace_with_of_type_any_2_highlighting = suggestion
+resharper_replace_with_of_type_count_1_highlighting = suggestion
+resharper_replace_with_of_type_count_2_highlighting = suggestion
+resharper_replace_with_of_type_first_1_highlighting = suggestion
+resharper_replace_with_of_type_first_2_highlighting = suggestion
+resharper_replace_with_of_type_first_or_default_1_highlighting = suggestion
+resharper_replace_with_of_type_first_or_default_2_highlighting = suggestion
+resharper_replace_with_of_type_last_1_highlighting = suggestion
+resharper_replace_with_of_type_last_2_highlighting = suggestion
+resharper_replace_with_of_type_last_or_default_1_highlighting = suggestion
+resharper_replace_with_of_type_last_or_default_2_highlighting = suggestion
+resharper_replace_with_of_type_long_count_highlighting = suggestion
+resharper_replace_with_of_type_single_1_highlighting = suggestion
+resharper_replace_with_of_type_single_2_highlighting = suggestion
+resharper_replace_with_of_type_single_or_default_1_highlighting = suggestion
+resharper_replace_with_of_type_single_or_default_2_highlighting = suggestion
+resharper_replace_with_of_type_where_highlighting = suggestion
+resharper_replace_with_simple_assignment_false_highlighting = suggestion
+resharper_replace_with_simple_assignment_true_highlighting = suggestion
+resharper_replace_with_single_assignment_false_highlighting = suggestion
+resharper_replace_with_single_assignment_true_highlighting = suggestion
+resharper_replace_with_single_call_to_any_highlighting = suggestion
+resharper_replace_with_single_call_to_count_highlighting = suggestion
+resharper_replace_with_single_call_to_first_highlighting = suggestion
+resharper_replace_with_single_call_to_first_or_default_highlighting = suggestion
+resharper_replace_with_single_call_to_last_highlighting = suggestion
+resharper_replace_with_single_call_to_last_or_default_highlighting = suggestion
+resharper_replace_with_single_call_to_single_highlighting = suggestion
+resharper_replace_with_single_call_to_single_or_default_highlighting = suggestion
+resharper_replace_with_single_or_default_1_highlighting = suggestion
+resharper_replace_with_single_or_default_2_highlighting = suggestion
+resharper_replace_with_single_or_default_3_highlighting = suggestion
+resharper_replace_with_single_or_default_4_highlighting = suggestion
+resharper_replace_with_string_is_null_or_empty_highlighting = suggestion
+resharper_required_base_types_conflict_highlighting = warning
+resharper_required_base_types_direct_conflict_highlighting = warning
+resharper_required_base_types_is_not_inherited_highlighting = warning
+resharper_resource_item_not_resolved_highlighting = error
+resharper_resource_not_resolved_highlighting = error
+resharper_resx_not_resolved_highlighting = warning
+resharper_return_type_can_be_enumerable_global_highlighting = hint
+resharper_return_type_can_be_enumerable_local_highlighting = hint
+resharper_return_type_can_be_not_nullable_highlighting = warning
+resharper_return_value_of_pure_method_is_not_used_highlighting = warning
+resharper_route_templates_action_route_prefix_can_be_extracted_to_controller_route_highlighting = hint
+resharper_route_templates_ambiguous_matching_constraint_constructor_highlighting = warning
+resharper_route_templates_constraint_argument_cannot_be_converted_highlighting = warning
+resharper_route_templates_controller_route_parameter_is_not_passed_to_methods_highlighting = hint
+resharper_route_templates_duplicated_parameter_highlighting = warning
+resharper_route_templates_matching_constraint_constructor_not_resolved_highlighting = warning
+resharper_route_templates_method_missing_route_parameters_highlighting = hint
+resharper_route_templates_optional_parameter_can_be_preceded_only_by_single_period_highlighting = warning
+resharper_route_templates_optional_parameter_must_be_at_the_end_of_segment_highlighting = warning
+resharper_route_templates_parameter_constraint_can_be_specified_highlighting = hint
+resharper_route_templates_parameter_type_and_constraints_mismatch_highlighting = warning
+resharper_route_templates_parameter_type_can_be_made_stricter_highlighting = suggestion
+resharper_route_templates_route_parameter_constraint_not_resolved_highlighting = warning
+resharper_route_templates_route_parameter_is_not_passed_to_method_highlighting = hint
+resharper_route_templates_route_token_not_resolved_highlighting = warning
+resharper_route_templates_symbol_not_resolved_highlighting = warning
+resharper_route_templates_syntax_error_highlighting = warning
+resharper_safe_cast_is_used_as_type_check_highlighting = suggestion
+resharper_script_tag_has_both_src_and_content_attributes_highlighting = error
+resharper_sealed_member_in_sealed_class_highlighting = warning
+resharper_separate_control_transfer_statement_highlighting = none
+resharper_service_contract_without_operations_highlighting = warning
+resharper_shift_expression_real_shift_count_is_zero_highlighting = warning
+resharper_shift_expression_result_equals_zero_highlighting = warning
+resharper_shift_expression_right_operand_not_equal_real_count_highlighting = warning
+resharper_shift_expression_zero_left_operand_highlighting = warning
+resharper_similar_anonymous_type_nearby_highlighting = hint
+resharper_simplify_conditional_operator_highlighting = suggestion
+resharper_simplify_conditional_ternary_expression_highlighting = suggestion
+resharper_simplify_i_if_highlighting = suggestion
+resharper_simplify_linq_expression_use_all_highlighting = none
+resharper_simplify_linq_expression_use_any_highlighting = suggestion
+resharper_simplify_linq_expression_use_min_by_and_max_by_highlighting = suggestion
+resharper_simplify_string_interpolation_highlighting = suggestion
+resharper_specify_a_culture_in_string_conversion_explicitly_highlighting = warning
+resharper_specify_string_comparison_highlighting = hint
+resharper_spin_lock_in_readonly_field_highlighting = warning
+resharper_stack_alloc_inside_loop_highlighting = warning
+resharper_static_member_initializer_referes_to_member_below_highlighting = warning
+resharper_static_member_in_generic_type_highlighting = warning
+resharper_static_problem_in_text_highlighting = warning
+resharper_string_compare_is_culture_specific_1_highlighting = warning
+resharper_string_compare_is_culture_specific_2_highlighting = warning
+resharper_string_compare_is_culture_specific_3_highlighting = warning
+resharper_string_compare_is_culture_specific_4_highlighting = warning
+resharper_string_compare_is_culture_specific_5_highlighting = warning
+resharper_string_compare_is_culture_specific_6_highlighting = warning
+resharper_string_compare_to_is_culture_specific_highlighting = warning
+resharper_string_ends_with_is_culture_specific_highlighting = none
+resharper_string_index_of_is_culture_specific_1_highlighting = warning
+resharper_string_index_of_is_culture_specific_2_highlighting = warning
+resharper_string_index_of_is_culture_specific_3_highlighting = warning
+resharper_string_last_index_of_is_culture_specific_1_highlighting = warning
+resharper_string_last_index_of_is_culture_specific_2_highlighting = warning
+resharper_string_last_index_of_is_culture_specific_3_highlighting = warning
+resharper_string_literal_as_interpolation_argument_highlighting = suggestion
+resharper_string_literal_typo_highlighting = suggestion
+resharper_string_starts_with_is_culture_specific_highlighting = none
+resharper_structured_message_template_problem_highlighting = warning
+resharper_struct_can_be_made_read_only_highlighting = suggestion
+resharper_struct_member_can_be_made_read_only_highlighting = none
+resharper_suggest_base_type_for_parameter_highlighting = hint
+resharper_suggest_base_type_for_parameter_in_constructor_highlighting = hint
+resharper_suggest_discard_declaration_var_style_highlighting = hint
+resharper_suggest_var_or_type_built_in_types_highlighting = hint
+resharper_suggest_var_or_type_deconstruction_declarations_highlighting = hint
+resharper_suggest_var_or_type_elsewhere_highlighting = hint
+resharper_suggest_var_or_type_simple_types_highlighting = hint
+resharper_suppress_nullable_warning_expression_as_inverted_is_expression_highlighting = warning
+resharper_suspicious_lock_over_synchronization_primitive_highlighting = warning
+resharper_suspicious_math_sign_method_highlighting = warning
+resharper_suspicious_parameter_name_in_argument_null_exception_highlighting = warning
+resharper_suspicious_type_conversion_global_highlighting = warning
+resharper_swap_via_deconstruction_highlighting = suggestion
+resharper_switch_expression_handles_some_known_enum_values_with_exception_in_default_highlighting = hint
+resharper_switch_statement_for_enum_misses_default_section_highlighting = hint
+resharper_switch_statement_handles_some_known_enum_values_with_default_highlighting = hint
+resharper_switch_statement_missing_some_enum_cases_no_default_highlighting = hint
+resharper_symbol_from_not_copied_locally_reference_used_warning_highlighting = warning
+resharper_tabs_and_spaces_mismatch_highlighting = none
+resharper_tabs_are_disallowed_highlighting = none
+resharper_tabs_outside_indent_highlighting = none
+resharper_tail_recursive_call_highlighting = hint
+resharper_template_duplicate_property_problem_highlighting = warning
+resharper_template_format_string_problem_highlighting = warning
+resharper_template_is_not_compile_time_constant_problem_highlighting = warning
+resharper_thread_static_at_instance_field_highlighting = warning
+resharper_thread_static_field_has_initializer_highlighting = warning
+resharper_too_wide_local_variable_scope_highlighting = suggestion
+resharper_try_cast_always_succeeds_highlighting = suggestion
+resharper_try_statements_can_be_merged_highlighting = hint
+resharper_type_parameter_can_be_variant_highlighting = suggestion
+resharper_unassigned_field_global_highlighting = suggestion
+resharper_unassigned_field_local_highlighting = warning
+resharper_unassigned_get_only_auto_property_highlighting = warning
+resharper_unassigned_readonly_field_highlighting = warning
+resharper_unclosed_script_highlighting = error
+resharper_unexpected_attribute_highlighting = warning
+resharper_unexpected_directive_highlighting = warning
+resharper_unnecessary_whitespace_highlighting = none
+resharper_unreachable_switch_arm_due_to_integer_analysis_highlighting = warning
+resharper_unreachable_switch_case_due_to_integer_analysis_highlighting = warning
+resharper_unreal_header_tool_error_highlighting = error
+resharper_unreal_header_tool_warning_highlighting = warning
+resharper_unsupported_required_base_type_highlighting = warning
+resharper_unused_anonymous_method_signature_highlighting = warning
+resharper_unused_auto_property_accessor_global_highlighting = warning
+resharper_unused_auto_property_accessor_local_highlighting = warning
+resharper_unused_import_clause_highlighting = warning
+resharper_unused_local_function_highlighting = warning
+resharper_unused_local_function_parameter_highlighting = warning
+resharper_unused_local_function_return_value_highlighting = warning
+resharper_unused_member_global_highlighting = suggestion
+resharper_unused_member_hierarchy_global_highlighting = suggestion
+resharper_unused_member_hierarchy_local_highlighting = warning
+resharper_unused_member_in_super_global_highlighting = suggestion
+resharper_unused_member_in_super_local_highlighting = warning
+resharper_unused_member_local_highlighting = warning
+resharper_unused_method_return_value_global_highlighting = suggestion
+resharper_unused_method_return_value_local_highlighting = warning
+resharper_unused_parameter_global_highlighting = suggestion
+resharper_unused_parameter_in_partial_method_highlighting = warning
+resharper_unused_parameter_local_highlighting = warning
+resharper_unused_tuple_component_in_return_value_highlighting = warning
+resharper_unused_type_global_highlighting = suggestion
+resharper_unused_type_local_highlighting = warning
+resharper_unused_type_parameter_highlighting = warning
+resharper_unused_variable_highlighting = warning
+resharper_useless_binary_operation_highlighting = warning
+resharper_useless_comparison_to_integral_constant_highlighting = warning
+resharper_use_array_creation_expression_1_highlighting = suggestion
+resharper_use_array_creation_expression_2_highlighting = suggestion
+resharper_use_array_empty_method_highlighting = suggestion
+resharper_use_await_using_highlighting = suggestion
+resharper_use_cancellation_token_for_i_async_enumerable_highlighting = suggestion
+resharper_use_collection_count_property_highlighting = suggestion
+resharper_use_configure_await_false_for_async_disposable_highlighting = none
+resharper_use_configure_await_false_highlighting = suggestion
+resharper_use_deconstruction_highlighting = hint
+resharper_use_empty_types_field_highlighting = suggestion
+resharper_use_event_args_empty_field_highlighting = suggestion
+resharper_use_format_specifier_in_format_string_highlighting = suggestion
+resharper_use_implicitly_typed_variable_evident_highlighting = hint
+resharper_use_implicitly_typed_variable_highlighting = none
+resharper_use_implicit_by_val_modifier_highlighting = hint
+resharper_use_indexed_property_highlighting = suggestion
+resharper_use_index_from_end_expression_highlighting = suggestion
+resharper_use_is_operator_1_highlighting = suggestion
+resharper_use_is_operator_2_highlighting = suggestion
+resharper_use_method_any_0_highlighting = suggestion
+resharper_use_method_any_1_highlighting = suggestion
+resharper_use_method_any_2_highlighting = suggestion
+resharper_use_method_any_3_highlighting = suggestion
+resharper_use_method_any_4_highlighting = suggestion
+resharper_use_method_is_instance_of_type_highlighting = suggestion
+resharper_use_nameof_expression_for_part_of_the_string_highlighting = none
+resharper_use_nameof_expression_highlighting = suggestion
+resharper_use_nameof_for_dependency_property_highlighting = suggestion
+resharper_use_name_of_instead_of_type_of_highlighting = suggestion
+resharper_use_negated_pattern_in_is_expression_highlighting = hint
+resharper_use_negated_pattern_matching_highlighting = hint
+resharper_use_nullable_annotation_instead_of_attribute_highlighting = suggestion
+resharper_use_nullable_attributes_supported_by_compiler_highlighting = suggestion
+resharper_use_nullable_reference_types_annotation_syntax_highlighting = warning
+resharper_use_null_propagation_highlighting = hint
+resharper_use_object_or_collection_initializer_highlighting = suggestion
+resharper_use_pattern_matching_highlighting = suggestion
+resharper_use_positional_deconstruction_pattern_highlighting = none
+resharper_use_string_interpolation_highlighting = suggestion
+resharper_use_string_interpolation_when_possible_highlighting = hint
+resharper_use_switch_case_pattern_variable_highlighting = suggestion
+resharper_use_throw_if_null_method_highlighting = none
+resharper_use_unsigned_right_shift_operator_highlighting = suggestion
+resharper_use_verbatim_string_highlighting = hint
+resharper_use_with_expression_to_copy_anonymous_object_highlighting = suggestion
+resharper_use_with_expression_to_copy_record_highlighting = suggestion
+resharper_use_with_expression_to_copy_struct_highlighting = suggestion
+resharper_use_with_expression_to_copy_tuple_highlighting = suggestion
+resharper_value_parameter_not_used_highlighting = warning
+resharper_value_range_attribute_violation_highlighting = warning
+resharper_variable_can_be_not_nullable_highlighting = warning
+resharper_variable_hides_outer_variable_highlighting = warning
+public virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualpublic virtualresharper_virtual_member_call_in_constructor_highlighting = warning
+resharper_virtual_member_never_overridden_global_highlighting = suggestion
+resharper_virtual_member_never_overridden_local_highlighting = suggestion
+resharper_void_method_with_must_use_return_value_attribute_highlighting = warning
+resharper_web_config_module_not_resolved_highlighting = warning
+resharper_web_config_module_qualification_resolve_highlighting = warning
+resharper_web_config_redundant_add_namespace_tag_highlighting = warning
+resharper_web_config_redundant_location_tag_highlighting = warning
+resharper_web_config_tag_prefix_redundand_highlighting = warning
+resharper_web_config_type_not_resolved_highlighting = warning
+resharper_web_config_unused_add_tag_highlighting = warning
+resharper_web_config_unused_element_due_to_config_source_attribute_highlighting = warning
+resharper_web_config_unused_remove_or_clear_tag_highlighting = warning
+resharper_web_config_web_config_path_warning_highlighting = warning
+resharper_web_config_wrong_module_highlighting = warning
+resharper_web_ignored_path_highlighting = none
+resharper_web_mapped_path_highlighting = hint
+resharper_with_expression_instead_of_initializer_highlighting = suggestion
+resharper_with_expression_modifies_all_members_highlighting = warning
+resharper_wrong_indent_size_highlighting = none
+resharper_xaml_assign_null_to_not_null_attribute_highlighting = warning
+resharper_xaml_avalonia_wrong_binding_mode_for_stream_binding_operator_highlighting = warning
+resharper_xaml_binding_without_context_not_resolved_highlighting = hint
+resharper_xaml_binding_with_context_not_resolved_highlighting = warning
+resharper_xaml_compiled_binding_missing_data_type_error_highlighting_highlighting = error
+resharper_xaml_constructor_warning_highlighting = warning
+resharper_xaml_decimal_parsing_is_culture_dependent_highlighting = warning
+resharper_xaml_dependency_property_resolve_error_highlighting = warning
+resharper_xaml_duplicate_style_setter_highlighting = warning
+resharper_xaml_dynamic_resource_error_highlighting = error
+resharper_xaml_element_name_reference_not_resolved_highlighting = error
+resharper_xaml_empty_grid_length_definition_highlighting = error
+resharper_xaml_field_modifier_requires_name_attribute_highlighting = warning
+resharper_xaml_grid_definitions_can_be_converted_to_attribute_highlighting = hint
+resharper_xaml_ignored_path_highlighting_highlighting = none
+resharper_xaml_index_out_of_grid_definition_highlighting = warning
+resharper_xaml_invalid_member_type_highlighting = error
+resharper_xaml_invalid_resource_target_type_highlighting = error
+resharper_xaml_invalid_resource_type_highlighting = error
+resharper_xaml_invalid_type_highlighting = error
+resharper_xaml_language_level_highlighting = error
+resharper_xaml_mapped_path_highlighting_highlighting = hint
+resharper_xaml_method_arguments_will_be_ignored_highlighting = warning
+resharper_xaml_missing_grid_index_highlighting = warning
+resharper_xaml_overloads_collision_highlighting = warning
+resharper_xaml_parent_is_out_of_current_component_tree_highlighting = warning
+resharper_xaml_path_error_highlighting = warning
+resharper_xaml_possible_null_reference_exception_highlighting = suggestion
+resharper_xaml_redundant_attached_property_highlighting = warning
+resharper_xaml_redundant_binding_mode_attribute_highlighting = warning
+resharper_xaml_redundant_collection_property_highlighting = warning
+resharper_xaml_redundant_freeze_attribute_highlighting = warning
+resharper_xaml_redundant_grid_definitions_highlighting = warning
+resharper_xaml_redundant_grid_span_highlighting = warning
+resharper_xaml_redundant_modifiers_attribute_highlighting = warning
+resharper_xaml_redundant_namespace_alias_highlighting = warning
+resharper_xaml_redundant_name_attribute_highlighting = warning
+resharper_xaml_redundant_property_type_qualifier_highlighting = warning
+resharper_xaml_redundant_resource_highlighting = warning
+resharper_xaml_redundant_styled_value_highlighting = warning
+resharper_xaml_redundant_update_source_trigger_attribute_highlighting = warning
+resharper_xaml_redundant_xamarin_forms_class_declaration_highlighting = warning
+resharper_xaml_resource_file_path_case_mismatch_highlighting = warning
+resharper_xaml_routed_event_resolve_error_highlighting = warning
+resharper_xaml_static_resource_not_resolved_highlighting = warning
+resharper_xaml_style_class_not_found_highlighting = warning
+resharper_xaml_style_invalid_target_type_highlighting = error
+resharper_xaml_unexpected_element_highlighting = error
+resharper_xaml_unexpected_text_token_highlighting = error
+resharper_xaml_xaml_duplicate_device_family_type_view_highlighting_highlighting = error
+resharper_xaml_xaml_mismatched_device_family_view_clr_name_highlighting_highlighting = warning
+resharper_xaml_xaml_relative_source_default_mode_warning_highlighting_highlighting = warning
+resharper_xaml_xaml_unknown_device_family_type_highlighting_highlighting = warning
+resharper_xaml_xaml_xamarin_forms_data_type_and_binding_context_type_mismatched_highlighting_highlighting = warning
+resharper_xaml_x_key_attribute_disallowed_highlighting = error
+resharper_xunit_xunit_test_with_console_output_highlighting = warning
+resharper_zero_index_from_end_highlighting = warning
+
+# ReSharper properties
+resharper_csharp_int_align_comments = true
+
+[*.html]
+indent_size = 4
+tab_width = 4
+indent_style = space
+ij_html_do_not_indent_children_of_tags = 
\ No newline at end of file
diff --git a/ExampleBots/LibMatrix.ExampleBot b/ExampleBots/LibMatrix.ExampleBot
new file mode 160000
+Subproject ecda7b17dfd83d787bc12d7194103d20cd4a835
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs
deleted file mode 100644
index e690890..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/CmdCommand.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using ArcaneLibs.StringNormalisation;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.ExampleBot.Bot.Interfaces;
-
-namespace LibMatrix.ExampleBot.Bot.Commands;
-
-public class CmdCommand : ICommand {
-    public string Name => "cmd";
-    public string Description => "Runs a command on the host system";
-
-    public Task<bool> CanInvoke(CommandContext ctx) {
-        return Task.FromResult(ctx.MessageEvent.Sender.EndsWith(":rory.gay") || ctx.MessageEvent.Sender.EndsWith(":conduit.rory.gay"));
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        var cmd = ctx.Args.Aggregate("\"", (current, arg) => current + arg + " ");
-
-        cmd = cmd.Trim();
-        cmd += "\"";
-
-        await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent(body: $"Command being executed: `{cmd}`"));
-
-        var output = ArcaneLibs.Util.GetCommandOutputAsync(
-            Environment.OSVersion.Platform == PlatformID.Unix ? "/bin/sh" : "cmd.exe",
-            (Environment.OSVersion.Platform == PlatformID.Unix ? "-c " : "/c ") + cmd);
-        // .Replace("`", "\\`")
-        // .Split("\n").ToList();
-
-        var msg = "";
-        EventIdResponse? msgId = await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent {
-            FormattedBody = $"Waiting for command output...",
-            Body = msg.RemoveAnsi(),
-            Format = "m.notice"
-        });
-
-        var lastSendTask = Task.CompletedTask;
-        await foreach (var @out in output) {
-            Console.WriteLine($"{@out.Length:0000} {@out}");
-            msg += @out + "\n";
-            if (lastSendTask.IsCompleted)
-                lastSendTask = ctx.Room.SendMessageEventAsync(new RoomMessageEventContent {
-                    FormattedBody = $"<pre class=\"language-csharp\">\n{msg}\n</pre>",
-                    Body = msg.RemoveAnsi(),
-                    Format = "org.matrix.custom.html"
-                });
-            if (msg.Length > 31000) {
-                await lastSendTask;
-                msgId = await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent {
-                    FormattedBody = $"Waiting for command output...",
-                    Body = msg.RemoveAnsi(),
-                    Format = "m.notice"
-                });
-                msg = "";
-            }
-        }
-
-        // while (output.Count > 0) {
-        //     Console.WriteLine("Adding: " + output[0]);
-        //     msg += output[0] + "\n";
-        //     output.RemoveAt(0);
-        //     if ((output.Count > 0 && (msg + output[0]).Length > 31500) || output.Count == 0) {
-        //         await ctx.Room.SendMessageEventAsync("m.room.message", new RoomMessageEventContent {
-        //             FormattedBody = $"<pre class=\"language-csharp\">\n{msg}\n</pre>",
-        //             // Body = Markdig.Markdown.ToHtml(msg),
-        //             Body = msg.RemoveAnsi(),
-        //             Format = "org.matrix.custom.html"
-        //         });
-        //         msg = "";
-        //     }
-        // }
-    }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/HelpCommand.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/HelpCommand.cs
deleted file mode 100644
index 23c4fe2..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/HelpCommand.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Text;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.ExampleBot.Bot.Interfaces;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace LibMatrix.ExampleBot.Bot.Commands;
-
-public class HelpCommand(IServiceProvider services) : ICommand {
-    public string Name { get; } = "help";
-    public string Description { get; } = "Displays this help message";
-
-    public async Task Invoke(CommandContext ctx) {
-        var sb = new StringBuilder();
-        sb.AppendLine("Available commands:");
-        var commands = services.GetServices<ICommand>().ToList();
-        foreach (var command in commands) {
-            sb.AppendLine($"- {command.Name}: {command.Description}");
-        }
-
-        await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent(body: sb.ToString()));
-    }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/PingCommand.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/PingCommand.cs
deleted file mode 100644
index ba242fe..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/Commands/PingCommand.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.ExampleBot.Bot.Interfaces;
-
-namespace LibMatrix.ExampleBot.Bot.Commands;
-
-public class PingCommand : ICommand {
-    public string Name { get; } = "ping";
-    public string Description { get; } = "Pong!";
-
-    public async Task Invoke(CommandContext ctx) {
-        await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent(body: "pong!"));
-    }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs
deleted file mode 100644
index 2c014de..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/FileStorageProvider.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Text.Json;
-using ArcaneLibs.Extensions;
-using LibMatrix.Interfaces.Services;
-using Microsoft.Extensions.Logging;
-
-namespace LibMatrix.ExampleBot.Bot;
-
-public class FileStorageProvider : IStorageProvider {
-    private readonly ILogger<FileStorageProvider> _logger;
-
-    public string TargetPath { get; }
-
-    /// <summary>
-    /// Creates a new instance of <see cref="FileStorageProvider" />.
-    /// </summary>
-    /// <param name="targetPath"></param>
-    public FileStorageProvider(string targetPath) {
-        new Logger<FileStorageProvider>(new LoggerFactory()).LogInformation("test");
-        Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}");
-        TargetPath = targetPath;
-        if (!Directory.Exists(targetPath)) {
-            Directory.CreateDirectory(targetPath);
-        }
-    }
-
-    public async Task SaveObjectAsync<T>(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson());
-
-    public async Task<T?> LoadObjectAsync<T>(string key) => JsonSerializer.Deserialize<T>(await File.ReadAllTextAsync(Path.Join(TargetPath, key)));
-
-    public Task<bool> ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key)));
-
-    public Task<List<string>> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList());
-
-    public Task DeleteObjectAsync(string key) {
-        File.Delete(Path.Join(TargetPath, key));
-        return Task.CompletedTask;
-    }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs
deleted file mode 100644
index 6dbb7f9..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/CommandContext.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.RoomTypes;
-
-namespace LibMatrix.ExampleBot.Bot.Interfaces;
-
-public class CommandContext {
-    public GenericRoom Room { get; set; }
-    public StateEventResponse MessageEvent { get; set; }
-    public string CommandName => (MessageEvent.TypedContent as RoomMessageEventContent).Body.Split(' ')[0][1..];
-    public string[] Args => (MessageEvent.TypedContent as RoomMessageEventContent).Body.Split(' ')[1..];
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/ICommand.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/ICommand.cs
deleted file mode 100644
index 2ba5a27..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/Interfaces/ICommand.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace LibMatrix.ExampleBot.Bot.Interfaces;
-
-public interface ICommand {
-    public string Name { get; }
-    public string Description { get; }
-
-    public Task<bool> CanInvoke(CommandContext ctx) {
-        return Task.FromResult(true);
-    }
-
-    public Task Invoke(CommandContext ctx);
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/RMUBot.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/RMUBot.cs
deleted file mode 100644
index de47ec6..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/RMUBot.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-using ArcaneLibs.Extensions;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.EventTypes.Spec.State;
-using LibMatrix.ExampleBot.Bot.Interfaces;
-using LibMatrix.Helpers;
-using LibMatrix.Homeservers;
-using LibMatrix.Services;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-
-namespace LibMatrix.ExampleBot.Bot;
-
-public class RMUBot : IHostedService {
-    private readonly HomeserverProviderService _homeserverProviderService;
-    private readonly ILogger<RMUBot> _logger;
-    private readonly RMUBotConfiguration _configuration;
-    private readonly IEnumerable<ICommand> _commands;
-
-    public RMUBot(HomeserverProviderService homeserverProviderService, ILogger<RMUBot> logger,
-        RMUBotConfiguration configuration, IServiceProvider services) {
-        logger.LogInformation("{} instantiated!", this.GetType().Name);
-        _homeserverProviderService = homeserverProviderService;
-        _logger = logger;
-        _configuration = configuration;
-        _logger.LogInformation("Getting commands...");
-        _commands = services.GetServices<ICommand>();
-        _logger.LogInformation("Got {} commands!", _commands.Count());
-    }
-
-    /// <summary>Triggered when the application host is ready to start the service.</summary>
-    /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
-    [SuppressMessage("ReSharper", "FunctionNeverReturns")]
-    public async Task StartAsync(CancellationToken cancellationToken) {
-        Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete);
-        AuthenticatedHomeserverGeneric hs;
-        try {
-            hs = await _homeserverProviderService.GetAuthenticatedWithToken(_configuration.Homeserver,
-                _configuration.AccessToken);
-        }
-        catch (Exception e) {
-            _logger.LogError("{}", e.Message);
-            throw;
-        }
-
-        var syncHelper = new SyncHelper(hs);
-
-        await (hs.GetRoom("!DoHEdFablOLjddKWIp:rory.gay")).JoinAsync();
-
-        // foreach (var room in await hs.GetJoinedRooms()) {
-        //     if(room.RoomId is "!OGEhHVWSdvArJzumhm:matrix.org") continue;
-        //     foreach (var stateEvent in await room.GetStateAsync<List<StateEvent>>("")) {
-        //         var _ = stateEvent.GetType;
-        //     }
-        //     _logger.LogInformation($"Got room state for {room.RoomId}!");
-        // }
-
-        syncHelper.InviteReceivedHandlers.Add(async Task (args) => {
-            var inviteEvent =
-                args.Value.InviteState.Events.FirstOrDefault(x =>
-                    x.Type == "m.room.member" && x.StateKey == hs.UserId);
-            _logger.LogInformation(
-                $"Got invite to {args.Key} by {inviteEvent.Sender} with reason: {(inviteEvent.TypedContent as RoomMemberEventContent).Reason}");
-            if (inviteEvent.Sender.EndsWith(":rory.gay") || inviteEvent.Sender == "@mxidupwitch:the-apothecary.club") {
-                try {
-                    var senderProfile = await hs.GetProfileAsync(inviteEvent.Sender);
-                    await (hs.GetRoom(args.Key)).JoinAsync(reason: $"I was invited by {senderProfile.DisplayName ?? inviteEvent.Sender}!");
-                }
-                catch (Exception e) {
-                    _logger.LogError("{}", e.ToString());
-                    await (hs.GetRoom(args.Key)).LeaveAsync(reason: "I was unable to join the room: " + e);
-                }
-            }
-        });
-        syncHelper.TimelineEventHandlers.Add(async @event => {
-            _logger.LogInformation(
-                "Got timeline event in {}: {}", @event.RoomId, @event.ToJson(indent: false, ignoreNull: true));
-
-            var room = hs.GetRoom(@event.RoomId);
-            // _logger.LogInformation(eventResponse.ToJson(indent: false));
-            if (@event is { Type: "m.room.message", TypedContent: RoomMessageEventContent message }) {
-                if (message is { MessageType: "m.text" } && message.Body.StartsWith(_configuration.Prefix)) {
-                    var command = _commands.FirstOrDefault(x => x.Name == message.Body.Split(' ')[0][_configuration.Prefix.Length..]);
-                    if (command == null) {
-                        await room.SendMessageEventAsync(
-                            new RoomMessageEventContent(messageType: "m.text", body: "Command not found!"));
-                        return;
-                    }
-
-                    var ctx = new CommandContext {
-                        Room = room,
-                        MessageEvent = @event
-                    };
-                    if (await command.CanInvoke(ctx)) {
-                        await command.Invoke(ctx);
-                    }
-                    else {
-                        await room.SendMessageEventAsync(
-                            new RoomMessageEventContent(messageType: "m.text", body: "You do not have permission to run this command!"));
-                    }
-                }
-            }
-        });
-        await syncHelper.RunSyncLoopAsync(cancellationToken: cancellationToken);
-    }
-
-    /// <summary>Triggered when the application host is performing a graceful shutdown.</summary>
-    /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
-    public Task StopAsync(CancellationToken cancellationToken) {
-        _logger.LogInformation("Shutting down bot!");
-        return Task.CompletedTask;
-    }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/RMUBotConfiguration.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/RMUBotConfiguration.cs
deleted file mode 100644
index 9edc4bd..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/RMUBotConfiguration.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Microsoft.Extensions.Configuration;
-
-namespace LibMatrix.ExampleBot.Bot;
-
-public class RMUBotConfiguration {
-    public RMUBotConfiguration(IConfiguration config) {
-        config.GetRequiredSection("Bot").Bind(this);
-    }
-    public string Homeserver { get; set; } = "";
-    public string AccessToken { get; set; } = "";
-    public string Prefix { get; set; }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs
deleted file mode 100644
index 0645668..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/StartupTasks/ServerRoomSizeCalulator.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-using LibMatrix.ExampleBot.Bot.Interfaces;
-using LibMatrix.Homeservers;
-using LibMatrix.Services;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-
-namespace LibMatrix.ExampleBot.Bot.StartupTasks;
-
-public class ServerRoomSizeCalulator : IHostedService {
-    private readonly HomeserverProviderService _homeserverProviderService;
-    private readonly ILogger<ServerRoomSizeCalulator> _logger;
-    private readonly RMUBotConfiguration _configuration;
-    private readonly IEnumerable<ICommand> _commands;
-
-    public ServerRoomSizeCalulator(HomeserverProviderService homeserverProviderService, ILogger<ServerRoomSizeCalulator> logger,
-        RMUBotConfiguration configuration, IServiceProvider services) {
-        logger.LogInformation("Server room size calculator hosted service instantiated!");
-        _homeserverProviderService = homeserverProviderService;
-        _logger = logger;
-        _configuration = configuration;
-    }
-
-    /// <summary>Triggered when the application host is ready to start the service.</summary>
-    /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
-    [SuppressMessage("ReSharper", "FunctionNeverReturns")]
-    public async Task StartAsync(CancellationToken cancellationToken) {
-        Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete);
-        AuthenticatedHomeserverGeneric hs;
-        try {
-            hs = await _homeserverProviderService.GetAuthenticatedWithToken(_configuration.Homeserver,
-                _configuration.AccessToken);
-        }
-        catch (Exception e) {
-            _logger.LogError("{}", e.Message);
-            throw;
-        }
-
-        await (hs.GetRoom("!DoHEdFablOLjddKWIp:rory.gay")).JoinAsync();
-
-        Dictionary<string, int> totalRoomSize = new();
-        foreach (var room in await hs.GetJoinedRooms()) {
-            var stateList = room.GetFullStateAsync().ToBlockingEnumerable().ToList();
-            var roomSize = stateList.Count;
-            if (roomSize > 10000) {
-                await File.AppendAllLinesAsync("large_rooms.txt", new[] { $"{{ \"{room.RoomId}\", {roomSize} }}," }, cancellationToken);
-            }
-
-            var roomHs = room.RoomId.Split(":")[1];
-            if (totalRoomSize.ContainsKey(roomHs)) {
-                totalRoomSize[roomHs] += roomSize;
-            }
-            else {
-                totalRoomSize.Add(roomHs, roomSize);
-            }
-
-            _logger.LogInformation($"Got room state for {room.RoomId}!");
-        }
-
-        await File.WriteAllTextAsync("server_size.txt", string.Join('\n', totalRoomSize.Select(x => $"{{ \"{x.Key}\", {x.Value} }},")), cancellationToken);
-    }
-
-    /// <summary>Triggered when the application host is performing a graceful shutdown.</summary>
-    /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
-    public Task StopAsync(CancellationToken cancellationToken) {
-        _logger.LogInformation("Shutting down bot!");
-        return Task.CompletedTask;
-    }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj b/ExampleBots/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj
deleted file mode 100644
index 4088d1d..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/LibMatrix.ExampleBot.csproj
+++ /dev/null
@@ -1,32 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">

-

-  <PropertyGroup>

-    <OutputType>Exe</OutputType>

-    <TargetFramework>net8.0</TargetFramework>

-    <LangVersion>preview</LangVersion>

-    <ImplicitUsings>enable</ImplicitUsings>

-    <Nullable>enable</Nullable>

-    <PublishAot>false</PublishAot>

-    <InvariantGlobalization>true</InvariantGlobalization>

-<!--    <PublishTrimmed>true</PublishTrimmed>-->

-<!--    <PublishReadyToRun>true</PublishReadyToRun>-->

-<!--    <PublishSingleFile>true</PublishSingleFile>-->

-<!--    <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings>-->

-<!--    <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison>-->

-<!--    <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings>-->

-  </PropertyGroup>

-

-  <ItemGroup>

-      <ProjectReference Include="..\..\LibMatrix\LibMatrix.csproj" />

-  </ItemGroup>

-

-  <ItemGroup>

-    <PackageReference Include="ArcaneLibs.StringNormalisation" Version="1.0.0-preview7205256004.28c0e5a" />

-    <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />

-  </ItemGroup>

-  <ItemGroup>

-    <Content Include="appsettings*.json">

-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>

-    </Content>

-  </ItemGroup>

-</Project>

diff --git a/ExampleBots/LibMatrix.ExampleBot/Program.cs b/ExampleBots/LibMatrix.ExampleBot/Program.cs
deleted file mode 100644
index 86d7598..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Program.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// See https://aka.ms/new-console-template for more information
-
-using ArcaneLibs;
-using LibMatrix.ExampleBot.Bot;
-using LibMatrix.ExampleBot.Bot.Interfaces;
-using LibMatrix.Services;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-Console.WriteLine("Hello, World!");
-
-var host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => {
-    services.AddScoped<TieredStorageService>(x =>
-        new TieredStorageService(
-            cacheStorageProvider: new FileStorageProvider("bot_data/cache/"),
-            dataStorageProvider: new FileStorageProvider("bot_data/data/")
-        )
-    );
-    services.AddScoped<RMUBotConfiguration>();
-    services.AddRoryLibMatrixServices();
-    foreach (var commandClass in new ClassCollector<ICommand>().ResolveFromAllAccessibleAssemblies()) {
-        Console.WriteLine($"Adding command {commandClass.Name}");
-        services.AddScoped(typeof(ICommand), commandClass);
-    }
-
-    // services.AddHostedService<ServerRoomSizeCalulator>();
-    services.AddHostedService<RMUBot>();
-}).UseConsoleLifetime().Build();
-
-await host.RunAsync();
diff --git a/ExampleBots/LibMatrix.ExampleBot/Properties/launchSettings.json b/ExampleBots/LibMatrix.ExampleBot/Properties/launchSettings.json
deleted file mode 100644
index 997e294..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/Properties/launchSettings.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "$schema": "http://json.schemastore.org/launchsettings.json",
-  "profiles": {
-    "Default": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-
-      }
-    },
-    "Development": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-        "DOTNET_ENVIRONMENT": "Development"
-      }
-    },
-    "Local config": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-        "DOTNET_ENVIRONMENT": "Local"
-      }
-    }
-  }
-}
diff --git a/ExampleBots/LibMatrix.ExampleBot/appsettings.Development.json b/ExampleBots/LibMatrix.ExampleBot/appsettings.Development.json
deleted file mode 100644
index 27bbd50..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/appsettings.Development.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "Logging": {
-        "LogLevel": {
-            "Default": "Debug",
-            "System": "Information",
-            "Microsoft": "Information"
-        }
-    }
-}
\ No newline at end of file
diff --git a/ExampleBots/LibMatrix.ExampleBot/appsettings.json b/ExampleBots/LibMatrix.ExampleBot/appsettings.json
deleted file mode 100644
index 5668b53..0000000
--- a/ExampleBots/LibMatrix.ExampleBot/appsettings.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "Logging": {
-        "LogLevel": {
-            "Default": "Debug",
-            "System": "Information",
-            "Microsoft": "Information"
-        }
-    },
-    "Bot": {
-        "Homeserver": "rory.gay",
-        "AccessToken": "syt_xxxxxxxxxxxxxxxxx"
-    }
-}
\ No newline at end of file
diff --git a/ExampleBots/ModerationBot b/ExampleBots/ModerationBot
new file mode 160000
+Subproject ee6e58970f62fa19d04f07d06d6c1476bf7e278
diff --git a/ExampleBots/ModerationBot/AccountData/BotData.cs b/ExampleBots/ModerationBot/AccountData/BotData.cs
deleted file mode 100644
index ab680c2..0000000
--- a/ExampleBots/ModerationBot/AccountData/BotData.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace ModerationBot.AccountData;
-
-public class BotData {
-    [JsonPropertyName("control_room")]
-    public string ControlRoom { get; set; } = "";
-
-    [JsonPropertyName("log_room")]
-    public string? LogRoom { get; set; } = "";
-
-    [JsonPropertyName("default_policy_room")]
-    public string? DefaultPolicyRoom { get; set; }
-}
diff --git a/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs b/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs
deleted file mode 100644
index 535fd4f..0000000
--- a/ExampleBots/ModerationBot/Commands/BanMediaCommand.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System.Security.Cryptography;
-using ArcaneLibs.Extensions;
-using LibMatrix;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.Helpers;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-using ModerationBot.StateEventTypes.Policies.Implementations;
-
-namespace ModerationBot.Commands;
-
-public class BanMediaCommand(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "banmedia";
-    public string Description { get; } = "Create a policy banning a piece of media, must be used in reply to a message";
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var policyRoom = ctx.Homeserver.GetRoom(botData.DefaultPolicyRoom ?? botData.ControlRoom);
-        var logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-
-        //check if reply
-        var messageContent = ctx.MessageEvent.TypedContent as RoomMessageEventContent;
-        if (messageContent?.RelatesTo is { InReplyTo: not null }) {
-            try {
-                await logRoom.SendMessageEventAsync(
-                    new RoomMessageEventContent(
-                        body: $"User {MessageFormatter.HtmlFormatMention(ctx.MessageEvent.Sender)} is trying to ban media {messageContent!.RelatesTo!.InReplyTo!.EventId}",
-                        messageType: "m.text"));
-
-                //get replied message
-                var repliedMessage = await ctx.Room.GetEventAsync<StateEventResponse>(messageContent.RelatesTo!.InReplyTo!.EventId);
-
-                //check if recommendation is in list
-                if (ctx.Args.Length < 2) {
-                    await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatError("You must specify a recommendation type and reason!"));
-                    return;
-                }
-
-                var recommendation = ctx.Args[0];
-
-                if (recommendation is not ("ban" or "kick" or "mute" or "redact" or "spoiler" or "warn" or "warn_admins")) {
-                    await ctx.Room.SendMessageEventAsync(
-                        MessageFormatter.FormatError(
-                            $"Invalid recommendation type {recommendation}, must be `warn_admins`, `warn`, `spoiler`, `redact`, `mute`, `kick` or `ban`!"));
-                    return;
-                }
-
-                //hash file
-                var mxcUri = (repliedMessage.TypedContent as RoomMessageEventContent).Url!;
-                var resolvedUri = await hsResolver.ResolveMediaUri(mxcUri.Split('/')[2], mxcUri);
-                var hashAlgo = SHA3_256.Create();
-                var uriHash = hashAlgo.ComputeHash(mxcUri.AsBytes().ToArray());
-                byte[]? fileHash = null;
-
-                try {
-                    fileHash = await hashAlgo.ComputeHashAsync(await ctx.Homeserver.ClientHttpClient.GetStreamAsync(resolvedUri));
-                }
-                catch (Exception ex) {
-                    await logRoom.SendMessageEventAsync(
-                        MessageFormatter.FormatException($"Error calculating file hash for {mxcUri} via {mxcUri.Split('/')[2]}, retrying via {ctx.Homeserver.BaseUrl}...",
-                            ex));
-                    try {
-                        resolvedUri = await hsResolver.ResolveMediaUri(ctx.Homeserver.BaseUrl, mxcUri);
-                        fileHash = await hashAlgo.ComputeHashAsync(await ctx.Homeserver.ClientHttpClient.GetStreamAsync(resolvedUri));
-                    }
-                    catch (Exception ex2) {
-                        await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatException("Error calculating file hash", ex2));
-                        await logRoom.SendMessageEventAsync(
-                            MessageFormatter.FormatException($"Error calculating file hash via {ctx.Homeserver.BaseUrl}!", ex2));
-                    }
-                }
-
-                MediaPolicyFile policy;
-                await policyRoom.SendStateEventAsync("gay.rory.moderation.rule.media", Guid.NewGuid().ToString(), policy = new MediaPolicyFile {
-                    Entity = Convert.ToBase64String(uriHash),
-                    FileHash = Convert.ToBase64String(fileHash),
-                    Reason = string.Join(' ', ctx.Args[1..]),
-                    Recommendation = recommendation,
-                });
-
-                await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatSuccessJson("Media policy created", policy));
-                await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccessJson("Media policy created", policy));
-            }
-            catch (Exception e) {
-                await logRoom.SendMessageEventAsync(MessageFormatter.FormatException("Error creating policy", e));
-                await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatException("Error creating policy", e));
-                await using var stream = new MemoryStream(e.ToString().AsBytes().ToArray());
-                await logRoom.SendFileAsync("error.log.cs", stream);
-            }
-        }
-        else {
-            await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatError("This command must be used in reply to a message!"));
-        }
-    }
-}
diff --git a/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs b/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs
deleted file mode 100644
index cd0bf6b..0000000
--- a/ExampleBots/ModerationBot/Commands/DbgAllRoomsArePolicyListsCommand.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.Helpers;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class DbgAllRoomsArePolicyListsCommand
-    (IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "dbg-allroomsarepolicy";
-    public string Description { get; } = "[Debug] mark all rooms as trusted policy rooms";
-    private GenericRoom logRoom { get; set; }
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-// #if !DEBUG
-//         return false;
-// #endif
-
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-
-        var joinedRooms = await ctx.Homeserver.GetJoinedRooms();
-
-        await ctx.Homeserver.SetAccountDataAsync("gay.rory.moderation_bot.policy_lists", joinedRooms.ToDictionary(x => x.RoomId, x => new PolicyList() {
-            Trusted = true
-        }));
-
-        await engine.ReloadActivePolicyLists();
-    }
-
-    private async Task<bool> JoinRoom(GenericRoom memberRoom, string reason, List<string> servers) {
-        try {
-            await memberRoom.JoinAsync(servers.ToArray(), reason);
-            await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Joined room {memberRoom.RoomId}"));
-        }
-        catch (Exception e) {
-            await logRoom.SendMessageEventAsync(MessageFormatter.FormatException($"Failed to join {memberRoom.RoomId}", e));
-        }
-
-        return true;
-    }
-}
diff --git a/ExampleBots/ModerationBot/Commands/DbgAniRainbowTest.cs b/ExampleBots/ModerationBot/Commands/DbgAniRainbowTest.cs
deleted file mode 100644
index b2216d1..0000000
--- a/ExampleBots/ModerationBot/Commands/DbgAniRainbowTest.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Diagnostics;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.Helpers;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class DbgAniRainbowTest(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "dbg-ani-rainbow";
-    public string Description { get; } = "[Debug] animated rainbow :)";
-    private GenericRoom logRoom { get; set; }
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-        return ctx.Room.RoomId == "!DoHEdFablOLjddKWIp:rory.gay";
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        //255 long string
-        // var rainbow = "🟥🟧🟨🟩🟦🟪";
-        var rainbow = "M";
-        var chars = rainbow;
-        for (var i = 0; i < 76; i++) {
-            chars += rainbow[i%rainbow.Length];
-        }
-
-        var msg = new MessageBuilder(msgType: "m.notice").WithRainbowString(chars).Build();
-        var msgEvent = await ctx.Room.SendMessageEventAsync(msg);
-        
-        Task.Run(async () => {
-
-            int i = 0;
-            while (true) {
-                msg = new MessageBuilder(msgType: "m.notice").WithRainbowString(chars, offset: i+=5).Build();
-                    // .SetReplaceRelation<RoomMessageEventContent>(msgEvent.EventId);
-                // msg.Body = "";
-                // msg.FormattedBody = "";
-                var sw = Stopwatch.StartNew();
-                await ctx.Room.SendMessageEventAsync(msg);
-                await Task.Delay(sw.Elapsed);
-            }
-            
-        });
-
-    }
-}
\ No newline at end of file
diff --git a/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs b/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs
deleted file mode 100644
index 285d792..0000000
--- a/ExampleBots/ModerationBot/Commands/DbgDumpActivePoliciesCommand.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using ArcaneLibs.Extensions;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class DbgDumpActivePoliciesCommand
-    (IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "dbg-dumppolicies";
-    public string Description { get; } = "[Debug] Dump all active policies";
-    private GenericRoom logRoom { get; set; }
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-#if !DEBUG
-        return false;
-#endif
-
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        await ctx.Room.SendFileAsync("all.json", new MemoryStream(engine.ActivePolicies.ToJson().AsBytes().ToArray()), contentType: "application/json");
-        await ctx.Room.SendFileAsync("by-type.json", new MemoryStream(engine.ActivePoliciesByType.ToJson().AsBytes().ToArray()), contentType: "application/json");
-    }
-}
diff --git a/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs b/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs
deleted file mode 100644
index 7563cac..0000000
--- a/ExampleBots/ModerationBot/Commands/DbgDumpAllStateTypesCommand.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using ArcaneLibs.Extensions;
-using LibMatrix;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class DbgDumpAllStateTypesCommand
-    (IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "dbg-dumpstatetypes";
-    public string Description { get; } = "[Debug] Dump all state types we can find";
-    private GenericRoom logRoom { get; set; }
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-#if !DEBUG
-        return false;
-#endif
-
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-
-
-        var joinedRooms = await ctx.Homeserver.GetJoinedRooms();
-
-        var tasks = joinedRooms.Select(GetStateTypes).ToAsyncEnumerable();
-        await foreach (var (room, (raw, html)) in tasks) {
-            await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent("m.text") {
-                Body = $"States for {room.RoomId}:\n{raw}",
-                FormattedBody = $"States for {room.RoomId}:\n{html}",
-                Format = "org.matrix.custom.html"
-            });
-        }
-    }
-
-    private async Task<(GenericRoom room, (string raw, string html))> GetStateTypes(GenericRoom memberRoom) {
-        var states = await memberRoom.GetFullStateAsListAsync();
-
-        return (memberRoom, SummariseStateTypeCounts(states));
-    }
-
-    private static (string Raw, string Html) SummariseStateTypeCounts(IList<StateEventResponse> states) {
-        string raw = "Count | State type | Mapped type", html = "<table><tr><th>Count</th><th>State type</th><th>Mapped type</th></tr>";
-        var groupedStates = states.GroupBy(x => x.Type).ToDictionary(x => x.Key, x => x.ToList()).OrderByDescending(x => x.Value.Count);
-        foreach (var (type, stateGroup) in groupedStates) {
-            raw += $"{stateGroup.Count} | {type} | {StateEvent.GetStateEventType(stateGroup[0].Type).Name}";
-            html += $"<tr><td>{stateGroup.Count}</td><td>{type}</td><td>{StateEvent.GetStateEventType(stateGroup[0].Type).Name}</td></tr>";
-        }
-
-        html += "</table>";
-        return (raw, html);
-    }
-}
diff --git a/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs b/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs
deleted file mode 100644
index eb22a70..0000000
--- a/ExampleBots/ModerationBot/Commands/JoinRoomCommand.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.Helpers;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class JoinRoomCommand(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "join";
-    public string Description { get; } = "Join arbitrary rooms";
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var policyRoom = ctx.Homeserver.GetRoom(botData.DefaultPolicyRoom ?? botData.ControlRoom);
-        var logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-
-        await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Joining room {ctx.Args[0]} with reason: {string.Join(' ', ctx.Args[1..])}"));
-        var roomId = ctx.Args[0];
-        var servers = new List<string>() { ctx.Homeserver.ServerName };
-        if (roomId.StartsWith('[')) {
-
-        }
-
-        if (roomId.StartsWith('#')) {
-            var res = await ctx.Homeserver.ResolveRoomAliasAsync(roomId);
-            roomId = res.RoomId;
-            servers.AddRange(servers);
-        }
-
-        await ctx.Homeserver.JoinRoomAsync(roomId, servers, string.Join(' ', ctx.Args[1..]));
-        await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Resolved room {ctx.Args[0]} to {roomId} with servers: {string.Join(", ", servers)}"));
-    }
-}
diff --git a/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs b/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs
deleted file mode 100644
index 6564e71..0000000
--- a/ExampleBots/ModerationBot/Commands/JoinSpaceMembersCommand.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using ArcaneLibs.Extensions;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.Helpers;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class JoinSpaceMembersCommand(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "joinspacemembers";
-    public string Description { get; } = "Join all rooms in space";
-    private GenericRoom logRoom { get; set; }
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-        var currentRooms = (await ctx.Homeserver.GetJoinedRooms()).Select(x=>x.RoomId).ToList();
-
-        await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Joining space children of {ctx.Args[0]} with reason: {string.Join(' ', ctx.Args[1..])}"));
-        var roomId = ctx.Args[0];
-        var servers = new List<string>() { ctx.Homeserver.ServerName };
-        if (roomId.StartsWith('[')) {
-
-        }
-
-        if (roomId.StartsWith('#')) {
-            var res = await ctx.Homeserver.ResolveRoomAliasAsync(roomId);
-            roomId = res.RoomId;
-            servers.AddRange(servers);
-        }
-
-        var room = ctx.Homeserver.GetRoom(roomId);
-        var tasks = new List<Task<bool>>();
-        await foreach (var memberRoom in room.AsSpace.GetChildrenAsync()) {
-            if (currentRooms.Contains(memberRoom.RoomId)) continue;
-            servers.Add(room.RoomId.Split(':', 2)[1]);
-            servers = servers.Distinct().ToList();
-            tasks.Add(JoinRoom(memberRoom, string.Join(' ', ctx.Args[1..]), servers));
-        }
-
-        await foreach (var b in tasks.ToAsyncEnumerable()) {
-            await Task.Delay(50);
-        }
-    }
-
-    private async Task<bool> JoinRoom(GenericRoom memberRoom, string reason, List<string> servers) {
-        try {
-            var resp = await memberRoom.JoinAsync(servers.ToArray(), reason, checkIfAlreadyMember: false);
-            await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Joined room {memberRoom.RoomId} (resp={resp.RoomId})"));
-        }
-        catch (Exception e) {
-            await logRoom.SendMessageEventAsync(MessageFormatter.FormatException($"Failed to join {memberRoom.RoomId}", e));
-        }
-
-        return true;
-    }
-}
diff --git a/ExampleBots/ModerationBot/Commands/ReloadPoliciesCommand.cs b/ExampleBots/ModerationBot/Commands/ReloadPoliciesCommand.cs
deleted file mode 100644
index b876145..0000000
--- a/ExampleBots/ModerationBot/Commands/ReloadPoliciesCommand.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.Helpers;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using ModerationBot.AccountData;
-
-namespace ModerationBot.Commands;
-
-public class ReloadPoliciesCommand(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver, PolicyEngine engine) : ICommand {
-    public string Name { get; } = "reloadpolicies";
-    public string Description { get; } = "Reload policies";
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-        if (ctx.MessageEvent.Sender == "@cadence:cadence.moe") return true;
-        //check if user is admin in control room
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
-        var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasStatePermission(ctx.MessageEvent.Sender, "m.room.ban");
-        if (!isAdmin) {
-            // await ctx.Reply("You do not have permission to use this command!");
-            await ctx.Homeserver.GetRoom(botData.LogRoom!).SendMessageEventAsync(
-                new RoomMessageEventContent(body: $"User {ctx.MessageEvent.Sender} tried to use command {Name} but does not have permission!", messageType: "m.text"));
-        }
-
-        return isAdmin;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-
-        var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        var policyRoom = ctx.Homeserver.GetRoom(botData.DefaultPolicyRoom ?? botData.ControlRoom);
-        var logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-        
-        await logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Reloading policy lists due to manual invocation!!!!"));
-        await engine.ReloadActivePolicyLists();
-    }
-}
diff --git a/ExampleBots/ModerationBot/FirstRunTasks.cs b/ExampleBots/ModerationBot/FirstRunTasks.cs
deleted file mode 100644
index 9dece1d..0000000
--- a/ExampleBots/ModerationBot/FirstRunTasks.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using LibMatrix;
-using LibMatrix.Homeservers;
-using LibMatrix.Responses;
-using ModerationBot.AccountData;
-
-namespace ModerationBot;
-
-public class FirstRunTasks {
-    public static async Task<BotData> ConstructBotData(AuthenticatedHomeserverGeneric hs, ModerationBotConfiguration configuration, BotData? botdata) {
-        botdata ??= new BotData();
-        var creationContent = CreateRoomRequest.CreatePrivate(hs, name: "Rory&::ModerationBot - Control room", roomAliasName: "moderation-bot-control-room");
-        creationContent.Invite = configuration.Admins;
-        creationContent.CreationContent["type"] = "gay.rory.moderation_bot.control_room";
-
-        if (botdata.ControlRoom is null)
-            try {
-                botdata.ControlRoom = (await hs.CreateRoom(creationContent)).RoomId;
-            }
-            catch (Exception e) {
-                if (e is not MatrixException { ErrorCode: "M_ROOM_IN_USE" }) {
-                    Console.WriteLine(e);
-                    throw;
-                }
-
-                creationContent.RoomAliasName += $"-{Guid.NewGuid()}";
-                botdata.ControlRoom = (await hs.CreateRoom(creationContent)).RoomId;
-            }
-        //set access rules to allow joining via control room
-        // creationContent.InitialState.Add(new StateEvent {
-        //     Type = "m.room.join_rules",
-        //     StateKey = "",
-        //     TypedContent = new RoomJoinRulesEventContent {
-        //         JoinRule = "knock_restricted",
-        //         Allow = new() {
-        //             new RoomJoinRulesEventContent.AllowEntry {
-        //                 Type = "m.room_membership",
-        //                 RoomId = botdata.ControlRoom
-        //             }
-        //         }
-        //     }
-        // });
-
-        creationContent.Name = "Rory&::ModerationBot - Log room";
-        creationContent.RoomAliasName = "moderation-bot-log-room";
-        creationContent.CreationContent["type"] = "gay.rory.moderation_bot.log_room";
-
-        if (botdata.LogRoom is null)
-            try {
-                botdata.LogRoom = (await hs.CreateRoom(creationContent)).RoomId;
-            }
-            catch (Exception e) {
-                if (e is not MatrixException { ErrorCode: "M_ROOM_IN_USE" }) {
-                    Console.WriteLine(e);
-                    throw;
-                }
-
-                creationContent.RoomAliasName += $"-{Guid.NewGuid()}";
-                botdata.LogRoom = (await hs.CreateRoom(creationContent)).RoomId;
-            }
-
-        creationContent.Name = "Rory&::ModerationBot - Policy room";
-        creationContent.RoomAliasName = "moderation-bot-policy-room";
-        creationContent.CreationContent["type"] = "gay.rory.moderation_bot.policy_room";
-
-        if (botdata.DefaultPolicyRoom is null)
-            try {
-                botdata.DefaultPolicyRoom = (await hs.CreateRoom(creationContent)).RoomId;
-            }
-            catch (Exception e) {
-                if (e is not MatrixException { ErrorCode: "M_ROOM_IN_USE" }) {
-                    Console.WriteLine(e);
-                    throw;
-                }
-
-                creationContent.RoomAliasName += $"-{Guid.NewGuid()}";
-                botdata.DefaultPolicyRoom = (await hs.CreateRoom(creationContent)).RoomId;
-            }
-
-        await hs.SetAccountDataAsync("gay.rory.moderation_bot_data", botdata);
-
-        return botdata;
-    }
-}
diff --git a/ExampleBots/ModerationBot/ModerationBot.cs b/ExampleBots/ModerationBot/ModerationBot.cs
deleted file mode 100644
index 2424eee..0000000
--- a/ExampleBots/ModerationBot/ModerationBot.cs
+++ /dev/null
@@ -1,303 +0,0 @@
-using ArcaneLibs.Extensions;
-using LibMatrix;
-using LibMatrix.EventTypes;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.EventTypes.Spec.State;
-using LibMatrix.EventTypes.Spec.State.Policy;
-using LibMatrix.Helpers;
-using LibMatrix.Homeservers;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using ModerationBot.AccountData;
-using ModerationBot.StateEventTypes.Policies;
-
-namespace ModerationBot;
-
-public class ModerationBot(AuthenticatedHomeserverGeneric hs, ILogger<ModerationBot> logger, ModerationBotConfiguration configuration, PolicyEngine engine) : IHostedService {
-    private Task _listenerTask;
-
-    // private GenericRoom _policyRoom;
-    private GenericRoom? _logRoom;
-    private GenericRoom? _controlRoom;
-
-    /// <summary>Triggered when the application host is ready to start the service.</summary>
-    /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
-    public async Task StartAsync(CancellationToken cancellationToken) {
-        _listenerTask = Run(cancellationToken);
-        logger.LogInformation("Bot started!");
-    }
-
-    private async Task Run(CancellationToken cancellationToken) {
-        return;
-        if (Directory.Exists("bot_data/cache"))
-            Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete);
-
-        BotData botData;
-
-        try {
-            logger.LogInformation("Fetching bot account data...");
-            botData = await hs.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-            logger.LogInformation("Got bot account data...");
-        }
-        catch (Exception e) {
-            logger.LogInformation("Could not fetch bot account data... {}", e.Message);
-            if (e is not MatrixException { ErrorCode: "M_NOT_FOUND" }) {
-                logger.LogError("{}", e.ToString());
-                throw;
-            }
-
-            botData = null;
-        }
-
-        botData = await FirstRunTasks.ConstructBotData(hs, configuration, botData);
-
-        // _policyRoom = hs.GetRoom(botData.PolicyRoom ?? botData.ControlRoom);
-        _logRoom = hs.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-        _controlRoom = hs.GetRoom(botData.ControlRoom);
-        foreach (var configurationAdmin in configuration.Admins) {
-            var pls = await _controlRoom.GetPowerLevelsAsync();
-            if (pls is null) {
-                await _logRoom?.SendMessageEventAsync(MessageFormatter.FormatWarning($"Control room has no m.room.power_levels?"));
-                continue;
-            }
-            pls.SetUserPowerLevel(configurationAdmin, pls.GetUserPowerLevel(hs.UserId));
-            await _controlRoom.SendStateEventAsync(RoomPowerLevelEventContent.EventId, pls);
-        }
-        var syncHelper = new SyncHelper(hs);
-
-        List<string> admins = new();
-
-#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
-        Task.Run(async () => {
-            while (!cancellationToken.IsCancellationRequested) {
-                var controlRoomMembers = _controlRoom.GetMembersEnumerableAsync();
-                var pls = await _controlRoom.GetPowerLevelsAsync();
-                await foreach (var member in controlRoomMembers) {
-                    if ((member.TypedContent as RoomMemberEventContent)?
-                        .Membership == "join" && pls.UserHasTimelinePermission(member.Sender, RoomMessageEventContent.EventId)) admins.Add(member.StateKey);
-                }
-
-                await Task.Delay(TimeSpan.FromMinutes(5), cancellationToken);
-            }
-        }, cancellationToken);
-#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
-
-        syncHelper.InviteReceivedHandlers.Add(async Task (args) => {
-            var inviteEvent =
-                args.Value.InviteState.Events.FirstOrDefault(x =>
-                    x.Type == "m.room.member" && x.StateKey == hs.UserId);
-            logger.LogInformation("Got invite to {RoomId} by {Sender} with reason: {Reason}", args.Key, inviteEvent!.Sender,
-                (inviteEvent.TypedContent as RoomMemberEventContent)!.Reason);
-            await _logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Bot invited to {MessageFormatter.HtmlFormatMention(args.Key)} by {MessageFormatter.HtmlFormatMention(inviteEvent.Sender)}"));
-            if (admins.Contains(inviteEvent.Sender)) {
-                try {
-                    await _logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Joining {MessageFormatter.HtmlFormatMention(args.Key)}..."));
-                    var senderProfile = await hs.GetProfileAsync(inviteEvent.Sender);
-                    await hs.GetRoom(args.Key).JoinAsync(reason: $"I was invited by {senderProfile.DisplayName ?? inviteEvent.Sender}!");
-                }
-                catch (Exception e) {
-                    logger.LogError("{}", e.ToString());
-                    await _logRoom.SendMessageEventAsync(MessageFormatter.FormatException("Could not join room", e));
-                    await hs.GetRoom(args.Key).LeaveAsync(reason: "I was unable to join the room: " + e);
-                }
-            }
-        });
-
-        syncHelper.TimelineEventHandlers.Add(async @event => {
-            var room = hs.GetRoom(@event.RoomId);
-            try {
-                logger.LogInformation(
-                    "Got timeline event in {}: {}", @event.RoomId, @event.ToJson(indent: true, ignoreNull: true));
-
-                if (@event != null && (
-                        @event.MappedType.IsAssignableTo(typeof(BasePolicy))
-                        || @event.MappedType.IsAssignableTo(typeof(PolicyRuleEventContent))
-                    )) {
-                    await LogPolicyChange(@event);
-                    await engine.ReloadActivePolicyListById(@event.RoomId);
-                }
-
-                var rules = await engine.GetMatchingPolicies(@event);
-                foreach (var matchedRule in rules) {
-                    await _logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccessJson(
-                        $"{MessageFormatter.HtmlFormatMessageLink(eventId: @event.EventId, roomId: room.RoomId, displayName: "Event")} matched {MessageFormatter.HtmlFormatMessageLink(eventId: @matchedRule.OriginalEvent.EventId, roomId: matchedRule.PolicyList.Room.RoomId, displayName: "rule")}", @matchedRule.OriginalEvent.RawContent));
-                }
-
-                if (configuration.DemoMode) {
-                    // foreach (var matchedRule in rules) {
-                    // await room.SendMessageEventAsync(MessageFormatter.FormatSuccessJson(
-                    // $"{MessageFormatter.HtmlFormatMessageLink(eventId: @event.EventId, roomId: room.RoomId, displayName: "Event")} matched {MessageFormatter.HtmlFormatMessageLink(eventId: @matchedRule.EventId, roomId: matchedRule.RoomId, displayName: "rule")}", @matchedRule.RawContent));
-                    // }
-                    return;
-                }
-                //
-                //                 if (@event is { Type: "m.room.message", TypedContent: RoomMessageEventContent message }) {
-                //                     if (message is { MessageType: "m.image" }) {
-                //                         //check media
-                //                         // var matchedPolicy = await CheckMedia(@event);
-                //                         var matchedPolicy = rules.FirstOrDefault();
-                //                         if (matchedPolicy is null) return;
-                //                         var matchedpolicyData = matchedPolicy.TypedContent as MediaPolicyEventContent;
-                //                         await _logRoom.SendMessageEventAsync(
-                //                             new RoomMessageEventContent(
-                //                                 body:
-                //                                 $"User {MessageFormatter.HtmlFormatMention(@event.Sender)} posted an image in {MessageFormatter.HtmlFormatMention(room.RoomId)} that matched rule {matchedPolicy.StateKey}, applying action {matchedpolicyData.Recommendation}, as described in rule: {matchedPolicy.RawContent!.ToJson(ignoreNull: true)}",
-                //                                 messageType: "m.text") {
-                //                                 Format = "org.matrix.custom.html",
-                //                                 FormattedBody =
-                //                                     $"<font color=\"#FFFF00\">User {MessageFormatter.HtmlFormatMention(@event.Sender)} posted an image in {MessageFormatter.HtmlFormatMention(room.RoomId)} that matched rule {matchedPolicy.StateKey}, applying action {matchedpolicyData.Recommendation}, as described in rule: <pre>{matchedPolicy.RawContent!.ToJson(ignoreNull: true)}</pre></font>"
-                //                             });
-                //                         switch (matchedpolicyData.Recommendation) {
-                //                             case "warn_admins": {
-                //                                 await _controlRoom.SendMessageEventAsync(
-                //                                     new RoomMessageEventContent(
-                //                                         body: $"{string.Join(' ', admins)}\nUser {MessageFormatter.HtmlFormatMention(@event.Sender)} posted a banned image {message.Url}",
-                //                                         messageType: "m.text") {
-                //                                         Format = "org.matrix.custom.html",
-                //                                         FormattedBody = $"{string.Join(' ', admins.Select(u => MessageFormatter.HtmlFormatMention(u)))}\n" +
-                //                                                         $"<font color=\"#FF0000\">User {MessageFormatter.HtmlFormatMention(@event.Sender)} posted a banned image <a href=\"{message.Url}\">{message.Url}</a></font>"
-                //                                     });
-                //                                 break;
-                //                             }
-                //                             case "warn": {
-                //                                 await room.SendMessageEventAsync(
-                //                                     new RoomMessageEventContent(
-                //                                         body: $"Please be careful when posting this image: {matchedpolicyData.Reason ?? "No reason specified"}",
-                //                                         messageType: "m.text") {
-                //                                         Format = "org.matrix.custom.html",
-                //                                         FormattedBody =
-                //                                             $"<font color=\"#FFFF00\">Please be careful when posting this image: {matchedpolicyData.Reason ?? "No reason specified"}</a></font>"
-                //                                     });
-                //                                 break;
-                //                             }
-                //                             case "redact": {
-                //                                 await room.RedactEventAsync(@event.EventId, matchedpolicyData.Reason ?? "No reason specified");
-                //                                 break;
-                //                             }
-                //                             case "spoiler": {
-                //                                 // <blockquote>
-                //                                 //  <a href=\"https://matrix.to/#/@emma:rory.gay\">@emma:rory.gay</a><br>
-                //                                 //  <a href=\"https://codeberg.org/crimsonfork/CN\"></a>
-                //                                 //  <font color=\"#dc143c\" data-mx-color=\"#dc143c\">
-                //                                 //      <b>CN</b>
-                //                                 //  </font>:
-                //                                 //  <a href=\"https://the-apothecary.club/_matrix/media/v3/download/rory.gay/sLkdxUhipiQaFwRkXcPSRwdg\">test</a><br>
-                //                                 //  <span data-mx-spoiler=\"\"><a href=\"https://the-apothecary.club/_matrix/media/v3/download/rory.gay/sLkdxUhipiQaFwRkXcPSRwdg\">
-                //                                 //      <img src=\"mxc://rory.gay/sLkdxUhipiQaFwRkXcPSRwdg\" height=\"69\"></a>
-                //                                 //  </span>
-                //                                 // </blockquote>
-                //                                 await room.SendMessageEventAsync(
-                //                                     new RoomMessageEventContent(
-                //                                         body:
-                //                                         $"Please be careful when posting this image: {matchedpolicyData.Reason}, I have spoilered it for you:",
-                //                                         messageType: "m.text") {
-                //                                         Format = "org.matrix.custom.html",
-                //                                         FormattedBody =
-                //                                             $"<font color=\"#FFFF00\">Please be careful when posting this image: {matchedpolicyData.Reason}, I have spoilered it for you:</a></font>"
-                //                                     });
-                //                                 var imageUrl = message.Url;
-                //                                 await room.SendMessageEventAsync(
-                //                                     new RoomMessageEventContent(body: $"CN: {imageUrl}",
-                //                                         messageType: "m.text") {
-                //                                         Format = "org.matrix.custom.html",
-                //                                         FormattedBody = $"""
-                //                                                              <blockquote>
-                //                                                                 <font color=\"#dc143c\" data-mx-color=\"#dc143c\">
-                //                                                                     <b>CN</b>
-                //                                                                 </font>:
-                //                                                                 <a href=\"{imageUrl}\">{matchedpolicyData.Reason}</a><br>
-                //                                                                 <span data-mx-spoiler=\"\">
-                //                                                                     <a href=\"{imageUrl}\">
-                //                                                                         <img src=\"{imageUrl}\" height=\"69\">
-                //                                                                     </a>
-                //                                                                 </span>
-                //                                                              </blockquote>
-                //                                                          """
-                //                                     });
-                //                                 await room.RedactEventAsync(@event.EventId, "Automatically spoilered: " + matchedpolicyData.Reason);
-                //                                 break;
-                //                             }
-                //                             case "mute": {
-                //                                 await room.RedactEventAsync(@event.EventId, matchedpolicyData.Reason);
-                //                                 //change powerlevel to -1
-                //                                 var currentPls = await room.GetPowerLevelsAsync();
-                //                                 if (currentPls is null) {
-                //                                     logger.LogWarning("Unable to get power levels for {room}", room.RoomId);
-                //                                     await _logRoom.SendMessageEventAsync(
-                //                                         MessageFormatter.FormatError($"Unable to get power levels for {MessageFormatter.HtmlFormatMention(room.RoomId)}"));
-                //                                     return;
-                //                                 }
-                //
-                //                                 currentPls.Users ??= new();
-                //                                 currentPls.Users[@event.Sender] = -1;
-                //                                 await room.SendStateEventAsync("m.room.power_levels", currentPls);
-                //                                 break;
-                //                             }
-                //                             case "kick": {
-                //                                 await room.RedactEventAsync(@event.EventId, matchedpolicyData.Reason);
-                //                                 await room.KickAsync(@event.Sender, matchedpolicyData.Reason);
-                //                                 break;
-                //                             }
-                //                             case "ban": {
-                //                                 await room.RedactEventAsync(@event.EventId, matchedpolicyData.Reason);
-                //                                 await room.BanAsync(@event.Sender, matchedpolicyData.Reason);
-                //                                 break;
-                //                             }
-                //                             default: {
-                //                                 throw new ArgumentOutOfRangeException("recommendation",
-                //                                     $"Unknown response type {matchedpolicyData.Recommendation}!");
-                //                             }
-                //                         }
-                //                     }
-                //                 }
-            }
-            catch (Exception e) {
-                logger.LogError("{}", e.ToString());
-                await _controlRoom.SendMessageEventAsync(
-                    MessageFormatter.FormatException($"Unable to process event in {MessageFormatter.HtmlFormatMention(room.RoomId)}", e));
-                await _logRoom.SendMessageEventAsync(
-                    MessageFormatter.FormatException($"Unable to process event in {MessageFormatter.HtmlFormatMention(room.RoomId)}", e));
-                await using var stream = new MemoryStream(e.ToString().AsBytes().ToArray());
-                await _controlRoom.SendFileAsync("error.log.cs", stream);
-                await _logRoom.SendFileAsync("error.log.cs", stream);
-            }
-        });
-        await engine.ReloadActivePolicyLists();
-        await syncHelper.RunSyncLoopAsync();
-    }
-
-    private async Task LogPolicyChange(StateEventResponse changeEvent) {
-        var room = hs.GetRoom(changeEvent.RoomId!);
-        var message = MessageFormatter.FormatWarning($"Policy change detected in {MessageFormatter.HtmlFormatMessageLink(changeEvent.RoomId, changeEvent.EventId, [hs.ServerName], await room.GetNameOrFallbackAsync())}!");
-        message = message.ConcatLine(new RoomMessageEventContent(body: $"Policy type: {changeEvent.Type} -> {changeEvent.MappedType.Name}") {
-            FormattedBody = $"Policy type: {changeEvent.Type} -> {changeEvent.MappedType.Name}"
-        });
-        var isUpdated = changeEvent.Unsigned.PrevContent is { Count: > 0 };
-        var isRemoved = changeEvent.RawContent is not { Count: > 0 };
-        // if (isUpdated) {
-        //     message = message.ConcatLine(MessageFormatter.FormatSuccess("Rule updated!"));
-        //     message = message.ConcatLine(MessageFormatter.FormatSuccessJson("Old rule:", changeEvent.Unsigned.PrevContent!));
-        // }
-        // else if (isRemoved) {
-        //     message = message.ConcatLine(MessageFormatter.FormatWarningJson("Rule removed!", changeEvent.Unsigned.PrevContent!));
-        // }
-        // else {
-        //     message = message.ConcatLine(MessageFormatter.FormatSuccess("New rule added!"));
-        // }
-        message = message.ConcatLine(MessageFormatter.FormatSuccessJson($"{(isUpdated ? "Updated" : isRemoved ? "Removed" : "New")} rule: {changeEvent.StateKey}", changeEvent.RawContent!));
-        if (isRemoved || isUpdated) {
-            message = message.ConcatLine(MessageFormatter.FormatSuccessJson("Old content: ", changeEvent.Unsigned.PrevContent!));
-        }
-        
-        await _logRoom.SendMessageEventAsync(message);
-    }
-
-    /// <summary>Triggered when the application host is performing a graceful shutdown.</summary>
-    /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
-    public async Task StopAsync(CancellationToken cancellationToken) {
-        logger.LogInformation("Shutting down bot!");
-    }
-
-}
diff --git a/ExampleBots/ModerationBot/ModerationBot.csproj b/ExampleBots/ModerationBot/ModerationBot.csproj
deleted file mode 100644
index 99eb0b9..0000000
--- a/ExampleBots/ModerationBot/ModerationBot.csproj
+++ /dev/null
@@ -1,32 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">

-

-  <PropertyGroup>

-    <OutputType>Exe</OutputType>

-    <TargetFramework>net8.0</TargetFramework>

-    <LangVersion>preview</LangVersion>

-    <ImplicitUsings>enable</ImplicitUsings>

-    <Nullable>enable</Nullable>

-    <PublishAot>false</PublishAot>

-    <InvariantGlobalization>true</InvariantGlobalization>

-<!--    <PublishTrimmed>true</PublishTrimmed>-->

-<!--    <PublishReadyToRun>true</PublishReadyToRun>-->

-<!--    <PublishSingleFile>true</PublishSingleFile>-->

-<!--    <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings>-->

-<!--    <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison>-->

-<!--    <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings>-->

-  </PropertyGroup>

-

-  <ItemGroup>

-      <ProjectReference Include="..\..\LibMatrix\LibMatrix.csproj" />

-      <ProjectReference Include="..\..\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj" />

-  </ItemGroup>

-

-  <ItemGroup>

-    <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />

-  </ItemGroup>

-  <ItemGroup>

-    <Content Include="appsettings*.json">

-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>

-    </Content>

-  </ItemGroup>

-</Project>

diff --git a/ExampleBots/ModerationBot/ModerationBotConfiguration.cs b/ExampleBots/ModerationBot/ModerationBotConfiguration.cs
deleted file mode 100644
index 415b581..0000000
--- a/ExampleBots/ModerationBot/ModerationBotConfiguration.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Microsoft.Extensions.Configuration;
-
-namespace ModerationBot;
-
-public class ModerationBotConfiguration {
-    public ModerationBotConfiguration(IConfiguration config) => config.GetRequiredSection("ModerationBot").Bind(this);
-
-    public List<string> Admins { get; set; } = new();
-    public bool DemoMode { get; set; } = false;
-}
diff --git a/ExampleBots/ModerationBot/PolicyEngine.cs b/ExampleBots/ModerationBot/PolicyEngine.cs
deleted file mode 100644
index 0d0ed65..0000000
--- a/ExampleBots/ModerationBot/PolicyEngine.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-using System.Diagnostics;
-using System.Security.Cryptography;
-using System.Text.Json;
-using System.Text.RegularExpressions;
-using ArcaneLibs.Extensions;
-using LibMatrix;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.EventTypes.Spec.State.Policy;
-using LibMatrix.Helpers;
-using LibMatrix.Homeservers;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using Microsoft.Extensions.Logging;
-using ModerationBot.AccountData;
-using ModerationBot.StateEventTypes.Policies;
-using ModerationBot.StateEventTypes.Policies.Implementations;
-
-namespace ModerationBot;
-
-public class PolicyEngine(AuthenticatedHomeserverGeneric hs, ILogger<ModerationBot> logger, ModerationBotConfiguration configuration, HomeserverResolverService hsResolver) {
-    private Dictionary<string, PolicyList> PolicyListAccountData { get; set; } = new();
-    // ReSharper disable once MemberCanBePrivate.Global
-    public List<PolicyList> ActivePolicyLists { get; set; } = new();
-    public List<BasePolicy> ActivePolicies { get; set; } = new();
-    public Dictionary<string, List<BasePolicy>> ActivePoliciesByType { get; set; } = new();
-    private GenericRoom? _logRoom;
-    private GenericRoom? _controlRoom;
-
-    public async Task ReloadActivePolicyLists() {
-        var sw = Stopwatch.StartNew();
-
-        var botData = await hs.GetAccountDataAsync<BotData>("gay.rory.moderation_bot_data");
-        _logRoom ??= hs.GetRoom(botData.LogRoom ?? botData.ControlRoom);
-        _controlRoom ??= hs.GetRoom(botData.ControlRoom);
-
-        await _controlRoom?.SendMessageEventAsync(MessageFormatter.FormatSuccess("Reloading policy lists!"))!;
-        await _logRoom?.SendMessageEventAsync(MessageFormatter.FormatSuccess("Reloading policy lists!"))!;
-
-        var progressMessage = await _logRoom?.SendMessageEventAsync(MessageFormatter.FormatSuccess("0/? policy lists loaded"))!;
-
-        var policyLists = new List<PolicyList>();
-        try {
-            PolicyListAccountData = await hs.GetAccountDataAsync<Dictionary<string, PolicyList>>("gay.rory.moderation_bot.policy_lists");
-        }
-        catch (MatrixException e) {
-            if (e is not { ErrorCode: "M_NOT_FOUND" }) throw;
-        }
-
-        if (!PolicyListAccountData.ContainsKey(botData.DefaultPolicyRoom!)) {
-            PolicyListAccountData.Add(botData.DefaultPolicyRoom!, new PolicyList() {
-                Trusted = true
-            });
-            await hs.SetAccountDataAsync("gay.rory.moderation_bot.policy_lists", PolicyListAccountData);
-        }
-
-        var loadTasks = new List<Task<PolicyList>>();
-        foreach (var (roomId, policyList) in PolicyListAccountData) {
-            var room = hs.GetRoom(roomId);
-            loadTasks.Add(LoadPolicyListAsync(room, policyList));
-        }
-
-        await foreach (var policyList in loadTasks.ToAsyncEnumerable()) {
-            policyLists.Add(policyList);
-
-            if (false || policyList.Policies.Count >= 256 || policyLists.Count == PolicyListAccountData.Count) {
-                var progressMsgContent = MessageFormatter.FormatSuccess($"{policyLists.Count}/{PolicyListAccountData.Count} policy lists loaded, " +
-                                                                        $"{policyLists.Sum(x => x.Policies.Count)} policies total, {sw.Elapsed} elapsed.")
-                    .SetReplaceRelation<RoomMessageEventContent>(progressMessage.EventId);
-
-                await _logRoom?.SendMessageEventAsync(progressMsgContent);
-            }
-        }
-
-        // Console.WriteLine($"Reloaded policy list data in {sw.Elapsed}");
-        // await _logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Done fetching {policyLists.Count} policy lists in {sw.Elapsed}!"));
-
-        ActivePolicyLists = policyLists;
-        ActivePolicies = await GetActivePolicies();
-    }
-
-    private async Task<PolicyList> LoadPolicyListAsync(GenericRoom room, PolicyList policyList) {
-        policyList.Room = room;
-        policyList.Policies.Clear();
-
-        var stateEvents = room.GetFullStateAsync();
-        await foreach (var stateEvent in stateEvents) {
-            if (stateEvent != null && (
-                    stateEvent.MappedType.IsAssignableTo(typeof(BasePolicy))
-                    || stateEvent.MappedType.IsAssignableTo(typeof(PolicyRuleEventContent))
-                )) {
-                policyList.Policies.Add(stateEvent);
-            }
-        }
-
-        // if (policyList.Policies.Count >= 1)
-        // await _logRoom?.SendMessageEventAsync(
-        // MessageFormatter.FormatSuccess($"Loaded {policyList.Policies.Count} policies for {MessageFormatter.HtmlFormatMention(room.RoomId)}!"))!;
-
-        return policyList;
-    }
-
-
-    public async Task ReloadActivePolicyListById(string roomId) {
-        if (!ActivePolicyLists.Any(x => x.Room.RoomId == roomId)) return;
-        await LoadPolicyListAsync(hs.GetRoom(roomId), ActivePolicyLists.Single(x => x.Room.RoomId == roomId));
-        ActivePolicies = await GetActivePolicies();
-    }
-
-    public async Task<List<BasePolicy>> GetActivePolicies() {
-        var sw = Stopwatch.StartNew();
-        List<BasePolicy> activePolicies = new();
-
-        foreach (var activePolicyList in ActivePolicyLists) {
-            foreach (var policyEntry in activePolicyList.Policies) {
-                // TODO: implement rule translation
-                var policy = policyEntry.TypedContent is BasePolicy ? policyEntry.TypedContent as BasePolicy : policyEntry.RawContent.Deserialize<UnknownPolicy>();
-                if (policy?.Entity is null) continue;
-                policy.PolicyList = activePolicyList;
-                policy.OriginalEvent = policyEntry;
-                activePolicies.Add(policy);
-            }
-        }
-
-        Console.WriteLine($"Translated policy list data in {sw.Elapsed}");
-        ActivePoliciesByType = activePolicies.GroupBy(x => x.GetType().Name).ToDictionary(x => x.Key, x => x.ToList());
-        await _logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Translated policy list data in {sw.GetElapsedAndRestart()}"));
-        // await _logRoom.SendMessageEventAsync(MessageFormatter.FormatSuccess($"Built policy type map in {sw.GetElapsedAndRestart()}"));
-
-        var summary = SummariseStateTypeCounts(activePolicies.Select(x => x.OriginalEvent).ToList());
-        await _logRoom?.SendMessageEventAsync(new RoomMessageEventContent() {
-            Body = summary.Raw,
-            FormattedBody = summary.Html,
-            Format = "org.matrix.custom.html"
-        })!;
-
-        return activePolicies;
-    }
-
-    public async Task<List<BasePolicy>> GetMatchingPolicies(StateEventResponse @event) {
-        List<BasePolicy> matchingPolicies = new();
-        if (@event.Sender == @hs.UserId) return matchingPolicies; //ignore self at all costs
-
-        if (ActivePoliciesByType.TryGetValue(nameof(ServerPolicyRuleEventContent), out var serverPolicies)) {
-            var userServer = @event.Sender.Split(':', 2)[1];
-            matchingPolicies.AddRange(serverPolicies.Where(x => x.Entity == userServer));
-        }
-
-        if (ActivePoliciesByType.TryGetValue(nameof(UserPolicyRuleEventContent), out var userPolicies)) {
-            matchingPolicies.AddRange(userPolicies.Where(x => x.Entity == @event.Sender));
-        }
-
-        if (@event.TypedContent is RoomMessageEventContent msgContent) {
-            matchingPolicies.AddRange(await CheckMessageContent(@event));
-            // if (msgContent.MessageType == "m.text" || msgContent.MessageType == "m.notice") ; //TODO: implement word etc. filters
-            if (msgContent.MessageType == "m.image" || msgContent.MessageType == "m.file" || msgContent.MessageType == "m.audio" || msgContent.MessageType == "m.video")
-                matchingPolicies.AddRange(await CheckMedia(@event));
-        }
-
-        return matchingPolicies;
-    }
-
-    #region Policy matching
-
-    private async Task<List<BasePolicy>> CheckMessageContent(StateEventResponse @event) {
-        var matchedRules = new List<BasePolicy>();
-        var msgContent = @event.TypedContent as RoomMessageEventContent;
-
-        if (ActivePoliciesByType.TryGetValue(nameof(MessagePolicyContainsText), out var messageContainsPolicies))
-            foreach (var policy in messageContainsPolicies) {
-                if ((@msgContent?.Body?.ToLowerInvariant().Contains(policy.Entity.ToLowerInvariant()) ?? false) || (@msgContent?.FormattedBody?.ToLowerInvariant().Contains(policy.Entity.ToLowerInvariant()) ?? false))
-                    matchedRules.Add(policy);
-            }
-
-
-        return matchedRules;
-    }
-
-    private async Task<List<BasePolicy>> CheckMedia(StateEventResponse @event) {
-        var matchedRules = new List<BasePolicy>();
-        var hashAlgo = SHA3_256.Create();
-
-        var mxcUri = @event.RawContent["url"].GetValue<string>();
-
-        //check server policies before bothering with hashes
-        if (ActivePoliciesByType.TryGetValue(nameof(MediaPolicyHomeserver), out var mediaHomeserverPolicies))
-            foreach (var policy in mediaHomeserverPolicies) {
-                logger.LogInformation("Checking rule {rule}: {data}", policy.OriginalEvent.StateKey, policy.OriginalEvent.TypedContent.ToJson(ignoreNull: true, indent: false));
-                policy.Entity = policy.Entity.Replace("\\*", ".*").Replace("\\?", ".");
-                var regex = new Regex($"mxc://({policy.Entity})/.*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
-                if (regex.IsMatch(@event.RawContent["url"]!.GetValue<string>())) {
-                    logger.LogInformation("{url} matched rule {rule}", @event.RawContent["url"], policy.ToJson(ignoreNull: true));
-                    matchedRules.Add(policy);
-                    // continue;
-                }
-            }
-
-        var resolvedUri = await hsResolver.ResolveMediaUri(mxcUri.Split('/')[2], mxcUri);
-        var uriHash = hashAlgo.ComputeHash(mxcUri.AsBytes().ToArray());
-        byte[]? fileHash = null;
-
-        try {
-            fileHash = await hashAlgo.ComputeHashAsync(await hs.ClientHttpClient.GetStreamAsync(resolvedUri));
-        }
-        catch (Exception ex) {
-            await _logRoom.SendMessageEventAsync(
-                MessageFormatter.FormatException($"Error calculating file hash for {mxcUri} via {mxcUri.Split('/')[2]} ({resolvedUri}), retrying via {hs.BaseUrl}...",
-                    ex));
-            try {
-                resolvedUri = await hsResolver.ResolveMediaUri(hs.BaseUrl, mxcUri);
-                fileHash = await hashAlgo.ComputeHashAsync(await hs.ClientHttpClient.GetStreamAsync(resolvedUri));
-            }
-            catch (Exception ex2) {
-                await _logRoom.SendMessageEventAsync(
-                    MessageFormatter.FormatException($"Error calculating file hash via {hs.BaseUrl} ({resolvedUri})!", ex2));
-            }
-        }
-
-        logger.LogInformation("Checking media {url} with hash {hash}", resolvedUri, fileHash);
-
-        if (ActivePoliciesByType.ContainsKey(nameof(MediaPolicyFile)))
-            foreach (MediaPolicyFile policy in ActivePoliciesByType[nameof(MediaPolicyFile)]) {
-                logger.LogInformation("Checking rule {rule}: {data}", policy.OriginalEvent.StateKey, policy.OriginalEvent.TypedContent.ToJson(ignoreNull: true, indent: false));
-                if (policy.Entity is not null && Convert.ToBase64String(uriHash).SequenceEqual(policy.Entity)) {
-                    logger.LogInformation("{url} matched rule {rule} by uri hash", @event.RawContent["url"], policy.ToJson(ignoreNull: true));
-                    matchedRules.Add(policy);
-                    // continue;
-                }
-                else logger.LogInformation("uri hash {uriHash} did not match rule's {ruleUriHash}", Convert.ToHexString(uriHash), policy.Entity);
-
-                if (policy.FileHash is not null && fileHash is not null && policy.FileHash == Convert.ToBase64String(fileHash)) {
-                    logger.LogInformation("{url} matched rule {rule} by file hash", @event.RawContent["url"], policy.ToJson(ignoreNull: true));
-                    matchedRules.Add(policy);
-                    // continue;
-                }
-                else logger.LogInformation("file hash {fileHash} did not match rule's {ruleFileHash}", Convert.ToBase64String(fileHash), policy.FileHash);
-
-                //check pixels every 10% of the way through the image using ImageSharp
-                // var image = Image.Load(await _hs._httpClient.GetStreamAsync(resolvedUri));
-            }
-        else logger.LogInformation("No active media file policies");
-        // logger.LogInformation("{url} did not match any rules", @event.RawContent["url"]);
-
-        return matchedRules;
-    }
-
-    #endregion
-
-    #region Internal code
-
-    #region Summarisation
-
-    private static (string Raw, string Html) SummariseStateTypeCounts(IList<StateEventResponse> states) {
-        string raw = "Count | State type | Mapped type", html = "<table><tr><th>Count</th><th>State type</th><th>Mapped type</th></tr>";
-        var groupedStates = states.GroupBy(x => x.Type).ToDictionary(x => x.Key, x => x.ToList()).OrderByDescending(x => x.Value.Count);
-        foreach (var (type, stateGroup) in groupedStates) {
-            raw += $"\n{stateGroup.Count} | {type} | {stateGroup[0].MappedType.Name}";
-            html += $"<tr><td>{stateGroup.Count}</td><td>{type}</td><td>{stateGroup[0].MappedType.Name}</td></tr>";
-        }
-
-        html += "</table>";
-        return (raw, html);
-    }
-
-    #endregion
-
-    #endregion
-
-}
diff --git a/ExampleBots/ModerationBot/PolicyList.cs b/ExampleBots/ModerationBot/PolicyList.cs
deleted file mode 100644
index f291c7b..0000000
--- a/ExampleBots/ModerationBot/PolicyList.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Text.Json.Serialization;
-using LibMatrix;
-using LibMatrix.RoomTypes;
-
-namespace ModerationBot;
-
-public class PolicyList {
-    [JsonIgnore]
-    public GenericRoom Room { get; set; }
-
-    [JsonPropertyName("trusted")]
-    public bool Trusted { get; set; } = false;
-
-    [JsonIgnore]
-    public List<StateEventResponse> Policies { get; set; } = new();
-}
diff --git a/ExampleBots/ModerationBot/Program.cs b/ExampleBots/ModerationBot/Program.cs
deleted file mode 100644
index d125258..0000000
--- a/ExampleBots/ModerationBot/Program.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// See https://aka.ms/new-console-template for more information
-
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using ModerationBot;
-
-Console.WriteLine("Hello, World!");
-
-var builder = Host.CreateDefaultBuilder(args);
-
-builder.ConfigureHostOptions(host => {
-    host.ServicesStartConcurrently = true;
-    host.ServicesStopConcurrently = true;
-    host.ShutdownTimeout = TimeSpan.FromSeconds(5);
-});
-
-if (Environment.GetEnvironmentVariable("MODERATIONBOT_APPSETTINGS_PATH") is string path)
-    builder.ConfigureAppConfiguration(x => x.AddJsonFile(path));
-
-var host = builder.ConfigureServices((_, services) => {
-    services.AddScoped<TieredStorageService>(x =>
-        new TieredStorageService(
-            cacheStorageProvider: new FileStorageProvider("bot_data/cache/"),
-            dataStorageProvider: new FileStorageProvider("bot_data/data/")
-        )
-    );
-    services.AddSingleton<ModerationBotConfiguration>();
-
-    services.AddRoryLibMatrixServices();
-    services.AddBot(withCommands: true);
-
-    services.AddSingleton<PolicyEngine>();
-
-    services.AddHostedService<ModerationBot.ModerationBot>();
-}).UseConsoleLifetime().Build();
-
-await host.RunAsync();
\ No newline at end of file
diff --git a/ExampleBots/ModerationBot/Properties/launchSettings.json b/ExampleBots/ModerationBot/Properties/launchSettings.json
deleted file mode 100644
index 997e294..0000000
--- a/ExampleBots/ModerationBot/Properties/launchSettings.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "$schema": "http://json.schemastore.org/launchsettings.json",
-  "profiles": {
-    "Default": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-
-      }
-    },
-    "Development": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-        "DOTNET_ENVIRONMENT": "Development"
-      }
-    },
-    "Local config": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-        "DOTNET_ENVIRONMENT": "Local"
-      }
-    }
-  }
-}
diff --git a/ExampleBots/ModerationBot/StateEventTypes/Policies/BasePolicy.cs b/ExampleBots/ModerationBot/StateEventTypes/Policies/BasePolicy.cs
deleted file mode 100644
index 64b0448..0000000
--- a/ExampleBots/ModerationBot/StateEventTypes/Policies/BasePolicy.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using System.Text.Json.Serialization;
-using LibMatrix;
-using LibMatrix.EventTypes;
-using LibMatrix.Interfaces;
-
-namespace ModerationBot.StateEventTypes.Policies;
-
-public abstract class BasePolicy : EventContent {
-    /// <summary>
-    ///     Entity this policy applies to, null if event was redacted
-    /// </summary>
-    [JsonPropertyName("entity")]
-    public string? Entity { get; set; }
-
-    /// <summary>
-    ///     Reason this policy exists
-    /// </summary>
-    [JsonPropertyName("reason")]
-    public string? Reason { get; set; }
-
-    /// <summary>
-    ///     Suggested action to take, one of `ban`, `kick`, `mute`, `redact`, `spoiler`, `warn` or `warn_admins`
-    /// </summary>
-    [JsonPropertyName("recommendation")]
-    [AllowedValues("ban", "kick", "mute", "redact", "spoiler", "warn", "warn_admins")]
-    public string Recommendation { get; set; } = "warn";
-
-    /// <summary>
-    ///     Expiry time in milliseconds since the unix epoch, or null if the ban has no expiry.
-    /// </summary>
-    [JsonPropertyName("support.feline.policy.expiry.rev.2")] //stable prefix: expiry, msc pending
-    public long? Expiry { get; set; }
-
-    //utils
-    /// <summary>
-    ///     Readable expiry time, provided for easy interaction
-    /// </summary>
-    [JsonPropertyName("gay.rory.matrix_room_utils.readable_expiry_time_utc")]
-    public DateTime? ExpiryDateTime {
-        get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime;
-        set => Expiry = value is null ? null : ((DateTimeOffset)value).ToUnixTimeMilliseconds();
-    }
-
-    #region Internal metadata
-
-    [JsonIgnore]
-    public PolicyList PolicyList { get; set; }
-
-    public StateEventResponse OriginalEvent { get; set; }
-
-    #endregion
-}
diff --git a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyFile.cs b/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyFile.cs
deleted file mode 100644
index c5b6ef2..0000000
--- a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyFile.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Text.Json.Serialization;
-using LibMatrix.EventTypes;
-
-namespace ModerationBot.StateEventTypes.Policies.Implementations;
-
-/// <summary>
-///     File policy event, entity is the MXC URI of the file, hashed with SHA3-256.
-/// </summary>
-[MatrixEvent(EventName = "gay.rory.moderation.rule.media")]
-public class MediaPolicyFile : BasePolicy {
-    /// <summary>
-    ///     Hash of the file
-    /// </summary>
-    [JsonPropertyName("file_hash")]
-    public string? FileHash { get; set; }
-}
diff --git a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyHomeserver.cs b/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyHomeserver.cs
deleted file mode 100644
index 72c9a60..0000000
--- a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MediaPolicyHomeserver.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using LibMatrix.EventTypes;
-
-namespace ModerationBot.StateEventTypes.Policies.Implementations;
-
-/// <summary>
-///     Homeserver media policy event, entity is the MXC URI of the file, hashed with SHA3-256.
-/// </summary>
-[MatrixEvent(EventName = "gay.rory.moderation.rule.media.homeserver")]
-public class MediaPolicyHomeserver : BasePolicy {
-}
diff --git a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MessagePolicyContainsText.cs b/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MessagePolicyContainsText.cs
deleted file mode 100644
index fa21e2d..0000000
--- a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/MessagePolicyContainsText.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using LibMatrix.EventTypes;
-
-namespace ModerationBot.StateEventTypes.Policies.Implementations;
-
-/// <summary>
-///     Text contains policy event, entity is the text to contain.
-/// </summary>
-[MatrixEvent(EventName = "gay.rory.moderation.rule.text.contains")]
-public class MessagePolicyContainsText : BasePolicy {
-}
diff --git a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/UnknownPolicy.cs b/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/UnknownPolicy.cs
deleted file mode 100644
index 78860ca..0000000
--- a/ExampleBots/ModerationBot/StateEventTypes/Policies/Implementations/UnknownPolicy.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ModerationBot.StateEventTypes.Policies.Implementations;
-
-/// <summary>
-///     Unknown policy event, usually used for handling unknown cases
-/// </summary>
-public class UnknownPolicy : BasePolicy {
-}
diff --git a/ExampleBots/ModerationBot/appsettings.Development.json b/ExampleBots/ModerationBot/appsettings.Development.json
deleted file mode 100644
index 224d0da..0000000
--- a/ExampleBots/ModerationBot/appsettings.Development.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  "Logging": {
-    "LogLevel": {
-      "Default": "Debug",
-      "System": "Information",
-      "Microsoft": "Information"
-    }
-  },
-  "LibMatrixBot": {
-    // The homeserver to connect to
-    "Homeserver": "rory.gay",
-    // The access token to use
-    "AccessToken": "syt_xxxxxxxxxxxxxxxxx",
-    // The command prefix
-    "Prefix": "?"
-  },
-  "ModerationBot": {
-    // List of people who should be invited to the control room
-    "Admins": [
-      "@emma:conduit.rory.gay",
-      "@emma:rory.gay"
-    ]
-  }
-}
diff --git a/ExampleBots/ModerationBot/appsettings.json b/ExampleBots/ModerationBot/appsettings.json
deleted file mode 100644
index 6ba02f3..0000000
--- a/ExampleBots/ModerationBot/appsettings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "Logging": {
-        "LogLevel": {
-            "Default": "Debug",
-            "System": "Information",
-            "Microsoft": "Information"
-        }
-    }
-}
diff --git a/ExampleBots/PluralContactBotPoC b/ExampleBots/PluralContactBotPoC
new file mode 160000
+Subproject 14c20d6905640c8f691fec76752318a474fa0bc
diff --git a/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs b/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs
deleted file mode 100644
index 2adcbb3..0000000
--- a/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Text.Json.Serialization;
-using LibMatrix.EventTypes;
-using LibMatrix.Interfaces;
-
-namespace PluralContactBotPoC.Bot.AccountData;
-[MatrixEvent(EventName = "gay.rory.plural_contact_bot.bot_config")]
-public class BotData : EventContent {
-    [JsonPropertyName("control_room")]
-    public string ControlRoom { get; set; } = "";
-
-    [JsonPropertyName("log_room")]
-    public string? LogRoom { get; set; } = "";
-
-    [JsonPropertyName("policy_room")]
-    public string? PolicyRoom { get; set; } = "";
-}
diff --git a/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs b/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs
deleted file mode 100644
index ad8ab1d..0000000
--- a/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Text.Json.Serialization;
-using LibMatrix.EventTypes;
-using LibMatrix.Interfaces;
-
-namespace PluralContactBotPoC.Bot.StateEventTypes;
-
-[MatrixEvent(EventName = "gay.rory.plural_contact_bot.system_data")]
-public class SystemData : EventContent {
-    [JsonPropertyName("control_room")]
-    public required string ControlRoom { get; set; }
-    [JsonPropertyName("system_members")]
-    public List<string> Members { get; set; } = new();
-    [JsonPropertyName("dm_space")]
-    public string? DmSpace { get; set; }
-}
diff --git a/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs b/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs
deleted file mode 100644
index 0bb3265..0000000
--- a/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using LibMatrix;
-using LibMatrix.EventTypes.Spec.State;
-using LibMatrix.Helpers;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot.Interfaces;
-using PluralContactBotPoC.Bot.AccountData;
-using PluralContactBotPoC.Bot.StateEventTypes;
-
-namespace PluralContactBotPoC.Bot.Commands;
-
-public class CreateSystemCommand(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver) : ICommand {
-    public string Name { get; } = "createsystem";
-    public string Description { get; } = "Create a new system";
-
-    public async Task<bool> CanInvoke(CommandContext ctx) {
-        return true;
-    }
-
-    public async Task Invoke(CommandContext ctx) {
-        if (ctx.Args.Length != 1) {
-            await ctx.Reply(MessageFormatter.FormatError("Only one argument is allowed: system name!"));
-            return;
-        }
-
-        var sysName = ctx.Args[0];
-        try {
-            try {
-                await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.plural_contact_bot.system_data");
-                await ctx.Reply(MessageFormatter.FormatError($"System {sysName} already exists!"));
-            }
-            catch (MatrixException e) {
-                if (e is { ErrorCode: "M_NOT_FOUND" }) {
-                    var sysData = new SystemData() {
-                        ControlRoom = ctx.Room.RoomId,
-                        Members = new(),
-                    };
-
-                    var state = ctx.Room.GetMembersEnumerableAsync();
-                    await foreach (var member in state) {
-                        sysData.Members.Add(member.StateKey);
-                    }
-
-                    await ctx.Room.SendStateEventAsync("m.room.name", new RoomNameEventContent() {
-                        Name = sysName + " control room"
-                    });
-
-                    return;
-                }
-
-                throw;
-            }
-        }
-        catch (Exception e) {
-            await ctx.Reply(MessageFormatter.FormatException("Something went wrong!", e));
-        }
-    }
-}
diff --git a/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs b/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs
deleted file mode 100644
index 231af95..0000000
--- a/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System.Text;
-using ArcaneLibs.Extensions;
-using LibMatrix.EventTypes.Spec;
-using LibMatrix.EventTypes.Spec.State;
-using LibMatrix.Helpers;
-using LibMatrix.Homeservers;
-using LibMatrix.RoomTypes;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot;
-using LibMatrix.Utilities.Bot.Interfaces;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using PluralContactBotPoC.Bot.AccountData;
-using PluralContactBotPoC.Bot.StateEventTypes;
-
-namespace PluralContactBotPoC.Bot;
-
-public class PluralContactBot(AuthenticatedHomeserverGeneric hs, ILogger<PluralContactBot> logger, LibMatrixBotConfiguration botConfiguration,
-    PluralContactBotConfiguration configuration,
-    HomeserverResolverService hsResolver) : IHostedService {
-    private readonly IEnumerable<ICommand> _commands;
-
-    private Task _listenerTask;
-
-    private GenericRoom? _logRoom;
-
-    /// <summary>Triggered when the application host is ready to start the service.</summary>
-    /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
-    public async Task StartAsync(CancellationToken cancellationToken) {
-        _listenerTask = Run(cancellationToken);
-        logger.LogInformation("Bot started!");
-    }
-
-    private async Task Run(CancellationToken cancellationToken) {
-        Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete);
-
-        BotData botData;
-
-        _logRoom = hs.GetRoom(botConfiguration.LogRoom);
-
-        var syncHelper = new SyncHelper(hs);
-
-        syncHelper.InviteReceivedHandlers.Add(async Task (args) => {
-            var inviteEvent =
-                args.Value.InviteState.Events.FirstOrDefault(x =>
-                    x.Type == "m.room.member" && x.StateKey == hs.UserId);
-            logger.LogInformation("Got invite to {} by {} with reason: {}", args.Key, inviteEvent.Sender, (inviteEvent.TypedContent as RoomMemberEventContent).Reason);
-
-            try {
-                var accountData = await hs.GetAccountDataAsync<SystemData>($"gay.rory.plural_contact_bot.system_data#{inviteEvent.StateKey}");
-                if (accountData.Members.Contains(inviteEvent.Sender)) {
-                    await (hs.GetRoom(args.Key)).JoinAsync(reason: "I was invited by a system member!");
-
-                    await _logRoom.SendMessageEventAsync(
-                        MessageFormatter.FormatSuccess(
-                            $"I was invited by a system member ({MessageFormatter.HtmlFormatMention(inviteEvent.Sender)}) to {MessageFormatter.HtmlFormatMention(args.Key)}"));
-
-                    return;
-                }
-            }
-            catch (Exception e) {
-                await _logRoom.SendMessageEventAsync(
-                    MessageFormatter.FormatException(
-                        $"Exception handling event {inviteEvent.EventId} by {inviteEvent.Sender} in {MessageFormatter.HtmlFormatMention(inviteEvent.RoomId)}", e));
-            }
-
-            if (inviteEvent.Sender.EndsWith(":rory.gay") || inviteEvent.Sender.EndsWith(":conduit.rory.gay")) {
-                try {
-                    var senderProfile = await hs.GetProfileAsync(inviteEvent.Sender);
-                    await (hs.GetRoom(args.Key)).JoinAsync(reason: $"I was invited by {senderProfile.DisplayName ?? inviteEvent.Sender}!");
-                }
-                catch (Exception e) {
-                    logger.LogError("{}", e.ToString());
-                    await (hs.GetRoom(args.Key)).LeaveAsync(reason: "I was unable to join the room: " + e);
-                }
-            }
-        });
-
-        syncHelper.TimelineEventHandlers.Add(async @event => {
-            var room = hs.GetRoom(@event.RoomId);
-            try {
-                logger.LogInformation(
-                    "Got timeline event in {}: {}", @event.RoomId, @event.ToJson(indent: true, ignoreNull: true));
-
-                if (@event is { Type: "m.room.message", TypedContent: RoomMessageEventContent message }) { }
-            }
-            catch (Exception e) {
-                logger.LogError("{}", e.ToString());
-                await _logRoom.SendMessageEventAsync(
-                    MessageFormatter.FormatException($"Exception handling event {@event.EventId} by {@event.Sender} in {MessageFormatter.HtmlFormatMention(room.RoomId)}", e));
-                await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(e.ToString()));
-                await _logRoom.SendFileAsync("error.log.cs", stream);
-            }
-        });
-    }
-
-    /// <summary>Triggered when the application host is performing a graceful shutdown.</summary>
-    /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
-    public async Task StopAsync(CancellationToken cancellationToken) {
-        logger.LogInformation("Shutting down bot!");
-    }
-}
diff --git a/ExampleBots/PluralContactBotPoC/Bot/PluralContactBotConfiguration.cs b/ExampleBots/PluralContactBotPoC/Bot/PluralContactBotConfiguration.cs
deleted file mode 100644
index f5c21af..0000000
--- a/ExampleBots/PluralContactBotPoC/Bot/PluralContactBotConfiguration.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Microsoft.Extensions.Configuration;
-
-namespace PluralContactBotPoC.Bot;
-
-public class PluralContactBotConfiguration {
-    public PluralContactBotConfiguration(IConfiguration config) => config.GetRequiredSection("PluralContactBot").Bind(this);
-
-    // public string
-}
diff --git a/ExampleBots/PluralContactBotPoC/PluralContactBotPoC.csproj b/ExampleBots/PluralContactBotPoC/PluralContactBotPoC.csproj
deleted file mode 100644
index 0cd647c..0000000
--- a/ExampleBots/PluralContactBotPoC/PluralContactBotPoC.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-    <PropertyGroup>
-        <OutputType>Exe</OutputType>
-        <TargetFramework>net8.0</TargetFramework>
-        <LangVersion>preview</LangVersion>
-        <ImplicitUsings>enable</ImplicitUsings>
-        <Nullable>enable</Nullable>
-        <PublishAot>false</PublishAot>
-        <InvariantGlobalization>true</InvariantGlobalization>
-        <!--    <PublishTrimmed>true</PublishTrimmed>-->
-        <!--    <PublishReadyToRun>true</PublishReadyToRun>-->
-        <!--    <PublishSingleFile>true</PublishSingleFile>-->
-        <!--    <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings>-->
-        <!--    <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison>-->
-        <!--    <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings>-->
-    </PropertyGroup>
-
-    <ItemGroup>
-        <ProjectReference Include="..\..\LibMatrix\LibMatrix.csproj" />
-        <ProjectReference Include="..\..\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
-    </ItemGroup>
-    <ItemGroup>
-        <Content Include="appsettings*.json">
-            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-        </Content>
-    </ItemGroup>
-    <ItemGroup>
-      <Folder Include="Bot\StateEventTypes\" />
-    </ItemGroup>
-</Project>
diff --git a/ExampleBots/PluralContactBotPoC/Program.cs b/ExampleBots/PluralContactBotPoC/Program.cs
deleted file mode 100644
index f65f2e9..0000000
--- a/ExampleBots/PluralContactBotPoC/Program.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-// See https://aka.ms/new-console-template for more information
-
-using System.Text.Json;
-using ArcaneLibs.Extensions;
-using LibMatrix.Services;
-using LibMatrix.Utilities.Bot;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using PluralContactBotPoC.Bot;
-
-Console.WriteLine("Hello, World!");
-
-var randomBytes = new byte[32];
-Random.Shared.NextBytes(randomBytes);
-var ASToken = Convert.ToBase64String(randomBytes);
-Random.Shared.NextBytes(randomBytes);
-var HSToken = Convert.ToBase64String(randomBytes);
-
-var asConfig = new AppServiceConfiguration() {
-    Id = "plural_contact_bot",
-    Url = null,
-    SenderLocalpart = "plural_contact_bot",
-    AppserviceToken = ASToken,
-    HomeserverToken = HSToken,
-    Namespaces = new() {
-        Users = new() {
-            new() {
-                Exclusive = false,
-                Regex = "@.*"
-            }
-        },
-        Aliases = new() {
-            new() {
-                Exclusive = false,
-                Regex = "#.*"
-            }
-        },
-        Rooms = new() {
-            new() {
-                Exclusive = false,
-                Regex = "!.*"
-            }
-        }
-    },
-    RateLimited = false,
-    Protocols = new List<string>() { "matrix" }
-};
-
-if (File.Exists("appservice.json"))
-    asConfig = JsonSerializer.Deserialize<AppServiceConfiguration>(File.ReadAllText("appservice.json"))!;
-
-File.WriteAllText("appservice.yaml", asConfig.ToYaml());
-File.WriteAllText("appservice.json", asConfig.ToJson());
-Environment.Exit(0);
-
-var host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => {
-    services.AddScoped<TieredStorageService>(x =>
-        new TieredStorageService(
-            cacheStorageProvider: new FileStorageProvider("bot_data/cache/"),
-            dataStorageProvider: new FileStorageProvider("bot_data/data/")
-        )
-    );
-    services.AddSingleton<PluralContactBotConfiguration>();
-    services.AddSingleton<AppServiceConfiguration>();
-
-    services.AddRoryLibMatrixServices();
-    services.AddBot(withCommands: true);
-
-    services.AddHostedService<PluralContactBot>();
-}).UseConsoleLifetime().Build();
-
-await host.RunAsync();
diff --git a/ExampleBots/PluralContactBotPoC/Properties/launchSettings.json b/ExampleBots/PluralContactBotPoC/Properties/launchSettings.json
deleted file mode 100644
index 997e294..0000000
--- a/ExampleBots/PluralContactBotPoC/Properties/launchSettings.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "$schema": "http://json.schemastore.org/launchsettings.json",
-  "profiles": {
-    "Default": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-
-      }
-    },
-    "Development": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-        "DOTNET_ENVIRONMENT": "Development"
-      }
-    },
-    "Local config": {
-      "commandName": "Project",
-      "dotnetRunMessages": true,
-      "environmentVariables": {
-        "DOTNET_ENVIRONMENT": "Local"
-      }
-    }
-  }
-}
diff --git a/ExampleBots/PluralContactBotPoC/appsettings.Development.json b/ExampleBots/PluralContactBotPoC/appsettings.Development.json
deleted file mode 100644
index 93dc0e6..0000000
--- a/ExampleBots/PluralContactBotPoC/appsettings.Development.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "Logging": {
-    "LogLevel": {
-      "Default": "Debug",
-      "System": "Information",
-      "Microsoft": "Information"
-    }
-  },
-  "LibMatrixBot": {
-    // The homeserver to connect to
-    "Homeserver": "rory.gay",
-    // The access token to use
-    "AccessToken": "syt_xxxxxxxxxxxxxxxxx",
-    // The command prefix
-    "Prefix": "?"
-  }
-}
diff --git a/ExampleBots/PluralContactBotPoC/appsettings.json b/ExampleBots/PluralContactBotPoC/appsettings.json
deleted file mode 100644
index 6ba02f3..0000000
--- a/ExampleBots/PluralContactBotPoC/appsettings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "Logging": {
-        "LogLevel": {
-            "Default": "Debug",
-            "System": "Information",
-            "Microsoft": "Information"
-        }
-    }
-}