Full Code of spaghettidba/WorkloadTools for AI

master 9fab260e2d4e cached
176 files
904.9 KB
218.5k tokens
505 symbols
1 requests
Download .txt
Showing preview only (960K chars total). Download the full file or copy to clipboard to get everything.
Repository: spaghettidba/WorkloadTools
Branch: master
Commit: 9fab260e2d4e
Files: 176
Total size: 904.9 KB

Directory structure:
gitextract_79qcbrcm/

├── .config/
│   └── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .gitignore
├── ConvertWorkload/
│   ├── App.config
│   ├── ConvertWorkload.csproj
│   ├── EventReader.cs
│   ├── EventWriter.cs
│   ├── ExtendedEventsEventReader.cs
│   ├── LocalDBManager.cs
│   ├── NLog.config
│   ├── Program.cs
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── SqlTraceEventReader.cs
│   ├── WorkloadConverter.cs
│   ├── WorkloadFileEventWriter.cs
│   └── packages.config
├── DebuggingTools/
│   ├── capture.json
│   ├── capture_trace.json
│   ├── capture_xel.json
│   ├── generate-allWorkload.bat
│   ├── generate-workload.ps1
│   ├── replay.json
│   ├── report.bat
│   ├── setup.bat
│   ├── start-capture.bat
│   ├── start-capture_trace.bat
│   ├── start-capture_xel.bat
│   └── start-replay.bat
├── LICENSE.md
├── README.md
├── Reports/
│   ├── README.md
│   ├── WorkloadTools Report - Sample.pbix
│   └── WorkloadTools Report - Template.pbit
├── Setup/
│   ├── Product.wxs
│   ├── Setup.wixproj
│   ├── SignMsi.ps1
│   ├── buildmsi.ps1
│   ├── postbuild.bat
│   ├── transform-nodirs.xsl
│   ├── transform.xsl
│   ├── transform2.xsl
│   └── transform3.xsl
├── SetupBootstrapper/
│   ├── Bundle.wxs
│   ├── License/
│   │   └── License.rtf
│   ├── SetupBootstrapper.wixproj
│   ├── SignMsi.ps1
│   ├── buildexe.ps1
│   └── postbuild.bat
├── SharedAssemblyInfo.cs
├── SqlWorkload/
│   ├── NLog.config
│   ├── Program.cs
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Resources.Designer.cs
│   │   └── Resources.resx
│   ├── SqlWorkload.csproj
│   ├── app.config
│   └── packages.config
├── WorkloadTools/
│   ├── BinarySerializedBufferedEventQueue.cs
│   ├── BufferedEventQueue.cs
│   ├── Config/
│   │   ├── AnalysisSample.json
│   │   ├── ReplaySample.json
│   │   ├── Sample.json
│   │   ├── SqlWorkloadConfig.cs
│   │   └── SqlWorkloadConfigTypeResolver.cs
│   ├── Consumer/
│   │   ├── Analysis/
│   │   │   ├── AnalysisConsumer.cs
│   │   │   ├── DatabaseSchema.sql
│   │   │   ├── NormalizedSqlText.cs
│   │   │   ├── SqlTextNormalizer.cs
│   │   │   ├── WorkloadAnalyzer.cs
│   │   │   └── createAnalysisView.sql
│   │   ├── BufferedWorkloadConsumer.cs
│   │   ├── Replay/
│   │   │   ├── ReplayCommand.cs
│   │   │   ├── ReplayConsumer.cs
│   │   │   ├── ReplayWorker.cs
│   │   │   ├── ReplayWorker.cs.bak
│   │   │   └── ResultSetConsumer.cs
│   │   ├── WorkloadConsumer.cs
│   │   └── WorkloadFile/
│   │       └── WorkloadFileWriterConsumer.cs
│   ├── CounterWorkloadEvent.cs
│   ├── DiskPerfWorkloadEvent.cs
│   ├── ErrorWorkloadEvent.cs
│   ├── ExecutionWorkloadEvent.cs
│   ├── FilterPredicate.cs
│   ├── GlobalSuppressions.cs
│   ├── IEventQueue.cs
│   ├── Listener/
│   │   ├── ExtendedEvents/
│   │   │   ├── ExtendedEventsEventFilter.cs
│   │   │   ├── ExtendedEventsFilterPredicate.cs
│   │   │   ├── ExtendedEventsWorkloadListener.cs
│   │   │   ├── FileTargetXEventDataReader.cs
│   │   │   ├── StreamXEventDataReader.cs
│   │   │   ├── XEventDataReader.cs
│   │   │   └── sqlworkload.sql
│   │   ├── File/
│   │   │   ├── FileEventFilter.cs
│   │   │   ├── FileFilterPredicate.cs
│   │   │   └── FileWorkloadListener.cs
│   │   ├── ReadIteration.cs
│   │   ├── SqlTransformer.cs
│   │   └── Trace/
│   │       ├── FileTraceEventDataReader.cs
│   │       ├── ProfilerEventFilter.cs
│   │       ├── ProfilerFilterPredicate.cs
│   │       ├── ProfilerWorkloadListener.cs
│   │       ├── SqlConnectionInfoWrapper.cs
│   │       ├── SqlTraceWorkloadListener.cs
│   │       ├── TraceEventDataReader.cs
│   │       ├── TraceEventFilter.cs
│   │       ├── TraceEventParser.cs
│   │       ├── TraceFileWrapper.cs
│   │       ├── TraceFilterPredicate.cs
│   │       ├── TraceServerWrapper.cs
│   │       ├── TraceUtils.cs
│   │       ├── sqlworkload.sql
│   │       └── sqlworkload.tdf
│   ├── MMFEventQueue.cs
│   ├── MessagWorkloadEvent.cs
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Settings.Designer.cs
│   │   ├── Settings.settings
│   │   └── SharedAssemblyInfo.cs
│   ├── SqlConnectionInfo.cs
│   ├── SqliteEventQueue.cs
│   ├── Util/
│   │   ├── DataUtils.cs
│   │   ├── ModelConverter.cs
│   │   ├── RingBuffer.cs
│   │   └── StringExtensions.cs
│   ├── WaitStatsWorkloadEvent.cs
│   ├── WorkloadController.cs
│   ├── WorkloadEvent.cs
│   ├── WorkloadEventFilter.cs
│   ├── WorkloadListener.cs
│   ├── WorkloadTools.csproj
│   ├── app.config
│   └── packages.config
├── WorkloadTools.sln
├── WorkloadToolsTests/
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── WorkloadTools/
│   │   ├── BinarySerializedBufferedEventQueueTest.cs
│   │   └── SqlTextNormalizerTest.cs
│   ├── WorkloadToolsTests.csproj
│   ├── app.config
│   └── packages.config
├── WorkloadViewer/
│   ├── App.config
│   ├── App.xaml
│   ├── App.xaml.cs
│   ├── Comparer/
│   │   └── QueryResultEqualityComparer.cs
│   ├── Model/
│   │   ├── NormalizedQuery.cs
│   │   ├── QueryDetails.cs
│   │   ├── SqlConnectionInfo.cs
│   │   ├── WorkloadAnalysis.cs
│   │   └── WorkloadAnalysisPoint.cs
│   ├── NLog.config
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Resources.Designer.cs
│   │   ├── Resources.resx
│   │   ├── Settings.Designer.cs
│   │   └── Settings.settings
│   ├── Resources/
│   │   ├── TSQL.xshd
│   │   └── WorkloadAnalysis.sql
│   ├── View/
│   │   ├── ConnectionInfoDialog.xaml
│   │   ├── ConnectionInfoDialog.xaml.cs
│   │   ├── ConnectionInfoDialogStyle.xaml
│   │   ├── ConnectionInfoEditor.xaml
│   │   ├── ConnectionInfoEditor.xaml.cs
│   │   ├── MainWindow.xaml
│   │   └── MainWindow.xaml.cs
│   ├── ViewModel/
│   │   ├── ConnectionInfoEditorViewModel.cs
│   │   ├── DictionaryExtensions.cs
│   │   ├── FilterDefinition.cs
│   │   ├── LinqExtensions.cs
│   │   ├── MainViewModel.cs
│   │   ├── Message.cs
│   │   ├── QueryResult.cs
│   │   ├── SortColMessage.cs
│   │   └── ViewModelLocator.cs
│   ├── WorkloadViewer.csproj
│   └── packages.config
└── build.ps1

================================================
FILE CONTENTS
================================================

================================================
FILE: .config/dotnet-tools.json
================================================
{
  "version": 1,
  "isRoot": true,
  "tools": {
    "wix": {
      "version": "4.0.5",
      "commands": [
        "wix"
      ]
    }
  }
}


================================================
FILE: .editorconfig
================================================
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true

# C# files
[*.cs]

#### Core EditorConfig Options ####

# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4

# New line preferences
end_of_line = crlf
insert_final_newline = false

#### .NET Coding Conventions ####

# Organize usings
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = true
file_header_template = unset

# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false

# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion

# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion

# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members

# Expression-level preferences
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true
dotnet_style_object_initializer = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_conditional_expression_over_assignment = true
dotnet_style_prefer_conditional_expression_over_return = true
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true

# Field preferences
dotnet_style_readonly_field = true

# Parameter preferences
dotnet_code_quality_unused_parameters = all

# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none

# New line preferences
dotnet_style_allow_multiple_blank_lines_experimental = true
dotnet_style_allow_statement_immediately_after_block_experimental = true

#### C# Coding Conventions ####

# var preferences
csharp_style_var_elsewhere = true:warning
csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning

# Expression-bodied members
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_constructors = when_on_single_line:silent
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
csharp_style_expression_bodied_local_functions = when_on_single_line:warning
csharp_style_expression_bodied_methods = when_on_single_line:silent
csharp_style_expression_bodied_operators = when_on_single_line:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning

# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:error
csharp_style_pattern_matching_over_is_with_cast_check = true:error
csharp_style_prefer_extended_property_pattern = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_pattern_matching = true:suggestion
csharp_style_prefer_switch_expression = true:warning

# Null-checking preferences
csharp_style_conditional_delegate_call = true:warning

# Modifier preferences
csharp_prefer_static_local_function = true:warning
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
csharp_style_prefer_readonly_struct = true:warning
csharp_style_prefer_readonly_struct_member = true:warning

# Code-block preferences
csharp_prefer_braces = true:warning
csharp_prefer_simple_using_statement = false:warning
csharp_style_namespace_declarations = block_scoped:warning
csharp_style_prefer_method_group_conversion = true:suggestion
csharp_style_prefer_top_level_statements = false:suggestion

# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_local_over_anonymous_function = true:suggestion
csharp_style_prefer_null_check_over_type_check = true:warning
csharp_style_prefer_range_operator = true:suggestion
csharp_style_prefer_tuple_swap = true:suggestion
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_throw_expression = false:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:warning
csharp_style_unused_value_expression_statement_preference = discard_variable:warning

# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:suggestion

# New line preferences
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent

#### C# Formatting Rules ####

# New line preferences
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true

# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true

# Space preferences
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_around_declaration_statements = false
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

# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true

#### Naming styles ####

# Naming rules

dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i

dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case

# Symbol specifications

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers = 

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers = 

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers = 

# Naming styles

dotnet_naming_style.pascal_case.required_prefix = 
dotnet_naming_style.pascal_case.required_suffix = 
dotnet_naming_style.pascal_case.word_separator = 
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix = 
dotnet_naming_style.begins_with_i.word_separator = 
dotnet_naming_style.begins_with_i.capitalization = pascal_case

[*.{cs,vb}]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_readonly_field = true:warning
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
dotnet_code_quality_unused_parameters = all:error
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion

================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs     diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following 
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln       merge=binary
#*.csproj    merge=binary
#*.vbproj    merge=binary
#*.vcxproj   merge=binary
#*.vcproj    merge=binary
#*.dbproj    merge=binary
#*.fsproj    merge=binary
#*.lsproj    merge=binary
#*.wixproj   merge=binary
#*.modelproj merge=binary
#*.sqlproj   merge=binary
#*.wwaproj   merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg   binary
#*.png   binary
#*.gif   binary

###############################################################################
# diff behavior for common document formats
# 
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the 
# entries below.
###############################################################################
#*.doc   diff=astextplain
#*.DOC   diff=astextplain
#*.docx  diff=astextplain
#*.DOCX  diff=astextplain
#*.dot   diff=astextplain
#*.DOT   diff=astextplain
#*.pdf   diff=astextplain
#*.PDF   diff=astextplain
#*.rtf   diff=astextplain
#*.RTF   diff=astextplain


================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
project.fragment.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
.nuget/nuget.exe

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush
.cr/

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
harvest.wxs
harvest2.wxs
harvest3.wxs
Setup/SignParams.ps1
SetupBootstrapper/SignParams.ps1
*.wixobj.nuget/nuget.exe
*.wixobj

================================================
FILE: ConvertWorkload/App.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.SqlServer.XE.Core" publicKeyToken="89845dcd8080cc91" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-14.100.0.0" newVersion="14.100.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>


================================================
FILE: ConvertWorkload/ConvertWorkload.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{62E37C03-BA08-46CE-A583-D71FB7A8825B}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>ConvertWorkload</RootNamespace>
    <AssemblyName>ConvertWorkload</AssemblyName>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
    <DefineConstants>TRACE;DEBUG</DefineConstants>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <OutputPath>bin\Debug\</OutputPath>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
    <OutputPath>bin\Release\</OutputPath>
    <Prefer32Bit>false</Prefer32Bit>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
    <OutputPath>bin\Release\</OutputPath>
    <Prefer32Bit>false</Prefer32Bit>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
    <OutputPath>bin\Debug\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
      <HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
    </Reference>
    <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
      <HintPath>..\packages\NLog.4.4.12\lib\net45\NLog.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data.SQLite, Version=1.0.112.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll</HintPath>
    </Reference>
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="..\SharedAssemblyInfo.cs">
      <Link>Properties\SharedAssemblyInfo.cs</Link>
    </Compile>
    <Compile Include="EventReader.cs" />
    <Compile Include="EventWriter.cs" />
    <Compile Include="ExtendedEventsEventReader.cs" />
    <Compile Include="LocalDBManager.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="SqlTraceEventReader.cs" />
    <Compile Include="WorkloadConverter.cs" />
    <Compile Include="WorkloadFileEventWriter.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config">
      <SubType>Designer</SubType>
    </None>
    <None Include="NLog.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\WorkloadTools\WorkloadTools.csproj">
      <Project>{ae6e4548-8c33-4728-8504-88aa9666020b}</Project>
      <Name>WorkloadTools</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="..\packages\System.Data.SQLite.Core.1.0.109.2\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.109.2\build\net46\System.Data.SQLite.Core.targets')" />
  <Import Project="..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets')" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets'))" />
  </Target>
</Project>

================================================
FILE: ConvertWorkload/EventReader.cs
================================================
using System;
using WorkloadTools;

namespace ConvertWorkload
{
    public abstract class EventReader : IDisposable
    {
        private WorkloadEventFilter _filter;

        public string[] ApplicationFilter { get; set; }
        public string[] DatabaseFilter { get; set; }
        public string[] HostFilter { get; set; }
        public string[] LoginFilter { get; set; }

        protected bool stopped;
        protected IEventQueue Events;

        protected WorkloadEventFilter Filter
        {
            get
            {
                if (_filter != null)
                {
                    _filter.ApplicationFilter.PredicateValue = ApplicationFilter;
                    _filter.DatabaseFilter.PredicateValue = DatabaseFilter;
                    _filter.HostFilter.PredicateValue = HostFilter;
                    _filter.LoginFilter.PredicateValue = LoginFilter;
                    return _filter;
                }
                else
                {
                    return null;
                }
            }
            set
            {
                _filter = value;
            }
        }

        public abstract bool HasFinished();

        public abstract WorkloadEvent Read();

        public abstract bool HasMoreElements();

        public void Dispose()
        {
            stopped = true;
            Events.Dispose();
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void Dispose(bool disposing);
    }
}

================================================
FILE: ConvertWorkload/EventWriter.cs
================================================
using System;
using WorkloadTools;

namespace ConvertWorkload
{
    public abstract class EventWriter : IDisposable
    {
        protected bool stopped;

        public abstract void Write(WorkloadEvent evt);

        public void Dispose()
        {
            stopped = true;
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void Dispose(bool disposing);

    }
}

================================================
FILE: ConvertWorkload/ExtendedEventsEventReader.cs
================================================
using NLog;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkloadTools;
using WorkloadTools.Listener;
using WorkloadTools.Listener.ExtendedEvents;
using WorkloadTools.Util;

namespace ConvertWorkload
{
 
    public class ExtendedEventsEventReader : EventReader
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();

        private string filePath;
        private bool started = false;
        private bool finished = false;

        private FileTargetXEventDataReader reader;

        public ExtendedEventsEventReader(string path)
        {
            Events = new BinarySerializedBufferedEventQueue();
            Events.BufferSize = 10000;
            filePath = path;
            Filter = new ExtendedEventsEventFilter();
        }


        private void ReadEventsFromFile()
        {
            try
            {
                var info = new SqlConnectionInfo();
                info.ServerName = "(localdb)\\MSSQLLocalDB";

                var sqlCreateTable = @"
                    IF OBJECT_ID('tempdb.dbo.trace_reader_queue') IS NULL
                    BEGIN
                        CREATE TABLE tempdb.dbo.trace_reader_queue (
                            ts datetime DEFAULT GETDATE(),
                            path nvarchar(4000)
                        )
                    END
                    TRUNCATE TABLE tempdb.dbo.trace_reader_queue;
                    INSERT INTO tempdb.dbo.trace_reader_queue (path) VALUES(@path);
                ";

                using (var conn = new SqlConnection())
                {
                    conn.ConnectionString = info.ConnectionString();
                    conn.Open();
                    using (var cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = sqlCreateTable;
                        var prm = new SqlParameter()
                        {
                            ParameterName = "@path",
                            DbType = System.Data.DbType.String,
                            Size = 4000,
                            Value = filePath
                        };
                        cmd.Parameters.Add(prm);
                        cmd.ExecuteNonQuery();
                    }
                }

                reader = new FileTargetXEventDataReader(info.ConnectionString(), null, Events, ExtendedEventsWorkloadListener.ServerType.LocalDB);
                reader.ReadEvents();
                finished = true;
                    
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message);

                if (ex.InnerException != null)
                {
                    logger.Error(ex.InnerException.Message);
                }

                Dispose();
            }
        }


        public override bool HasFinished()
        {
            return finished && !Events.HasMoreElements();
        }

        public override bool HasMoreElements()
        {
            return !finished && !stopped && (started ? Events.HasMoreElements() : true);
        }

        public override WorkloadEvent Read()
        {
            if (!started)
            {
                var t = Task.Factory.StartNew(ReadEventsFromFile);
                started = true;
            }

            WorkloadEvent result = null;
            while (!Events.TryDequeue(out result))
            {
                if (stopped || finished)
                {
                    return null;
                }

                Thread.Sleep(5);
            }
            return result;
        }

        protected override void Dispose(bool disposing)
        {
            if (!stopped)
            {
                stopped = true;
                reader.Stop();
                reader.Dispose();
            }
        }

    }

}


================================================
FILE: ConvertWorkload/LocalDBManager.cs
================================================
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using WorkloadTools;

namespace ConvertWorkload
{
    internal class LocalDBManager
    {

        public bool IsElevated
        {
            get
            {
                return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
            }
        }

        public string DownloadLocalDB()
        {
            var localPath = Path.GetTempPath() + "SqlLocalDB.msi";
            using (var client = new WebClient())
            {
                var wp = WebRequest.DefaultWebProxy;
                wp.Credentials = CredentialCache.DefaultCredentials;
                client.Proxy = wp;
                client.DownloadFile("https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SqlLocalDB.msi", localPath);
            }
            return localPath;
        }


        public void InstallLocalDB()
        {
            if (!IsElevated)
            {
                throw new InvalidOperationException("Installing LocalDB requires elevation.");
            }
            var localFileName = DownloadLocalDB();
            var p = new Process();
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.FileName = "c:\\windows\\system32\\msiexec.exe";
            p.StartInfo.Arguments = " /i "+ localFileName +" /qn IACCEPTSQLLOCALDBLICENSETERMS=YES";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            //Vista or higher check
            if (System.Environment.OSVersion.Version.Major >= 6)
            {
                p.StartInfo.Verb = "runas";
            }
            p.Start();
            p.WaitForExit();
        }

        public bool CanConnectToLocalDB()
        {
            try
            {
                var info = new SqlConnectionInfo();
                info.ServerName = @"(localdb)\MSSQLLocalDB";
                info.UseIntegratedSecurity = true;
                using (var conn = new SqlConnection(info.ConnectionString() + ";Connect Timeout=30;"))
                {
                    conn.Open();
                }
                return true;
            }
            catch(Exception)
            {
                return false;
            }
        }


    }
}


================================================
FILE: ConvertWorkload/NLog.config
================================================
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">


  <targets>
    <target name="logfile" xsi:type="File" fileName="ConvertWorkload.log" layout="${longdate} - ${level} - ${logger} : ${message}" />
    <target name="warnfile" xsi:type="File" fileName="Warnings.log" layout="${longdate} - ${message}" />
    <target name="console" xsi:type="Console" layout="${level} - ${logger} : ${message}"/>
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="logfile" />
    <logger name="*" minlevel="Info" writeTo="console" />
    <logger name="*" levels="Warn" writeTo="warnfile" />
  </rules>
</nlog>


================================================
FILE: ConvertWorkload/Program.cs
================================================
using CommandLine;
using CommandLine.Text;
using NLog;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkloadTools.Listener.Trace;

namespace ConvertWorkload
{
    class Program
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        private static CancellationTokenSource source;


        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(GenericErrorHandler);
            GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
            var version = fvi.FileMajorPart.ToString() + "." + fvi.FileMinorPart.ToString() + "." + fvi.FileBuildPart.ToString();
            var name = assembly.FullName;
            logger.Info(name + " " + version);


            try
            {
                var options = new Options();
                if (!CommandLine.Parser.Default.ParseArguments(args, options))
                {
                    
                    return;
                }
                Run(options);
            }
            catch (Exception e)
            {
                logger.Error(e);
            }
        }

        private static void Run(Options options)
        {
            // reconfigure loggers to use a file in the current directory
            // or the file specified by the "Log" commandline parameter
            if(LogManager.Configuration != null)
            {
                var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
                if (target != null)
                {
                    var pathToLog = options.LogFile;
                    if (pathToLog == null)
                    {
                        pathToLog = Path.Combine(Environment.CurrentDirectory, "ConvertWorkload.log");
                    }
                    if (!Path.IsPathRooted(pathToLog))
                    {
                        pathToLog = Path.Combine(Environment.CurrentDirectory, pathToLog);
                    }
                    target.FileName = pathToLog;
                    LogManager.ReconfigExistingLoggers();
                }
            }

            // check whether localdb is installed
            logger.Info("Checking LocalDB...");
            var manager = new LocalDBManager();
            if (!manager.CanConnectToLocalDB())
            {
                logger.Info("Installing LocalDB...");
                try
                {
                    manager.InstallLocalDB();
                }
                catch (InvalidOperationException)
                {
                    logger.Error("This operation requires elevation. Restart the application as an administrator.");
                    return;
                }
            }

            EventReader reader = null;
            if (options.InputFile.EndsWith(".trc"))
            {
                reader = new SqlTraceEventReader(options.InputFile);
            }
            else 
            {
                reader = new ExtendedEventsEventReader(options.InputFile);
            }
            EventWriter writer = new WorkloadFileEventWriter(options.OutputFile);
            var converter = new WorkloadConverter(reader, writer);
            if(options.ApplicationFilter != null)
            {
                converter.ApplicationFilter = new string[1] { options.ApplicationFilter };
            }

            if (options.DatabaseFilter != null)
            {
                converter.DatabaseFilter = new string[1] { options.DatabaseFilter };
            }

            if (options.HostFilter != null)
            {
                converter.HostFilter = new string[1] { options.HostFilter };
            }

            if (options.LoginFilter != null)
            {
                converter.LoginFilter = new string[1] { options.LoginFilter };
            }

            Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) {
                e.Cancel = true;
                logger.Info("Received shutdown signal...");
                source.CancelAfter(TimeSpan.FromSeconds(10)); // give a 10 seconds cancellation grace period 
                converter.Stop();
            };

            var t = processConverter(converter);
            t.Wait();
            logger.Info("Converter stopped.");
        }

        public static void CancelNotification()
        {
            logger.Info("Shutdown complete.");
        }

        public static async Task processConverter(WorkloadConverter converter)
        {
            source = new CancellationTokenSource();
            source.Token.Register(CancelNotification);
            var completionSource = new TaskCompletionSource<object>();
            source.Token.Register(() => completionSource.TrySetCanceled());
            var task = Task.Factory.StartNew(() => converter.Convert(), source.Token);
            await Task.WhenAny(task, completionSource.Task);
        }

        static void GenericErrorHandler(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                logger.Error(e.ToString());
            }
            finally
            {
                Console.WriteLine("Caught unhandled exception...");

            }
        }
    }


    class Options
    {
        [Option('L', "Log", HelpText = "Log file")]
        public string LogFile { get; set; }

        [Option('I', "Input", HelpText = "Input file", Required = true)]
        public string InputFile { get; set; }

        [Option('O', "Output", HelpText = "Output file", Required = true)]
        public string OutputFile { get; set; }

        [Option('A', "ApplicationFilter", HelpText = "Application filter")]
        public string ApplicationFilter { get; set; }

        [Option('D', "DatabaseFilter", HelpText = "Database filter")]
        public string DatabaseFilter { get; set; }

        [Option('H', "HostFilter", HelpText = "Host Filter")]
        public string HostFilter { get; set; }

        [Option('U', "LoginFilter", HelpText = "Login Filter")]
        public string LoginFilter { get; set; }

        [ParserState]
        public IParserState LastParserState { get; set; }

        [HelpOption]
        public string GetUsage()
        {
            return HelpText.AutoBuild(this,
              (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
        }

    }
}


================================================
FILE: ConvertWorkload/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;


// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("62e37c03-ba08-46ce-a583-d71fb7a8825b")]


================================================
FILE: ConvertWorkload/SqlTraceEventReader.cs
================================================
using NLog;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkloadTools;
using WorkloadTools.Listener;
using WorkloadTools.Listener.Trace;

namespace ConvertWorkload
{
    public class SqlTraceEventReader : EventReader
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();

        private string tracePath;
        private bool started = false;
        private bool finished = false;

        private FileTraceEventDataReader reader;

        public SqlTraceEventReader(string path)
        {
            Events = new BinarySerializedBufferedEventQueue();
            Events.BufferSize = 10000;
            tracePath = path;
            Filter = new TraceEventFilter();
        }


        private void ReadEventsFromFile()
        {
            try
            {
                var info = new SqlConnectionInfo();
                info.ServerName = "(localdb)\\MSSQLLocalDB";

                var sqlCreateTable = @"
                    IF OBJECT_ID('tempdb.dbo.trace_reader_queue') IS NULL
                    BEGIN
                        CREATE TABLE tempdb.dbo.trace_reader_queue (
                            ts datetime DEFAULT GETDATE(),
                            path nvarchar(4000)
                        )
                    END
                    TRUNCATE TABLE tempdb.dbo.trace_reader_queue;
                    INSERT INTO tempdb.dbo.trace_reader_queue (path) VALUES(@path);
                ";
                
                using(var conn = new SqlConnection())
                {
                    conn.ConnectionString = info.ConnectionString();
                    conn.Open();
                    using(var cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = sqlCreateTable;
                        var prm = new SqlParameter()
                        {
                            ParameterName = "@path",
                            DbType = System.Data.DbType.String,
                            Size = 4000,
                            Value = tracePath
                        };
                        cmd.Parameters.Add(prm);
                        cmd.ExecuteNonQuery();
                    }
                }

                reader = new FileTraceEventDataReader(info.ConnectionString(), Filter, Events);
                reader.ReadEvents();
                finished = true;
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message);

                if (ex.InnerException != null)
                {
                    logger.Error(ex.InnerException.Message);
                }

                Dispose();
            }

        }

        public override WorkloadEvent Read()
        {
            if (!started)
            {
                var t = Task.Factory.StartNew(ReadEventsFromFile);
                started = true;
            }

            WorkloadEvent result = null;
            while (!Events.TryDequeue(out result))
            {
                if (stopped || finished)
                {
                    return null;
                }

                Thread.Sleep(5);
            }
            return result;
        }

        protected override void Dispose(bool disposing) 
        {
            if (!stopped)
            {
                stopped = true;
                reader.Stop();
                reader.Dispose();
            }
        }

        public override bool HasMoreElements()
        {
            return !finished && !stopped && (started ? Events.HasMoreElements() : true);
        }

        public override bool HasFinished()
        {
            return finished && !Events.HasMoreElements();
        }
    }
}


================================================
FILE: ConvertWorkload/WorkloadConverter.cs
================================================
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WorkloadTools;

namespace ConvertWorkload
{
    public class WorkloadConverter
    {

        private static Logger logger = LogManager.GetCurrentClassLogger();

        private EventReader reader;
        private EventWriter writer;
        private bool stopped = false;

        public string[] ApplicationFilter { get; set; }
        public string[] DatabaseFilter { get; set; }
        public string[] HostFilter { get; set; }
        public string[] LoginFilter { get; set; }

        public WorkloadConverter(EventReader reader, EventWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Convert()
        {
            try
            {
                if (ApplicationFilter != null)
                {
                    reader.ApplicationFilter = ApplicationFilter;
                }

                if (DatabaseFilter != null)
                {
                    reader.DatabaseFilter = DatabaseFilter;
                }

                if (HostFilter != null)
                {
                    reader.HostFilter = HostFilter;
                }

                if (LoginFilter != null)
                {
                    reader.LoginFilter = LoginFilter;
                }

                while ((!reader.HasFinished() || reader.HasMoreElements()) && !stopped)
                {
                    writer.Write(reader.Read());
                }
            }
            catch(Exception ex)
            {
                stopped = true;
                logger.Error(ex);
            }
            finally
            {
                Stop();
            }
        }

        public void Stop()
        {
            stopped = true;
            reader.Dispose();
            writer.Dispose();
        }
    }
}


================================================
FILE: ConvertWorkload/WorkloadFileEventWriter.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WorkloadTools;
using WorkloadTools.Consumer.WorkloadFile;

namespace ConvertWorkload
{
    public class WorkloadFileEventWriter : EventWriter
    {
        private WorkloadFileWriterConsumer consumer;

        public WorkloadFileEventWriter(string outputPath)
        {
            consumer = new WorkloadFileWriterConsumer()
            {
                OutputFile = outputPath
            };
        }

        public override void Write(WorkloadEvent evt)
        {
            consumer.Consume(evt);
        }

        protected override void Dispose(bool disposing)
        {
            consumer.Dispose();
        }
    }
}


================================================
FILE: ConvertWorkload/packages.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="CommandLineParser" version="1.9.71" targetFramework="net461" />
  <package id="Microsoft.SqlServer.SqlManagementObjects" version="140.17283.0" targetFramework="net461" />
  <package id="NLog" version="4.4.12" targetFramework="net461" />
  <package id="System.Collections" version="4.0.11" targetFramework="net461" />
  <package id="System.Console" version="4.0.0" targetFramework="net461" />
  <package id="System.Data.SQLite.Core" version="1.0.112.0" targetFramework="net461" />
  <package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="net461" />
  <package id="System.Globalization" version="4.0.11" targetFramework="net461" />
  <package id="System.IO" version="4.1.0" targetFramework="net461" />
  <package id="System.Linq" version="4.1.0" targetFramework="net461" />
  <package id="System.Linq.Expressions" version="4.1.0" targetFramework="net461" />
  <package id="System.Reflection" version="4.1.0" targetFramework="net461" />
  <package id="System.Reflection.Extensions" version="4.0.1" targetFramework="net461" />
  <package id="System.Reflection.TypeExtensions" version="4.1.0" targetFramework="net461" />
  <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net461" />
  <package id="System.Runtime" version="4.1.0" targetFramework="net461" />
  <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net461" />
</packages>

================================================
FILE: DebuggingTools/capture.json
================================================
{
    "Controller": {

        "Listener":
        {
            "__type": "SqlTraceWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "localhost"
            },
            "DatabaseFilter": "benchmark",
            "ApplicationFilter": "testapp",
            "TimeoutMinutes": 10
        },

        "Consumers":
        [
            {
                "__type": "WorkloadFileWriterConsumer",
                "OutputFile": "C:\\temp\\WorkloadTools\\debug\\capture.sqlite"
            }
            ,{
                "__type": "AnalysisConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "(local)",
                    "DatabaseName": "benchmark_analysis",
                    "SchemaName": "test"
                },
                "UploadIntervalSeconds": 60
            }
        ]
    }
}

================================================
FILE: DebuggingTools/capture_trace.json
================================================
{
    "Controller": {

        "Listener":
        {
            "__type": "SqlTraceWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "localhost"
            },
            "DatabaseFilter": "benchmark",
            "TraceRolloverCount": 100,
            "TimeoutMinutes": 10
        },

        "Consumers":
        [
            {
                "__type": "WorkloadFileWriterConsumer",
                "OutputFile": "C:\\temp\\WorkloadTools\\debug\\capture.sqlite"
            }
            ,{
                "__type": "AnalysisConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "(local)",
                    "DatabaseName": "benchmark_analysis",
                    "SchemaName": "test"
                },
                "UploadIntervalSeconds": 60
            }
        ]
    }
}

================================================
FILE: DebuggingTools/capture_xel.json
================================================
{
    "Controller": {

        "Listener":
        {
            "__type": "ExtendedEventsWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "localhost"
            },
            "ApplicationFilter": "testapp",
            "FileTargetPath": "C:\\temp\\WorkloadTools\\debug\\capture.xel"
        },

        "Consumers":
        [
            {
                "__type": "WorkloadFileWriterConsumer",
                "OutputFile": "C:\\temp\\WorkloadTools\\debug\\capture.sqlite"
            }
            ,{
                "__type": "AnalysisConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "(local)",
                    "DatabaseName": "benchmark_analysis",
                    "SchemaName": "test"
                },
                "UploadIntervalSeconds": 60
            }
        ]
    }
}

================================================
FILE: DebuggingTools/generate-allWorkload.bat
================================================
del "c:\temp\workloadtools\debug\capture.sqlite"
sqlcmd -S(local) -dbenchmark -Q"TRUNCATE TABLE dbo.benchmark"
start "" powershell -File .\generate-workload.ps1 -start 0
start "" powershell -File .\generate-workload.ps1 -start 1000000
start "" powershell -File .\generate-workload.ps1 -start 2000000
start "" powershell -File .\generate-workload.ps1 -start 3000000
start "" powershell -File .\generate-workload.ps1 -start 4000000
start "" powershell -File .\generate-workload.ps1 -start 5000000

================================================
FILE: DebuggingTools/generate-workload.ps1
================================================
param (
    [int]$start
)
Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$connectionString = "Data Source=(local);Integrated Security=SSPI;Initial Catalog=benchmark;Application Name=testapp"

$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$connection.Open()

$command = new-object system.data.sqlclient.sqlcommand("INSERT INTO benchmark VALUES(@p0)",$connection)
$command.Parameters.AddWithValue("@p0",0) | Out-Null

for($i = $start; $i -lt ($start + 100000); $i++) {
    $command.Parameters[0].Value = $i
    $command.ExecuteNonQuery() | Out-Null
    if($i % 1000 -eq 0) {$i}
}
$i

$connection.Close()
Get-Date -Format "yyyy-MM-dd HH:mm:ss"

================================================
FILE: DebuggingTools/replay.json
================================================
{
    "Controller": {
 
        "Listener":
        {
            "__type": "FileWorkloadListener",
            "Source": "C:\\temp\\workloadtools\\debug\\capture.sqlite",
            // in this case you want to simulate the original query rate
            "SynchronizationMode": "true"
        },
 
        "Consumers":
        [
            {
                "__type": "ReplayConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "(local)",
                    "DatabaseName": "benchmark"
                },
                "ConsumeResults": "false"
            }
        ]
    }
}

================================================
FILE: DebuggingTools/report.bat
================================================
"c:\Program Files\WorkloadTools\WorkloadViewer.exe" --BaselineServer (local) --BaselineSchema test --BaselineDatabase benchmark_analysis

================================================
FILE: DebuggingTools/setup.bat
================================================
sqlcmd -S(local) -Q"CREATE DATABASE benchmark"
sqlcmd -S(local) -dbenchmark -Q"CREATE TABLE dbo.benchmark ( i int NULL )"
sqlcmd -S(local) -Q"CREATE DATABASE benchmark_analysis"

mkdir c:\temp
mkdir c:\temp\workloadtools
mkdir c:\temp\workloadtools\debug

================================================
FILE: DebuggingTools/start-capture.bat
================================================
del "c:\temp\workloadtools\debug\capture.sqlite"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Applications"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Databases"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Errors"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Hosts"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Intervals"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Logins"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.NormalizedQueries"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WaitStats"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WorkloadDetails"
"c:\program files\workloadtools\sqlworkload.exe" --File "%CD%\capture.json"

================================================
FILE: DebuggingTools/start-capture_trace.bat
================================================
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Applications"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Databases"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Errors"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Hosts"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Intervals"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Logins"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.NormalizedQueries"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WaitStats"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WorkloadDetails"
"c:\program files\workloadtools\sqlworkload.exe" --File "%CD%\capture_trace.json"

================================================
FILE: DebuggingTools/start-capture_xel.bat
================================================
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Applications"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Databases"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Errors"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Hosts"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Intervals"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Logins"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.NormalizedQueries"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WaitStats"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WorkloadDetails"
"c:\program files\workloadtools\sqlworkload.exe" --File "%CD%\capture_xel.json"

================================================
FILE: DebuggingTools/start-replay.bat
================================================
echo %time%
sqlcmd -S(local) -dbenchmark -Q"TRUNCATE TABLE benchmark"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Applications"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Databases"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Errors"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Hosts"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Intervals"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.Logins"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.NormalizedQueries"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WaitStats"
sqlcmd -S(local) -dbenchmark_analysis -Q"TRUNCATE TABLE test.WorkloadDetails"
"c:\program files\workloadtools\sqlworkload.exe" --File "%CD%\replay.json"
echo %time%

================================================
FILE: LICENSE.md
================================================
MIT License

Copyright (c) 2018 Gianluca Sartori

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
![](https://countrush-prod.azurewebsites.net/l/badge/?repository=spaghettidba.WorkloadTools)
# WorkloadTools

*WorkloadTools is a collection of tools to collect, analyze and replay SQL Server workloads, on premises and in the cloud .*

## Download

Go to the [release page](https://github.com/spaghettidba/WorkloadTools/releases/latest) and download the msi installer for your target bitness (x86 or x64) 

## Documentation

If you're looking for detailed documentation on the individual tools, please have a look at the [Wiki](https://github.com/spaghettidba/WorkloadTools/wiki)

If you're looking for usage scenarios and examples, see the [posts tagged WorkloadTools at my blog](https://spaghettidba.com/tag/workloadtools/)

## SqlWorkload

SqlWorkload is a command line tool to start workload collection, analyze the collected data and replay the workload to a target machine, all in real-time.

SqlWorkload can connect to a SQL Server instance and capture execution related events via SqlTrace or Extended Events. These events are processed and passed to "consumers" that can replay the events to a target instance in real-time and analyze the statements. 
All the batches are "normalized" (parameters and constants are stripped away) and metrics are calculated on each normalized batch, like cpu, duration, reads and writes.

During the analysis, additional metrics are captured and saved regularly to the analysis database:

- cpu usage
- wait stats

### Replaying and analyzing a production workload in test

If you want to compare the execution of the same workload on two different machines, you can point a first instance of SqlWorkload to your production server: SqlWorkload will analyze the workload and write the metrics to a database of your choice.
It will also replay the workload to a test server, where you can point a second instance of SqlWorkload to obtain the same metrics. This second instance of SqlWorkload will not perform the replay, but it will only perform the workload analysis and write it to the same database where you stored the metrics relative to production (possibly on a different schema).

Once you have captured and replayed the workload for a representative enough time, you can stop the two instances of SqlWorkload and analyze the data using the included Workload Analyzer or PowerBI dashboard.

### Command line switches

SqlWorkload accepts two command line switches:

`--Log` Path to the log file

`--File` Path to the `.JSON` configuration file

In fact, SqlWorkload supports a multitude of parameters and specifying them all in the command line can become really tedious. For this reason, SqlWorkload supports `.JSON` configuration files.

This is a sample configuration file. Please refer to [the documentation](https://github.com/spaghettidba/WorkloadTools/wiki) to see the full list of available configuration options.

```javascript
{
    "Controller": {

        // The Listener section describes how to capture the events
        "Listener":
        {
            // The main parameter here is the class type of the Listener
            "__type": "ExtendedEventsWorkloadListener",

            // The ConnectionInfo describes how to connect the Listener
            "ConnectionInfo":
            {
                "ServerName": "SQLDEMO\\SQL2014",
                // If you omit the UserName/Password, Windows authentication
                // will be used
                "UserName": "sa",
                "Password": "P4$$w0rd!"
            },

            // Filters for the workload
            "DatabaseFilter": "DS3",
            "ApplicationFilter" : "SomeAppName",
            "HostFilter" : "MyComputer",
            "LoginFilter": "sa"
        },

        // This section contains the list of the consumers
        // The list can contain 0 to N consumers of different types
        "Consumers":
        [
            {
                // This is the type of the consumer
                "__type": "ReplayConsumer",

                // The same considerations for ConnectionInfo
                // valid for the Listener apply here as well
                "ConnectionInfo":
                {
                    "ServerName": "SQLDEMO\\SQL2016",
                    "DatabaseName": "DS3",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                }
            },
            {
                // Here is another example with the AnalysisConsumer
                "__type": "AnalysisConsumer",

                // ConnectionInfo
                "ConnectionInfo": 
                {
                    "ServerName": "SQLDEMO\\SQL2016",
                    "DatabaseName": "DS3",
                    // This "SchemaName" parameter is important, because it 
                    // decides where the analysis data is written to
                    "SchemaName": "baseline",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                },

                // This decides how often the metrics are aggregated and 
                // written to the target database
                "UploadIntervalSeconds": 60
            }
        ]
    }
}
```

## WorkloadViewer

WorkloadViewer is a GUI tool to analyze the data collected by the WorkloadAnalysisTarget in a SQL Server database. It shows metrics about the workload, relative to the beginning of the capture (in minutes).

Here are some screenshots of WorkloadViewer. 

### Workload

The three charts in the "Workload" tab show an overview of the workload analysis: CPU, Duration and Batches/sec. Two workloads can be compared by displaying independent series (Baseline and Benchmark) for each workload.

![SqlWorkload analysis Overview](./Images/SqlWorkloadOverview.png "Overview")

### Queries

This tab displays information about the queries and how they relate to the workload. For a single workload analysis, it shows the most expensive queries. When comparing two workloads, it can be used to identify query regressions.

![SqlWorkload regressed queries](./Images/SqlWorkloadRegresses.png "RegressedQueries")

### Query Details

Double clicking a query in the "Queries" tab takes you to the "Query Details" tab, where you can see the text of the selected query, specific statistics by application, database, host and login and the average duration in a chart.

![SqlWorkload query detail](./Images/SqlWorkloadDetail.png "Detail")

## ConvertWorkload

ConvertWorkload is a command line tool to convert existing trace files to the internal SQLite format used by WorkloadTools. In the future, ConvertWorkload will also support conversion from existing Extended Events files.

Why converting trace file to a different intermediate format instead of supporting it directly? Trace files can be read using an API that works only in x86. While WorkloadTools **can** work in x86, using x64 builds is highly recommended, due to the possible high memory usage when capturing intensive workloads. Using a x86 API would have excluded the functionality from the x64 builds, hence using an external tool to convert trace files seems much more appropriate.

### Command line switches

```text
-I or --Input               The input file (trace or extended events) to convert

-O or --Output              The output SQLite file to write

-L or --Log                 Specifies where to save the log file

-A or --ApplicationFilter   Application filter to apply while converting the source file

-D or --DatabaseFilter      Database filter to apply while converting the source file

-H or --HostFilter          Host filter to apply while converting the source file

-U or --LoginFilter         Login filter to apply while converting the source file
```


================================================
FILE: Reports/README.md
================================================
# WorkloadTools Power BI Report

To analyze the data produced by WorkloadTools you can use the provided Power BI Template.

In this folder you will find:
* A Sample Power Bi report "WorkloadTools Report - Sample.pbix", use it play with the report
* The Power BI template "WorkloadTools Report - Template.pbit", which defines a report structure and will ask for some input parameters before it loading data.

## Overview of the report pages
![Overview](/Images/PowerBI_Overview.png)
![WeightOnTotal](/Images/PowerBI_WeightOnTotal.png)
![Queries](/Images/PowerBI_Queries.png)
![QueryDetail](/Images/PowerBI_QueryDetail.png)
![WaitStats](/Images/PowerBI_WaitStats.png)


## Usage
1. Download and install Power BI Desktop
2. Open the provided template "WorkloadTools Report - Template.pbit" 
3. Provide the connection parameters
4. Explore your data
5. (optional) Save the file for later use, it won't ask again for the parameters

The report allows you to load one or two series of data, if you want to visualize only one series leave the optional parameters ("Benchmark") empty

Required parameters:
* Baseline Server\Instance
* Baseline Database
* Baseline Schema

Optional parameters:
* Benchmark Server\Instance
* Benchmark Database
* Benchmark Schema

![Input Parameters](/Images/PowerBI_InputParams.png)

**Note:**

When using only one serie of data some charts and metrics will be empty, the deltas won't be meaningful.


### Using "Drillthrough" for "Query Detail"

In order to correctly filter the "Query Detail" sheet you need to use the "Drillthrough" function of Power BI.
This function is available on any visual that contains a specific fields (in this case "Sql Hash") and has a properly configured Drillthrough page.

ie: on the "Queries" page you can find several tables with the field "Sql Hash", right click it and choose "Drillthrough", you will now see the available drillthrough pages, if you click the page, it will show up, filtered by the selected "Sql Hash".
To go back to the previous page you can use the arrow in the top-left corner of the page.

![Drillthrough](/Images/PowerBI_DrillThrough.png)

## Authentication

When connecting to the specified source or sources (if the data are on 2 different server/databases) power Bi will use windows authentication.
If the current user does not have the permission to access the data the load will fail.
To use different credentials you will need to:
* Run the Power BI template
* Save it as a report even if it fails to load the data
* Go to: "File -> options and settings -> data source settings" select the datasource and click "edit permission" now you can set the authentication method and credentials

## Use the Power BI Report on Existing Databases

**What if I already have the data and just want to use the Power BI report?**

Power BI needs a bunch of views in order to load the data, those views are created when some workload data are written to the db for the first time.

You can manually create the views by running the procedure in this folder:
[WorkloadTools\Consumer\Analysis\createAnalysisView.sql](/WorkloadTools/Consumer/Analysis/createAnalysisView.sql)

```
--At least one of the two parameters must be provided, the schema must be the same of your data tables
EXEC [dbo].[createAnalysisView]	@baselineSchema = N'<BaselineSchemaName>', @replaySchema = N'<BenchmarkSchemaName>'
```

## Additional Suggestions

Power BI Desktop does not offer a "wiewer mode", it has been made to create and edit reports. Anyone with the file has full control over it, and can create/edit/delete any visual or measure in the frontend or tables, relationships and M script in the backend.

In order to make the report more usable on Power BI Desktop you can set the following
* **Lock Objects** - this prevents them from moving around while using the report (in the top bar "View" → "Lock Objects" checkbox)
* **Collapse Unused Bars** - this allows you to recover plently of space to view the report, you can collapse the side-bars and the top bar (small arrow i the top right corner)

## Notes For Editors and Curious

If you are new to Power BI and want to make some changes, make your own report or simply know how the report works you may need to know the following

* **Hidden Objects** - to have a more readable report only the strictly necessary is visible in the "Field" panel, some tables, columns and measures (formulas) are hidden. To view them expand the "Field" side-bar, right click and enable "View hidden"
* **Time Field** - For how the Power BI model works:
    * **always** use the field [Elapsed Time (min)] of the "Time" table in any visual that displayes the trend by time (or use the time in general)
    * Any other [Elapsed Time (min)] Field (there is one in almost every table, set as hidden) will not propagate the filter correctly. If used you will obtain flat charts and static numbers



================================================
FILE: Setup/Product.wxs
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <?if $(var.Platform) = x64 ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
  <?else ?>
    <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
  <?endif ?>

  <?define ProductName="WorkloadTools" ?>
  <?define CompanyName="sqlconsulting.it" ?>
  <?define ProductVersion="$(var.BuildVersion)" ?>

  <Product Id="*" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)"
           Manufacturer="$(var.CompanyName)" UpgradeCode="EF0F1905-E03F-4634-BB2E-3A5C3369AB23">

    <Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade AllowDowngrades="yes" />
    <MediaTemplate EmbedCab="yes" />

    <Property Id="REINSTALLMODE" Value="amus" />

    <!--
      These component groups are generated by heat.exe in buildmsi.ps1.
      XSL transforms (transform.xsl, transform2.xsl, transform3.xsl) filter
      out duplicate and unwanted files across the component groups.
    -->
    <Feature Id="ProductFeature" Title="WorkloadTools" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
      <ComponentGroupRef Id="WorkloadViewerComponents" />
      <ComponentGroupRef Id="ProductReports" />
      <ComponentGroupRef Id="ConvertWorkloadComponents" />
    </Feature>

  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="$(var.PlatformProgramFilesFolder)">
        <Directory Id="INSTALLFOLDER" Name="WorkloadTools" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <DirectoryRef Id="INSTALLFOLDER">
      <Directory Id="dirCD80900D3B5A452B876D2B896E10F051" Name="Reports" />
    </DirectoryRef>
  </Fragment>
  <Fragment>
    <ComponentGroup Id="ProductReports">
      <Component Id="cmp20EE999FA46842A8A3E67D82FF987418" Directory="dirCD80900D3B5A452B876D2B896E10F051" Guid="9CDDBDE3-A115-4CEE-9F5F-41DCCABB618E">
        <File Id="filF8339E0B13434A31BB913FADC4066D7D" Source="..\Reports\WorkloadTools Report - Sample.pbix" />
        <File Id="fil9A72942DD7E14FC98051DF6EAA302AF0" Source="..\Reports\WorkloadTools Report - Template.pbit" />
        <File Id="filB480F52C6274410197E5CB8F865AE5BB" Source="..\Reports\README.md" />
      </Component>
    </ComponentGroup>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductLicense">
      <Component Id="cmpE591726ED3774E44B75D7106236DD456" Directory="INSTALLFOLDER" Guid="2CA2DACC-347C-449E-A39E-4A68310BDAB1">
        <File Id="fil63DB101A0DC947AC94811D8A5C151E54" Source="..\LICENSE.md" />
      </Component>
    </ComponentGroup>
  </Fragment>

</Wix>


================================================
FILE: Setup/Setup.wixproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
  WiX v3 MSBuild project. Requires WiX Toolset v3.x to be installed.
  See https://wixtoolset.org/ to download WiX v3.
  For a standalone build (including harvesting), use buildmsi.ps1.
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.10</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}</ProjectGuid>
    <OutputType>Package</OutputType>
    <OutputName>WorkloadTools</OutputName>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <!-- Default version for local developer builds; buildmsi.ps1 always passes BuildVersion -->
    <BuildVersion Condition=" '$(BuildVersion)' == '' ">0.0.0.0</BuildVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\x86\Release\</OutputPath>
    <IntermediateOutputPath>obj\x86\Release\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
    <OutputPath>bin\x64\Release\</OutputPath>
    <IntermediateOutputPath>obj\x64\Release\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\x86\Debug\</OutputPath>
    <IntermediateOutputPath>obj\x86\Debug\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    <OutputPath>bin\x64\Debug\</OutputPath>
    <IntermediateOutputPath>obj\x64\Debug\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Product.wxs" />
    <!--
      harvest.wxs, harvest2.wxs and harvest3.wxs are generated by heat.exe
      in buildmsi.ps1. Run buildmsi.ps1 before building from Visual Studio.
    -->
    <Compile Include="harvest.wxs" Condition="Exists('harvest.wxs')" />
    <Compile Include="harvest2.wxs" Condition="Exists('harvest2.wxs')" />
    <Compile Include="harvest3.wxs" Condition="Exists('harvest3.wxs')" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="postbuild.bat" />
    <Content Include="SignMsi.ps1" />
    <Content Include="transform.xsl" />
    <Content Include="transform2.xsl" />
    <Content Include="transform3.xsl" />
  </ItemGroup>
  <PropertyGroup>
    <PostBuildEvent>call $(ProjectDir)postbuild.bat "$(TargetPath)" "$(TargetDir)WorkloadTools_$(Platform)$(TargetExt)"</PostBuildEvent>
  </PropertyGroup>
  <Import Project="$(WixTargetsPath)" Condition="Exists('$(WixTargetsPath)')" />
  <Target Name="EnsureWixTargetsImported" BeforeTargets="PrepareForBuild" Condition=" '$(WixTargetsImported)' == '' ">
    <Warning Text="WiX Toolset v3 build targets were not found at '$(WixTargetsPath)'. Build skipped. Use buildmsi.ps1 to build the installer." />
  </Target>
  <Target Name="Build" Condition=" '$(WixTargetsImported)' == '' ">
    <Message Text="Setup project skipped: WiX Toolset v3 is not installed. Use buildmsi.ps1 to build the installer." Importance="high" />
  </Target>
</Project>

================================================
FILE: Setup/SignMsi.ps1
================================================
[CmdletBinding()]
Param(
    [Parameter(Mandatory=$True,Position=1)]
    [string]$InputFile,
    [Parameter(Mandatory=$True,Position=2)]
    [string]$OutputFile
)


if(-not (Test-Path $PSScriptRoot\SignParams.ps1)) 
{
    Write-Warning "No code signing is applied to the .msi file."
    Write-Warning "You need to create a file called SignParams.ps1 and provide signing info."

    Write-Output "Moving $InputFile --> $OutputFile"
    Move-Item $InputFile $OutputFile -Force

    exit
}

# read paramters
$signParams = get-content $PSScriptRoot\SignParams.ps1 -Raw
Invoke-Expression $signParams

$params = $(
     'sign'
    ,'/fd'
    ,'SHA1'
    ,'/f'
    ,('"' + $certPath + '"')
    ,'/p'
    ,('"' + $certPass + '"')
    ,'/sha1'
    ,$certSha
    ,'/t'
    ,('"' + $certTime + '"')
    ,'/d'
    ,'"WorkloadTools"'
)

& $signTool ($params + $InputFile)

Write-Output "Moving $InputFile --> $OutputFile"
Move-Item $InputFile $OutputFile -Force


================================================
FILE: Setup/buildmsi.ps1
================================================
param (
    [Parameter(Mandatory=$false)]
    [string]$BuildVersion = "1.0.0.0",
    [Parameter(Mandatory=$false)]
    [string]$Platform = "x64"
)

Set-Location $PSScriptRoot

# ---------------------------------------------------------------------------
# Locate MSBuild via vswhere (ships with Visual Studio 2017+)
# ---------------------------------------------------------------------------
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
if (-not (Test-Path $vswhere)) {
    throw "vswhere.exe not found at '$vswhere'. Visual Studio 2017 or newer is required."
}

$msbuild = & $vswhere -latest -requires Microsoft.Component.MSBuild `
    -find MSBuild\**\Bin\MSBuild.exe | Select-Object -First 1
if (-not $msbuild) {
    throw "MSBuild.exe not found. Please install Visual Studio with the MSBuild component."
}

# ---------------------------------------------------------------------------
# Locate WiX v3 tools (heat.exe, candle.exe, light.exe)
# The WIX environment variable is set automatically by the WiX v3 installer.
# ---------------------------------------------------------------------------
$wixDir = $null
if ($env:WIX -and (Test-Path $env:WIX)) {
    $wixDir = $env:WIX
}
if (-not $wixDir) {
    $wixDir = @(
        "${env:ProgramFiles(x86)}\WiX Toolset v3.14",
        "${env:ProgramFiles(x86)}\WiX Toolset v3.11",
        "${env:ProgramFiles(x86)}\WiX Toolset v3.10",
        "${env:ProgramFiles}\WiX Toolset v3.14",
        "${env:ProgramFiles}\WiX Toolset v3.11"
    ) | Where-Object { Test-Path $_ } | Select-Object -First 1
}
if (-not $wixDir) {
    throw "WiX Toolset v3 not found. Install from https://wixtoolset.org/ or set the WIX environment variable."
}

$heat   = Join-Path $wixDir "bin\heat.exe"
$candle = Join-Path $wixDir "bin\candle.exe"
$light  = Join-Path $wixDir "bin\light.exe"

# ---------------------------------------------------------------------------
# Build the .NET projects whose output directories will be harvested into
# the MSI by heat.exe.
#
# SqlWorkload and WorkloadViewer use the "AnyCPU" MSBuild platform to produce
# x64 output (bin\x64\Release) or "x86" for x86 output (bin\x86\Release).
# ConvertWorkload always outputs to bin\Release regardless of platform.
# ---------------------------------------------------------------------------
$netPlatform = if ($Platform -eq 'x86') { 'x86' } else { 'AnyCPU' }

& $msbuild "$PSScriptRoot\..\SqlWorkload\SqlWorkload.csproj" `
    -t:Rebuild -p:Configuration=Release "-p:Platform=$netPlatform" `
    -nologo -verbosity:minimal
if ($LASTEXITCODE -ne 0) { throw "SqlWorkload build failed." }

& $msbuild "$PSScriptRoot\..\WorkloadViewer\WorkloadViewer.csproj" `
    -t:Rebuild -p:Configuration=Release "-p:Platform=$netPlatform" `
    -nologo -verbosity:minimal
if ($LASTEXITCODE -ne 0) { throw "WorkloadViewer build failed." }

& $msbuild "$PSScriptRoot\..\ConvertWorkload\ConvertWorkload.csproj" `
    -t:Rebuild -p:Configuration=Release `
    -nologo -verbosity:minimal
if ($LASTEXITCODE -ne 0) { throw "ConvertWorkload build failed." }

# ---------------------------------------------------------------------------
# Prepare output and intermediate directories
# ---------------------------------------------------------------------------
$outDir = "$PSScriptRoot\bin\$Platform\Release"
$objDir = "$PSScriptRoot\obj\$Platform\Release"

foreach ($dir in $outDir, $objDir) {
    if (-not (Test-Path $dir)) {
        New-Item -ItemType Directory -Path $dir -Force | Out-Null
    } elseif (Test-Path "$dir\*") {
        Remove-Item "$dir\*" -Recurse -Force
    }
}

# ---------------------------------------------------------------------------
# Harvest .NET output directories with heat.exe (WiX v3)
# The generated harvest*.wxs files are placed in the Setup project directory
# so they are picked up as Compile items in Setup.wixproj.
# ---------------------------------------------------------------------------
$sqlWorkloadDir    = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\SqlWorkload\bin\$Platform\Release")
$workloadViewerDir = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\WorkloadViewer\bin\$Platform\Release")
$convertWorkloadDir = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\ConvertWorkload\bin\Release")

& $heat dir "$sqlWorkloadDir" `
    -cg ProductComponents -dr INSTALLFOLDER -srd -sreg -ag `
    -var var.SqlWorkloadDir `
    -t "$PSScriptRoot\transform.xsl" `
    -out "$PSScriptRoot\harvest.wxs" -nologo
if ($LASTEXITCODE -ne 0) { throw "heat.exe failed for SqlWorkload." }

& $heat dir "$workloadViewerDir" `
    -cg WorkloadViewerComponents -dr INSTALLFOLDER -srd -sreg -ag `
    -var var.WorkloadViewerDir `
    -t "$PSScriptRoot\transform.xsl" -t "$PSScriptRoot\transform2.xsl" `
    -t "$PSScriptRoot\transform-nodirs.xsl" `
    -out "$PSScriptRoot\harvest2.wxs" -nologo
if ($LASTEXITCODE -ne 0) { throw "heat.exe failed for WorkloadViewer." }

& $heat dir "$convertWorkloadDir" `
    -cg ConvertWorkloadComponents -dr INSTALLFOLDER -srd -sreg -ag `
    -var var.ConvertWorkloadDir `
    -t "$PSScriptRoot\transform.xsl" -t "$PSScriptRoot\transform2.xsl" `
    -t "$PSScriptRoot\transform3.xsl" -t "$PSScriptRoot\transform-nodirs.xsl" `
    -out "$PSScriptRoot\harvest3.wxs" -nologo
if ($LASTEXITCODE -ne 0) { throw "heat.exe failed for ConvertWorkload." }

# ---------------------------------------------------------------------------
# Compile all WXS sources with candle.exe
# ---------------------------------------------------------------------------
$arch = if ($Platform -eq 'x86') { 'x86' } else { 'x64' }

& $candle `
    "$PSScriptRoot\Product.wxs" `
    "$PSScriptRoot\harvest.wxs" `
    "$PSScriptRoot\harvest2.wxs" `
    "$PSScriptRoot\harvest3.wxs" `
    -arch $arch `
    "-dBuildVersion=$BuildVersion" `
    "-dPlatform=$Platform" `
    "-dSqlWorkloadDir=$sqlWorkloadDir" `
    "-dWorkloadViewerDir=$workloadViewerDir" `
    "-dConvertWorkloadDir=$convertWorkloadDir" `
    -out "$objDir\" `
    -nologo
if ($LASTEXITCODE -ne 0) { throw "candle.exe failed." }

# ---------------------------------------------------------------------------
# Link with light.exe to produce the MSI
# ---------------------------------------------------------------------------
$wixObjs = Get-ChildItem "$objDir\*.wixobj" | Select-Object -ExpandProperty FullName

& $light $wixObjs `
    -out "$outDir\WorkloadTools.msi" `
    -nologo
if ($LASTEXITCODE -ne 0) { throw "light.exe failed." }

# ---------------------------------------------------------------------------
# Sign (or just rename if no signing cert is configured)
# ---------------------------------------------------------------------------
. $PSScriptRoot\SignMsi.ps1 `
    -InputFile "$outDir\WorkloadTools.msi" `
    -OutputFile "$outDir\WorkloadTools_$Platform.msi"

================================================
FILE: Setup/postbuild.bat
================================================
powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File %~dp0\SignMsi.ps1 -InputFile %1 -OutputFile %2



================================================
FILE: Setup/transform-nodirs.xsl
================================================
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">

  <!-- Copy all attributes and elements to the output. -->
  <xsl:template match="@*|*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="*" />
    </xsl:copy>
  </xsl:template>

  <xsl:output method="xml" indent="yes" />

  <!--
    Remove Fragment elements that only contain DirectoryRef children (i.e. the
    directory-structure fragments that heat.exe generates for each subdirectory).
    Those directories are already declared in harvest.wxs (SqlWorkload) and
    re-declaring them in secondary harvest files causes LGHT0091 "Duplicate symbol"
    errors during linking. The ComponentGroup fragment is unaffected because it
    does not contain a DirectoryRef as a direct child.
    -->
  <xsl:template match="wix:Fragment[wix:DirectoryRef and not(wix:ComponentGroup)]" />

</xsl:stylesheet>


================================================
FILE: Setup/transform.xsl
================================================
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">

  <!-- Copy all attributes and elements to the output. -->
  <xsl:template match="@*|*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="*" />
    </xsl:copy>
  </xsl:template>

  <xsl:output method="xml" indent="yes" />

  <!--
    This section includes all the files that need not be included
    in the setup. For instance, all local log files.
    -->

  <xsl:key name="log-search" match="wix:Component[contains(wix:File/@Source, '.log')]" use="@Id" />
  <xsl:template match="wix:Component[key('log-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('log-search', @Id)]" />
</xsl:stylesheet>

================================================
FILE: Setup/transform2.xsl
================================================
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">

  <!-- Copy all attributes and elements to the output. -->
  <xsl:template match="@*|*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="*" />
    </xsl:copy>
  </xsl:template>

  <xsl:output method="xml" indent="yes" />

  <!--
    This section includes all the files that MUST not be included
    in the setup, because they are already included by other projects.
    In this list we will include the libraries (nuget packages) that are
    already included in the SqlWorkload project, in order to avoid collisions.

    ##########################################################################
    REMEMBER THAT THE MATCH IS CASE-SENSITIVE!!! 
    If your setup is not building, please double check the case of the items
    that you want to exclude
    ##########################################################################
    
    -->

  <xsl:key name="commandline-search" match="wix:Component[contains(wix:File/@Source, 'CommandLine.')]" use="@Id" />
  <xsl:template match="wix:Component[key('commandline-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('commandline-search', @Id)]" />
  
  <xsl:key name="nlog-search" match="wix:Component[contains(wix:File/@Source, 'NLog.')]" use="@Id" />
  <xsl:template match="wix:Component[key('nlog-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('nlog-search', @Id)]" />

  <xsl:key name="config-search" match="wix:Directory[@Name='Config']" use="@Id" />
  <xsl:template match="wix:Directory[key('config-search', @Id)]" />
  <xsl:template match="wix:DirectoryRef[key('config-search', @Id)]" />

  <xsl:key name="consumer-search" match="wix:Directory[@Name='Consumer']" use="@Id" />
  <xsl:template match="wix:Directory[key('consumer-search', @Id)]" />
  <xsl:template match="wix:DirectoryRef[key('consumer-search', @Id)]" />

  <xsl:key name="listener-search" match="wix:Directory[@Name='Listener']" use="@Id" />
  <xsl:template match="wix:Directory[key('listener-search', @Id)]" />
  <xsl:template match="wix:DirectoryRef[key('listener-search', @Id)]" />

  <xsl:key name="sql-search" match="wix:Component[contains(wix:File/@Source, '.sql')]" use="@Id" />
  <xsl:template match="wix:Component[key('sql-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('sql-search', @Id)]" />
</xsl:stylesheet>

================================================
FILE: Setup/transform3.xsl
================================================
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">

  <!-- Copy all attributes and elements to the output. -->
  <xsl:template match="@*|*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="*" />
    </xsl:copy>
  </xsl:template>

  <xsl:output method="xml" indent="yes" />

  <!--
    This section includes all the files that MUST not be included
    in the setup, because they are already included by other projects.
    In this list we will include the libraries (nuget packages) that are
    already included in the SqlWorkload project, in order to avoid collisions.

    ##########################################################################
    REMEMBER THAT THE MATCH IS CASE-SENSITIVE!!! 
    If your setup is not building, please double check the case of the items
    that you want to exclude
    ##########################################################################
    
    -->

  <xsl:key name="unwanted-search" match="wix:Component[not(contains(wix:File/@Source, '\ConvertWorkload.'))]" use="@Id" />
  <xsl:template match="wix:Component[key('unwanted-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('unwanted-search', @Id)]" />

</xsl:stylesheet>

================================================
FILE: SetupBootstrapper/Bundle.wxs
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">

  <?if $(var.Platform) = x64 ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
  <?else ?>
    <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
  <?endif ?>

  <?define ProductName="WorkloadTools" ?>
  <?define CompanyName="sqlconsulting.it" ?>
  <?define ProductVersion="$(var.BuildVersion)" ?>

  <Bundle Name="$(var.ProductName)" Version="$(var.ProductVersion)" Manufacturer="$(var.CompanyName)" UpgradeCode="cad976c4-d0c6-4313-b605-ec3749a23b5f">
    <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
      <bal:WixStandardBootstrapperApplication
            LicenseFile="License\License.rtf"
            LogoFile="License\Icon.png"
            LogoSideFile="License\SideLogo.png"
            />
    </BootstrapperApplicationRef>

    <Variable Name="InstallFolder" Value="[$(var.PlatformProgramFilesFolder)]WorkloadTools" Type="string" />

    <Chain>
      <MsiPackage SourceFile="..\Setup\bin\$(var.Platform)\Release\WorkloadTools_$(var.Platform).msi" Id="WorkloadToolsMsi">
        <MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
      </MsiPackage>
      <PackageGroupRef Id="VCRedist"/>
    </Chain>
  </Bundle>

  <Fragment>
    <PackageGroup Id="VCRedist">
      <ExePackage
         Cache="no"
         Compressed="yes"
         PerMachine="yes"
         Permanent="yes"
         Vital="yes"
         Name="Redist\vcredist_$(var.Platform).exe"
         SourceFile="Redist\vcredist_$(var.Platform).exe"
         InstallCommand="/install /quiet /norestart">

        <ExitCode Value="3010" Behavior="forceReboot"/>

        <!-- Ignore "Newer version installed" error -->
        <ExitCode Value="1638" Behavior="success"/>
      </ExePackage>
    </PackageGroup>
  </Fragment>
</Wix>


================================================
FILE: SetupBootstrapper/License/License.rtf
================================================
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f63\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f64\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
{\f66\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f67\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f68\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f69\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
{\f70\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f71\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f383\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f384\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}
{\f386\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f387\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f390\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f391\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}
{\f413\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f414\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f416\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f417\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
{\f418\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f419\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\f420\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}
{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}
{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}
{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}
{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \f31506\fs22 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 
\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive 
\rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 \ssemihidden \sunhideused \styrsid6231089 Hyperlink;}{\s16\ql \li0\ri0\widctlpar
\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 
\f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext16 \slink17 \ssemihidden \sunhideused \styrsid6231089 HTML Preformatted;}{\*\cs17 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 
\sbasedon10 \slink16 \slocked \ssemihidden \styrsid6231089 HTML Preformatted Char;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid1144825\rsid6231089\rsid7602890\rsid8207159\rsid10379327\rsid11422003\rsid12734223\rsid13719530\rsid14571638
\rsid15563878}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Gianluca Sartori}{\operator Gianluca Sartori}{\creatim\yr2020\mo3\dy30\hr16\min21}
{\revtim\yr2020\mo3\dy30\hr17\min5}{\version5}{\edmins3}{\nofpages1}{\nofwords160}{\nofchars914}{\nofcharsws1072}{\vern123}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}
\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect 
\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen
\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1
\jexpand\viewkind1\viewscale120\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
\asianbrkrule\rsidroot6231089\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0
{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang 
{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang 
{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
\pard\plain \ltrpar\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid6231089 \rtlch\fcs1 
\af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid12734223 MIT License}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 

\par 
\par Copyright (c) 20}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089 20}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089  Gianluca Sartori
\par 
\par Permission is hereby granted, free of charge, to any person obtaining a copy}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 
of this software and associated documentation files (the "Software"), to deal}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 
in the Software without restriction, including without limitation the rights}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 to use, copy, modify, merge, pu
blish, distribute, sublicense, and/or sell}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 
copies of the Software, and to permit persons to whom the Software is}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 
furnished to do so, subject to the following conditions:}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089 
\par }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825\charrsid6231089 
\par }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 The above copyright notice and this permission notice shall be included in }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 a}{\rtlch\fcs1 \af2\afs20 
\ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 ll}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 copies or substantial portions of the Software.

\par 
\par }\pard \ltrpar\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1144825 {\rtlch\fcs1 
\af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 
\f2\fs20\cf1\insrsid6231089\charrsid6231089 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 
\f2\fs20\cf1\insrsid6231089\charrsid6231089 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 
\f2\fs20\cf1\insrsid6231089\charrsid6231089 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 
\f2\fs20\cf1\insrsid6231089\charrsid6231089 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 
\f2\fs20\cf1\insrsid6231089\charrsid6231089 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 
\f2\fs20\cf1\insrsid6231089\charrsid6231089 SOFTWARE.}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825  }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13719530\charrsid6231089 
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f
7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd
ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d
7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b
d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52
fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71
b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b
fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567
9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd
79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf
5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2
d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1
738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68
2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac
5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a
b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9
493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2
be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f
f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64
7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e
b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4
6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd
f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d
7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39
4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf
1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a
faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2
67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9
416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27
1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b
8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4
8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65
2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36
3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e
3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985
0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000
0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000
000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000
7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000
000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000
000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000}
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000
02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000d0bc
a2b6a406d601feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}}

================================================
FILE: SetupBootstrapper/SetupBootstrapper.wixproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
  WiX v3 MSBuild project. Requires WiX Toolset v3.x to be installed.
  See https://wixtoolset.org/ to download WiX v3.
  For a standalone build, use buildexe.ps1.
  The MSI (Setup project) must be built before building this bundle.
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.10</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{CAD976C4-D0C6-4313-B605-EC3749A23B5F}</ProjectGuid>
    <OutputType>Bundle</OutputType>
    <OutputName>WorkloadTools</OutputName>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <!-- Default version for local developer builds; buildexe.ps1 always passes BuildVersion -->
    <BuildVersion Condition=" '$(BuildVersion)' == '' ">0.0.0.0</BuildVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\x86\Release\</OutputPath>
    <IntermediateOutputPath>obj\x86\Release\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
    <OutputPath>bin\x64\Release\</OutputPath>
    <IntermediateOutputPath>obj\x64\Release\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\x86\Debug\</OutputPath>
    <IntermediateOutputPath>obj\x86\Debug\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    <OutputPath>bin\x64\Debug\</OutputPath>
    <IntermediateOutputPath>obj\x64\Debug\</IntermediateOutputPath>
    <DefineConstants>BuildVersion=$(BuildVersion);Platform=$(Platform)</DefineConstants>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Bundle.wxs" />
  </ItemGroup>
  <ItemGroup>
    <WixExtension Include="WixBalExtension" />
    <WixExtension Include="WixUIExtension" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="License" />
    <Folder Include="Redist" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="License\Icon.png" />
    <Content Include="License\License.rtf" />
    <Content Include="postbuild.bat" />
    <Content Include="Redist\vcredist_x64.exe" />
    <Content Include="Redist\vcredist_x86.exe" />
    <Content Include="SignMsi.ps1" />
  </ItemGroup>
  <PropertyGroup>
    <PostBuildEvent>call $(ProjectDir)postbuild.bat "$(TargetPath)" "$(TargetDir)WorkloadTools_$(Platform)$(TargetExt)"</PostBuildEvent>
  </PropertyGroup>
  <Import Project="$(WixTargetsPath)" Condition="Exists('$(WixTargetsPath)')" />
  <Target Name="EnsureWixTargetsImported" BeforeTargets="PrepareForBuild" Condition=" '$(WixTargetsImported)' == '' ">
    <Warning Text="WiX Toolset v3 build targets were not found at '$(WixTargetsPath)'. Build skipped. Use buildexe.ps1 to build the bootstrapper." />
  </Target>
  <Target Name="Build" Condition=" '$(WixTargetsImported)' == '' ">
    <Message Text="SetupBootstrapper project skipped: WiX Toolset v3 is not installed. Use buildexe.ps1 to build the bootstrapper." Importance="high" />
  </Target>
</Project>

================================================
FILE: SetupBootstrapper/SignMsi.ps1
================================================
[CmdletBinding()]
Param(
    [Parameter(Mandatory=$True,Position=1)]
    [string]$InputFile,
    [Parameter(Mandatory=$True,Position=2)]
    [string]$OutputFile
)


if(-not (Test-Path $PSScriptRoot\SignParams.ps1)) 
{
    Write-Warning "No code signing is applied to the .msi file."
    Write-Warning "You need to create a file called SignParams.ps1 and provide signing info."
    
    Write-Output "Moving $InputFile --> $OutputFile"
    Move-Item $InputFile $OutputFile -Force

    exit
}

# read paramters
$signParams = get-content $PSScriptRoot\SignParams.ps1 -Raw
Invoke-Expression $signParams

$params = $(
     'sign'
    ,'/fd'
    ,'SHA1'
    ,'/f'
    ,('"' + $certPath + '"')
    ,'/p'
    ,('"' + $certPass + '"')
    ,'/sha1'
    ,$certSha
    ,'/t'
    ,('"' + $certTime + '"')
    ,'/d'
    ,'"WorkloadTools"'
)

$ParentPath = Split-Path -Path $InputFile

& $insigniaPath $("-ib","$InputFile","-o","$ParentPath\engine.exe")
& $signTool ($params + "$ParentPath\engine.exe")

& $insigniaPath $("-ab","$ParentPath\engine.exe",$InputFile,"-o",$InputFile)
& $signTool ($params + $InputFile)


Write-Output "Moving $InputFile --> $OutputFile"
Move-Item $InputFile $OutputFile -Force

Remove-Item "$ParentPath\engine.exe"

================================================
FILE: SetupBootstrapper/buildexe.ps1
================================================
param (
    [Parameter(Mandatory=$false)]
    [string]$BuildVersion = "1.0.0.0",
    [Parameter(Mandatory=$false)]
    [string]$Platform = "x64"
)

# ---------------------------------------------------------------------------
# Build the MSI first
# ---------------------------------------------------------------------------
. $PSScriptRoot\..\Setup\buildmsi.ps1 -BuildVersion $BuildVersion -Platform $Platform

Set-Location $PSScriptRoot

# ---------------------------------------------------------------------------
# Resolve the version from SharedAssemblyInfo.cs if the caller left the default
# ---------------------------------------------------------------------------
if ($BuildVersion -eq "1.0.0.0") {
    $BuildVersion = (Get-Content ..\SharedAssemblyInfo.cs |
        Where-Object { $_.StartsWith("[assembly: AssemblyVersion(") }).
        Replace('[assembly: AssemblyVersion("','').Replace('")]','')
}

# ---------------------------------------------------------------------------
# Locate WiX v3 tools (candle.exe, light.exe)
# The WIX environment variable is set automatically by the WiX v3 installer.
# ---------------------------------------------------------------------------
$wixDir = $null
if ($env:WIX -and (Test-Path $env:WIX)) {
    $wixDir = $env:WIX
}
if (-not $wixDir) {
    $wixDir = @(
        "${env:ProgramFiles(x86)}\WiX Toolset v3.14",
        "${env:ProgramFiles(x86)}\WiX Toolset v3.11",
        "${env:ProgramFiles(x86)}\WiX Toolset v3.10",
        "${env:ProgramFiles}\WiX Toolset v3.14",
        "${env:ProgramFiles}\WiX Toolset v3.11"
    ) | Where-Object { Test-Path $_ } | Select-Object -First 1
}
if (-not $wixDir) {
    throw "WiX Toolset v3 not found. Install from https://wixtoolset.org/ or set the WIX environment variable."
}

$candle = Join-Path $wixDir "bin\candle.exe"
$light  = Join-Path $wixDir "bin\light.exe"

# ---------------------------------------------------------------------------
# Prepare output and intermediate directories
# ---------------------------------------------------------------------------
$outDir = "$PSScriptRoot\bin\$Platform\Release"
$objDir = "$PSScriptRoot\obj\$Platform\Release"

foreach ($dir in $outDir, $objDir) {
    if (-not (Test-Path $dir)) {
        New-Item -ItemType Directory -Path $dir -Force | Out-Null
    } elseif (Test-Path "$dir\*") {
        Remove-Item "$dir\*" -Recurse -Force
    }
}

# ---------------------------------------------------------------------------
# Compile Bundle.wxs with candle.exe
# ---------------------------------------------------------------------------
$arch = if ($Platform -eq 'x86') { 'x86' } else { 'x64' }

& $candle `
    "$PSScriptRoot\Bundle.wxs" `
    -arch $arch `
    "-dBuildVersion=$BuildVersion" `
    "-dPlatform=$Platform" `
    -out "$objDir\" `
    -nologo -ext WixBalExtension
if ($LASTEXITCODE -ne 0) { throw "candle.exe failed for Bundle.wxs." }

# ---------------------------------------------------------------------------
# Link with light.exe to produce the bootstrapper EXE
# ---------------------------------------------------------------------------
$wixObjs = Get-ChildItem "$objDir\*.wixobj" | Select-Object -ExpandProperty FullName

& $light $wixObjs `
    -out "$outDir\WorkloadTools.exe" `
    -nologo -ext WixBalExtension
if ($LASTEXITCODE -ne 0) { throw "light.exe failed for Bundle." }

# ---------------------------------------------------------------------------
# Sign (or just rename if no signing cert is configured)
# ---------------------------------------------------------------------------
. $PSScriptRoot\SignMsi.ps1 `
    -InputFile "$outDir\WorkloadTools.exe" `
    -OutputFile "$outDir\WorkloadTools_$Platform.exe"

================================================
FILE: SetupBootstrapper/postbuild.bat
================================================
powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File %~dp0\SignMsi.ps1 -InputFile %1 -OutputFile %2



================================================
FILE: SharedAssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WorkloadTools")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("spaghettidba")]
[assembly: AssemblyProduct("WorkloadTools")]
[assembly: AssemblyCopyright("Copyright © 2021 spaghettidba")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.7.4")]
[assembly: AssemblyFileVersion("1.7.4")]


================================================
FILE: SqlWorkload/NLog.config
================================================
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" 
      internalLogFile="c:\temp\nlog-internal.log">

  <targets>
    <target name="logfile" xsi:type="File" fileName="SqlWorkload.log" layout="${longdate} - ${level} - ${logger}${when:when='${event-properties:item=Worker}'=='':else=(${event-properties:item=Worker})} : ${message:withexception=true}" />
    <target name="warnfile" xsi:type="File" fileName="Warnings.log" layout="${longdate} - ${logger}${when:when='${event-properties:item=Worker}'=='':else=(${event-properties:item=Worker})} - ${message:withexception=true}" />
    <target name="console" xsi:type="ColoredConsole" layout="${level} - ${logger}${when:when='${event-properties:item=Worker}'=='':else=(${event-properties:item=Worker})} : ${message:withexception=true}"/>
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="logfile" />
    <logger name="*" minlevel="Info" writeTo="console" />
    <logger name="*" levels="Warn" writeTo="warnfile" />
  </rules>
</nlog>


================================================
FILE: SqlWorkload/Program.cs
================================================
using CommandLine;
using CommandLine.Text;
using NLog;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkloadTools;
using WorkloadTools.Config;
using WorkloadTools.Consumer;
using WorkloadTools.Listener;
using WorkloadTools.Listener.ExtendedEvents;
using WorkloadTools.Listener.Trace;

namespace SqlWorkload
{
    class Program
    {

        private static Logger logger = LogManager.GetCurrentClassLogger();
        private static CancellationTokenSource source;

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(GenericErrorHandler);
            GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
            var version = fvi.FileMajorPart.ToString() + "." + fvi.FileMinorPart.ToString() + "." + fvi.FileBuildPart.ToString();
            var name = assembly.FullName;
            logger.Info(name + " " + version);

            try
            {
                var options = new Options();
                if (!CommandLine.Parser.Default.ParseArguments(args, options))
                {
                    return;
                }
                Run(options);
            }
            catch(Exception e)
            {
                logger.Error(e);
            }

        }

        static void Run(Options options)
        {
            // reconfigure loggers to use a file in the current directory
            // or the file specified by the "Log" commandline parameter
            if (LogManager.Configuration != null)
            {
                var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
                if (target != null)
                {
                    var pathToLog = options.LogFile;
                    if (pathToLog == null)
                    {
                        pathToLog = Path.Combine(Environment.CurrentDirectory, "SqlWorkload.log");
                    }
                    if (!Path.IsPathRooted(pathToLog))
                    {
                        pathToLog = Path.Combine(Environment.CurrentDirectory, pathToLog);
                    }
                    target.FileName = pathToLog;

                    if(options.LogLevel != null)
                    {
                        foreach(var rule in LogManager.Configuration.LoggingRules)
                        {
                            foreach (var level in LogLevel.AllLoggingLevels)
                            {
                                rule.DisableLoggingForLevel(level);
                            }
                            rule.EnableLoggingForLevels(LogLevel.FromString(options.LogLevel),LogLevel.Fatal);
                        }
                    }

                    LogManager.ReconfigExistingLoggers();
                }
            }

            options.ConfigurationFile = System.IO.Path.GetFullPath(options.ConfigurationFile);
            logger.Info(String.Format("Reading configuration from '{0}'", options.ConfigurationFile));

            if (!File.Exists(options.ConfigurationFile))
            {
                logger.Error("File not found!");
                Console.WriteLine(options.GetUsage());
                return;
            }

            var config = SqlWorkloadConfig.LoadFromFile(options.ConfigurationFile);
            config.Controller.Listener.Source = System.IO.Path.GetFullPath(config.Controller.Listener.Source);

            Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) {
                e.Cancel = true;
                logger.Info("Received shutdown signal...");
                source.CancelAfter(TimeSpan.FromSeconds(100)); // give a 100 seconds cancellation grace period 
                config.Controller.Stop();
            };

            var t = processController(config.Controller);
            t.Wait();
            logger.Info("Controller stopped.");
            config.Controller.Dispose();
            logger.Info("Controller disposed.");
        }



        static void GenericErrorHandler(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                logger.Error(e.ToString());
            }
            finally
            {
                Console.WriteLine("Caught unhandled exception...");
            }
        }


        public static async Task processController(WorkloadController controller)
        {
            source = new CancellationTokenSource();
            source.Token.Register(CancelNotification);
            var completionSource = new TaskCompletionSource<object>();
            source.Token.Register(() => completionSource.TrySetCanceled());
            var task = Task.Factory.StartNew(() => controller.Run(), source.Token);
            await Task.WhenAny(task, completionSource.Task);
        }

        public static void CancelNotification()
        {
            logger.Info("Shutdown complete.");
        }


    }





    class Options
    {
        [Option('F', "File", DefaultValue = "SqlWorkload.json", HelpText = "Configuration file")]
        public string ConfigurationFile { get; set; }

        [Option('L', "Log", HelpText = "Log file")]
        public string LogFile { get; set; }

        [Option('E', "LogLevel", HelpText = "Log level")]
        public string LogLevel { get; set; }

        [ParserState]
        public IParserState LastParserState { get; set; }

        [HelpOption]
        public string GetUsage()
        {
            return HelpText.AutoBuild(this,
              (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
        }
    
    }

}


================================================
FILE: SqlWorkload/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: Guid("fb46ad2c-df81-4d35-b419-d93e5ef9d98a")]



================================================
FILE: SqlWorkload/Properties/Resources.Designer.cs
================================================
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace SqlWorkload.Properties {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    public class Resources {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal Resources() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        public static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SqlWorkload.Properties.Resources", typeof(Resources).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        public static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to true.
        /// </summary>
        public static string TRUNCATE_TO_4000 {
            get {
                return ResourceManager.GetString("TRUNCATE_TO_4000", resourceCulture);
            }
        }
    }
}


================================================
FILE: SqlWorkload/Properties/Resources.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="TRUNCATE_TO_4000" xml:space="preserve">
    <value>true</value>
  </data>
</root>

================================================
FILE: SqlWorkload/SqlWorkload.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>SqlWorkload</RootNamespace>
    <AssemblyName>SqlWorkload</AssemblyName>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <TargetFrameworkProfile />
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\x64\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\x64\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\x86\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
    <OutputPath>bin\x86\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
    <DebugType>pdbonly</DebugType>
    <PlatformTarget>x86</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
      <HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
    </Reference>
    <Reference Include="DouglasCrockford.JsMin, Version=1.1.3.0, Culture=neutral, PublicKeyToken=99147aa1108448b7, processorArchitecture=MSIL">
      <HintPath>..\packages\DouglasCrockford.JsMin.1.1.3\lib\net40-client\DouglasCrockford.JsMin.dll</HintPath>
    </Reference>
    <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
      <HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data.SQLite, Version=1.0.112.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll</HintPath>
    </Reference>
    <Reference Include="System.IO.Compression" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.Transactions" />
    <Reference Include="System.Web.Extensions" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="..\SharedAssemblyInfo.cs">
      <Link>Properties\SharedAssemblyInfo.cs</Link>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <None Include="NLog.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\WorkloadTools\WorkloadTools.csproj">
      <Project>{ae6e4548-8c33-4728-8504-88aa9666020b}</Project>
      <Name>WorkloadTools</Name>
      <Private>True</Private>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets')" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.112.0\build\net46\System.Data.SQLite.Core.targets'))" />
  </Target>
</Project>

================================================
FILE: SqlWorkload/app.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
  </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.SqlServer.XE.Core" publicKeyToken="89845dcd8080cc91" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-14.100.0.0" newVersion="14.100.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
    <gcConcurrent enabled="false"/>
  </runtime>
</configuration>


================================================
FILE: SqlWorkload/packages.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="CommandLineParser" version="1.9.71" targetFramework="net451" />
  <package id="DouglasCrockford.JsMin" version="1.1.3" targetFramework="net451" />
  <package id="NLog" version="4.7.15" targetFramework="net48" />
  <package id="System.Data.SQLite.Core" version="1.0.112.0" targetFramework="net461" />
</packages>

================================================
FILE: WorkloadTools/BinarySerializedBufferedEventQueue.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization.Formatters.Binary;
using WorkloadTools.Util;
using System.Diagnostics;

namespace WorkloadTools
{
    public class BinarySerializedBufferedEventQueue : BufferedEventQueue
    {
        private readonly string baseFolder;

        private int _minFile, _maxFile;

        private readonly string file_name_uniquifier = "";

        private readonly BinaryFormatter _formatter = new BinaryFormatter();

        public BinarySerializedBufferedEventQueue() : base()
        {
            file_name_uniquifier = DateTime.Now.ToString("yyyyMMddHHmm") + "_" + ("000000000" + (Environment.TickCount & int.MaxValue)).Right(9) + "_";
            baseFolder = Path.Combine(Path.Combine(System.IO.Path.GetTempPath(), "WorkloadTools"), "SerializedEventQueue");
            _ = System.IO.Directory.CreateDirectory(baseFolder);
            _minFile = 0;
            _maxFile = 0;

        }

        protected override WorkloadEvent[] ReadEvents(int count)
        {
            WorkloadEvent[] result = null;
            var destFile = Path.Combine(baseFolder, file_name_uniquifier + ("000000000" + _minFile).Right(9) + ".cache");
            
            using (var fileStream = new System.IO.FileStream(destFile, System.IO.FileMode.Open))
            using (var bufferedStream = new BufferedStream(fileStream))
            {
                result = (WorkloadEvent[])_formatter.Deserialize(bufferedStream);
                if(result.Length != count)
                {
                    throw new ArgumentOutOfRangeException($"The deserialized array is of the wrong size (expected: {count}, found: {result.Length})");
                }
            }

            File.Delete(destFile);
            _minFile++;

            return result;
        }

        protected override void WriteEvents(WorkloadEvent[] events)
        {
            var destFile = Path.Combine(baseFolder, file_name_uniquifier);
            // c# does not have a String.Right method, so I created
            // an extension for it. Crazy, right?
            destFile += ("000000000" + _maxFile).Right(9) + ".cache";

            if (File.Exists(destFile))
            {
                File.Delete(destFile);
            }

            using (var fileStream = new FileStream(destFile, FileMode.CreateNew))
            using (var bufferedStream = new BufferedStream(fileStream))
            {
                _formatter.Serialize(bufferedStream, events);
                fileStream.Close();
            }
            _maxFile++;
        }

        protected override void Dispose(bool disposing)
        {
            // delete all pending files
            for (var i=_minFile; i<=_maxFile; i++)
            {
                var destFile = Path.Combine(baseFolder, file_name_uniquifier);
                destFile += ("000000000" + i).Right(9) + ".cache";
                if (File.Exists(destFile))
                {
                    File.Delete(destFile);
                }

            }
        }

    }
}


================================================
FILE: WorkloadTools/BufferedEventQueue.cs
================================================
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WorkloadTools
{
    public abstract class BufferedEventQueue : IEventQueue 
    {
        private static readonly Logger logger = LogManager.GetCurrentClassLogger();

        private int _bufferSize;

        public int BufferSize
        {
            get => _bufferSize;
            set { _bufferSize = value; initialize(); }
        }

        protected object syncRoot = new object();

        private WorkloadEvent[] _array;
        private WorkloadEvent[] _overflowArray;
        private int _head;               // First valid element in the queue
        private int _tail;               // Last valid element in the queue
        private int _size;               // Number of elements in the array
        private int _totOverflowSize;    // Total number of elements in the overflow array AND disk
        private int _overflowSize;       // Current number of elements in the overflow array
        private int _overflowBufferSize;

        public virtual int Count
        {
            get
            {
                lock (syncRoot)
                {
                    return _size + _totOverflowSize;
                }
            }
        }

        public BufferedEventQueue()
        {
            initialize();
        }

        private void initialize()
        {
            _array = new WorkloadEvent[BufferSize];
            _overflowArray = null;
            _overflowBufferSize = BufferSize / 2;
        }

        protected abstract void WriteEvents(WorkloadEvent[] events);

        protected abstract WorkloadEvent[] ReadEvents(int count);

        public virtual void Enqueue(WorkloadEvent evt)
        {
            lock (syncRoot)
            {
                if (_overflowArray != null)
                {
                    // write to the overflow array
                    _overflowArray[_overflowSize] = evt;
                    _overflowSize++;
                    _totOverflowSize++;
                    if(_overflowSize == _overflowBufferSize)
                    {
                        // decide what to do with the overflow:
                        // if we have enough room in the base array
                        // AND no events persisted to disk, then
                        // write events back to the queue
                        // if the base array does not have enough room, 
                        // write the overflow array to the database
                        // and allocate a new overflow array

                        if((_size <= BufferSize - _overflowBufferSize) && (_totOverflowSize - _overflowSize <= 0))
                        {
                            EnqueueAll(_overflowArray);
                            _overflowSize = 0;
                            _overflowArray = null;
                        }
                        else
                        {
                            WriteEvents(_overflowArray);
                            _overflowSize = 0;
                            _overflowArray = new WorkloadEvent[_overflowBufferSize];
                        }
                    }
                }
                else
                {
                    _array[_tail] = evt;
                    _tail = (_tail + 1) % _array.Length;
                    _size++;

                    // the internal array is at capacity: allocate an overflow array
                    // with size = 50% of BufferSize
                    if (_size == _array.Length)
                    {
                        _overflowArray = new WorkloadEvent[_overflowBufferSize];
                    }
                }
            }
        }

        private void EnqueueAll(WorkloadEvent[] source)
        {
            EnqueueAll(source, source.Length);
        }

        private void EnqueueAll(WorkloadEvent[] source, int count)
        {
            if(count > source.Length)
            {
                throw new ArgumentOutOfRangeException($"The 'count' argument ({count}) is greater than the length of the array to enqueue ({source.Length}).");
            }

            if (_head < _tail)
            {
                var numFirst = _array.Length - _tail;
                if (numFirst > count)
                {
                    numFirst = count;
                }

                Array.Copy(source, 0, _array, _tail, numFirst);
                _tail = (_tail + numFirst) % _array.Length;
                if (numFirst < count)
                {
                    var numSecond = count - numFirst;
                    Array.Copy(source, numFirst, _array, _tail, numSecond);
                    _tail = (_tail + numSecond) % _array.Length;
                }
            }
            else
            {
                Array.Copy(source, 0, _array, _tail, count);
                _tail = (_tail + count) % _array.Length;
            }
            _size += count;
            _totOverflowSize -= count;
        }

        public virtual bool TryDequeue(out WorkloadEvent result)
        {
            result = null;
            try
            {
                lock (syncRoot)
                {
                    if (Count == 0)
                    {
                        return false;
                    }

                    result = _array[_head];
                    _array[_head] = null;
                    _head = (_head + 1) % _array.Length;
                    _size--;

                    if(_totOverflowSize > 0)
                    {

                        // if we have space available and overflowed 
                        // events on disk, then we read them back 
                        if (_totOverflowSize - _overflowSize > 0) 
                        {
                            if (_size == _array.Length - _overflowBufferSize)
                            {
                                EnqueueAll(ReadEvents(_overflowBufferSize));
                            }
                        }
                        else
                        {
                            // if we have events in the overflow array (but not on disk)
                            // and enough space in the queue (at least 75% free), put them back
                            if (_overflowSize > 0 && _size <= _array.Length - (_overflowBufferSize + (_overflowBufferSize / 2)))
                            {
                                EnqueueAll(_overflowArray, _overflowSize);
                                _overflowSize = 0;
                                _overflowArray = null;
                                _totOverflowSize = 0;
                            }
                        }

                    }

                }
                return true;
            }
            catch (Exception e)
            {
                logger.Warn(e, "Unable to dequeue");
                result = null;
                return false;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void Dispose(bool disposing);

        public bool HasMoreElements()
        {
            return Count > 0;
        }
    }
}


================================================
FILE: WorkloadTools/Config/AnalysisSample.json
================================================
{
    "Controller": {

        "Listener":
        {
            "__type": "ExtendedEventsWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "testServer",
                "UserName": "sa",
                "Password": "P4$$w0rd!"
            },
            "DatabaseFilter": "MyDB"
        },

        "Consumers":
        [
            {
                "__type": "AnalysisConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "testServer",
                    "DatabaseName": "SqlWorkload",
                    "SchemaName": "replay",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                },
                "UploadIntervalSeconds": 60
            }
        ]
    }
}

================================================
FILE: WorkloadTools/Config/ReplaySample.json
================================================
{
    "Controller": {

        "Listener":
        {
            "__type": "ExtendedEventsWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "ProductionServer",
                "UserName": "sa",
                "Password": "P4$$w0rd!"
            },
            "DatabaseFilter": "MyDB"
        },

        "Consumers":
        [
            {
                "__type": "ReplayConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "testServer",
                    "DatabaseName": "MyDB",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                }
            },
            {
                "__type": "AnalysisConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "testServer",
                    "DatabaseName": "SqlWorkload",
                    "SchemaName": "baseline",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                },
                "UploadIntervalSeconds": 60
            }
        ]
    }
}

================================================
FILE: WorkloadTools/Config/Sample.json
================================================
{
    "Controller": {

        "Listener":
        {
            "__type": "ExtendedEventsWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "SQLDEMO\\SQL2014",
                "UserName": "sa",
                "Password": "P4$$w0rd!"
            },
            "DatabaseFilter": "DS3"
        },

        "Consumers":
        [
            {
                "__type": "ReplayConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "SQLDEMO\\SQL2016",
                    "DatabaseName": "DS3",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                }
            },
            {
                "__type": "AnalysisConsumer",
                "ConnectionInfo": 
                {
                    "ServerName": "SQLDEMO\\SQL2016",
                    "DatabaseName": "DS3",
                    "SchemaName": "baseline",
                    "UserName": "sa",
                    "Password": "P4$$w0rd!"
                },
                "UploadIntervalSeconds": 60
            }
        ]
    }
}

================================================
FILE: WorkloadTools/Config/SqlWorkloadConfig.cs
================================================
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WorkloadTools;
using System.Web.Script.Serialization;
using System.IO;
using DouglasCrockford.JsMin;
using WorkloadTools.Listener.ExtendedEvents;
using WorkloadTools.Consumer.Replay;
using WorkloadTools.Consumer.Analysis;
using WorkloadTools.Util;

namespace WorkloadTools.Config
{
    public class SqlWorkloadConfig
    {
        public SqlWorkloadConfig()
        {
        }

        public WorkloadController Controller { get; set; }

        public static SqlWorkloadConfig LoadFromFile(string path)
        {
            var ser = new JavaScriptSerializer(new SqlWorkloadConfigTypeResolver());
            ser.RegisterConverters(new JavaScriptConverter[] { new ModelConverter() });
            using (var r = new StreamReader(path))
            {
                var json = r.ReadToEnd();
                var minifier = new JsMinifier();
                // minify JSON to strip away comments
                // Comments in config files are very useful but JSON parsers
                // do not allow comments. Minification solves the issue.
                SqlWorkloadConfig result = null;
                string jsonMin = null;
                try
                {
                    jsonMin = minifier.Minify(json);
                }
                catch (Exception e)
                {
                    throw new FormatException($"Unable to load configuration from '{path}'. The file contains syntax errors.", e);
                }

                try
                {
                    result = ser.Deserialize<SqlWorkloadConfig>(jsonMin);
                }
                catch (Exception e)
                {
                    throw new FormatException($"Unable to load configuration from '{path}'. The file contains semantic errors.", e);
                }
                return result;
            }
        }

        public static void Test()
        {
            var ser = new JavaScriptSerializer(new SqlWorkloadConfigTypeResolver());
            var x = new SqlWorkloadConfig()
            {
                Controller = new WorkloadController()
            };
            x.Controller.Listener = new ExtendedEventsWorkloadListener()
            {
                Source = "Listener\\ExtendedEvents\\sqlworkload.sql",
                ConnectionInfo = new SqlConnectionInfo()
                {
                    ServerName = "SQLDEMO\\SQL2014",
                    UserName = "sa",
                    Password = "P4$$w0rd!"
                }
            };
            //x.Controller.Listener.Filter.DatabaseFilter.PredicateValue = "DS3";

            x.Controller.Consumers.Add(new ReplayConsumer()
            {
                ConnectionInfo = new SqlConnectionInfo()
                {
                    ServerName = "SQLDEMO\\SQL2016",
                    UserName = "sa",
                    Password = "P4$$w0rd!"
                }
            });

            x.Controller.Consumers.Add(new ReplayConsumer()
            {
                ConnectionInfo = new SqlConnectionInfo()
                {
                    ServerName = "SQLDEMO\\SQL2016",
                    UserName = "sa",
                    Password = "P4$$w0rd!",
                    DatabaseName = "RTR",
                    SchemaName = "baseline"
                },
                DatabaseMap = new Dictionary<string, string>()
                {
                    { "DatabaseA", "DatabaseB" },
                    { "DatabaseC", "DatabaseD" }
                }
            });

            var s = ser.Serialize(x);

            Console.WriteLine(s);

            //SqlWorkloadConfig tc = ser.Deserialize<SqlWorkloadConfig>(Samples.Sample.ToString());

        }

    }
}


================================================
FILE: WorkloadTools/Config/SqlWorkloadConfigTypeResolver.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Script.Serialization;

namespace WorkloadTools.Config
{
    internal class SqlWorkloadConfigTypeResolver : SimpleTypeResolver
    {

        private static readonly Dictionary<string, Type> mappedTypes = new Dictionary<string, Type>();

        static SqlWorkloadConfigTypeResolver()
        {
            var currentAssembly = Assembly.GetExecutingAssembly();
            var nameSpace = "WorkloadTools";
            var types = currentAssembly.GetTypes().Where(t => t != null && t.FullName.StartsWith(nameSpace) & !t.FullName.Contains("+")).ToArray();
            foreach (var t in types)
            {
                try
                {
                    mappedTypes.Add(t.AssemblyQualifiedName, t);
                    mappedTypes.Add(t.Name, t);
                }
                catch(Exception)
                {
                    throw;
                }
            }
        }

        public override Type ResolveType(string id)
        {
            if (mappedTypes.ContainsKey(id))
            {
                return mappedTypes[id];
            }
            else
            {
                return base.ResolveType(id);
            }
        }

        public override string ResolveTypeId(Type type)
        {
            return base.ResolveTypeId(type);
        }
    }
}

================================================
FILE: WorkloadTools/Consumer/Analysis/AnalysisConsumer.cs
================================================
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WorkloadTools.Consumer.Analysis;
Download .txt
gitextract_79qcbrcm/

├── .config/
│   └── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .gitignore
├── ConvertWorkload/
│   ├── App.config
│   ├── ConvertWorkload.csproj
│   ├── EventReader.cs
│   ├── EventWriter.cs
│   ├── ExtendedEventsEventReader.cs
│   ├── LocalDBManager.cs
│   ├── NLog.config
│   ├── Program.cs
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── SqlTraceEventReader.cs
│   ├── WorkloadConverter.cs
│   ├── WorkloadFileEventWriter.cs
│   └── packages.config
├── DebuggingTools/
│   ├── capture.json
│   ├── capture_trace.json
│   ├── capture_xel.json
│   ├── generate-allWorkload.bat
│   ├── generate-workload.ps1
│   ├── replay.json
│   ├── report.bat
│   ├── setup.bat
│   ├── start-capture.bat
│   ├── start-capture_trace.bat
│   ├── start-capture_xel.bat
│   └── start-replay.bat
├── LICENSE.md
├── README.md
├── Reports/
│   ├── README.md
│   ├── WorkloadTools Report - Sample.pbix
│   └── WorkloadTools Report - Template.pbit
├── Setup/
│   ├── Product.wxs
│   ├── Setup.wixproj
│   ├── SignMsi.ps1
│   ├── buildmsi.ps1
│   ├── postbuild.bat
│   ├── transform-nodirs.xsl
│   ├── transform.xsl
│   ├── transform2.xsl
│   └── transform3.xsl
├── SetupBootstrapper/
│   ├── Bundle.wxs
│   ├── License/
│   │   └── License.rtf
│   ├── SetupBootstrapper.wixproj
│   ├── SignMsi.ps1
│   ├── buildexe.ps1
│   └── postbuild.bat
├── SharedAssemblyInfo.cs
├── SqlWorkload/
│   ├── NLog.config
│   ├── Program.cs
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Resources.Designer.cs
│   │   └── Resources.resx
│   ├── SqlWorkload.csproj
│   ├── app.config
│   └── packages.config
├── WorkloadTools/
│   ├── BinarySerializedBufferedEventQueue.cs
│   ├── BufferedEventQueue.cs
│   ├── Config/
│   │   ├── AnalysisSample.json
│   │   ├── ReplaySample.json
│   │   ├── Sample.json
│   │   ├── SqlWorkloadConfig.cs
│   │   └── SqlWorkloadConfigTypeResolver.cs
│   ├── Consumer/
│   │   ├── Analysis/
│   │   │   ├── AnalysisConsumer.cs
│   │   │   ├── DatabaseSchema.sql
│   │   │   ├── NormalizedSqlText.cs
│   │   │   ├── SqlTextNormalizer.cs
│   │   │   ├── WorkloadAnalyzer.cs
│   │   │   └── createAnalysisView.sql
│   │   ├── BufferedWorkloadConsumer.cs
│   │   ├── Replay/
│   │   │   ├── ReplayCommand.cs
│   │   │   ├── ReplayConsumer.cs
│   │   │   ├── ReplayWorker.cs
│   │   │   ├── ReplayWorker.cs.bak
│   │   │   └── ResultSetConsumer.cs
│   │   ├── WorkloadConsumer.cs
│   │   └── WorkloadFile/
│   │       └── WorkloadFileWriterConsumer.cs
│   ├── CounterWorkloadEvent.cs
│   ├── DiskPerfWorkloadEvent.cs
│   ├── ErrorWorkloadEvent.cs
│   ├── ExecutionWorkloadEvent.cs
│   ├── FilterPredicate.cs
│   ├── GlobalSuppressions.cs
│   ├── IEventQueue.cs
│   ├── Listener/
│   │   ├── ExtendedEvents/
│   │   │   ├── ExtendedEventsEventFilter.cs
│   │   │   ├── ExtendedEventsFilterPredicate.cs
│   │   │   ├── ExtendedEventsWorkloadListener.cs
│   │   │   ├── FileTargetXEventDataReader.cs
│   │   │   ├── StreamXEventDataReader.cs
│   │   │   ├── XEventDataReader.cs
│   │   │   └── sqlworkload.sql
│   │   ├── File/
│   │   │   ├── FileEventFilter.cs
│   │   │   ├── FileFilterPredicate.cs
│   │   │   └── FileWorkloadListener.cs
│   │   ├── ReadIteration.cs
│   │   ├── SqlTransformer.cs
│   │   └── Trace/
│   │       ├── FileTraceEventDataReader.cs
│   │       ├── ProfilerEventFilter.cs
│   │       ├── ProfilerFilterPredicate.cs
│   │       ├── ProfilerWorkloadListener.cs
│   │       ├── SqlConnectionInfoWrapper.cs
│   │       ├── SqlTraceWorkloadListener.cs
│   │       ├── TraceEventDataReader.cs
│   │       ├── TraceEventFilter.cs
│   │       ├── TraceEventParser.cs
│   │       ├── TraceFileWrapper.cs
│   │       ├── TraceFilterPredicate.cs
│   │       ├── TraceServerWrapper.cs
│   │       ├── TraceUtils.cs
│   │       ├── sqlworkload.sql
│   │       └── sqlworkload.tdf
│   ├── MMFEventQueue.cs
│   ├── MessagWorkloadEvent.cs
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Settings.Designer.cs
│   │   ├── Settings.settings
│   │   └── SharedAssemblyInfo.cs
│   ├── SqlConnectionInfo.cs
│   ├── SqliteEventQueue.cs
│   ├── Util/
│   │   ├── DataUtils.cs
│   │   ├── ModelConverter.cs
│   │   ├── RingBuffer.cs
│   │   └── StringExtensions.cs
│   ├── WaitStatsWorkloadEvent.cs
│   ├── WorkloadController.cs
│   ├── WorkloadEvent.cs
│   ├── WorkloadEventFilter.cs
│   ├── WorkloadListener.cs
│   ├── WorkloadTools.csproj
│   ├── app.config
│   └── packages.config
├── WorkloadTools.sln
├── WorkloadToolsTests/
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── WorkloadTools/
│   │   ├── BinarySerializedBufferedEventQueueTest.cs
│   │   └── SqlTextNormalizerTest.cs
│   ├── WorkloadToolsTests.csproj
│   ├── app.config
│   └── packages.config
├── WorkloadViewer/
│   ├── App.config
│   ├── App.xaml
│   ├── App.xaml.cs
│   ├── Comparer/
│   │   └── QueryResultEqualityComparer.cs
│   ├── Model/
│   │   ├── NormalizedQuery.cs
│   │   ├── QueryDetails.cs
│   │   ├── SqlConnectionInfo.cs
│   │   ├── WorkloadAnalysis.cs
│   │   └── WorkloadAnalysisPoint.cs
│   ├── NLog.config
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Resources.Designer.cs
│   │   ├── Resources.resx
│   │   ├── Settings.Designer.cs
│   │   └── Settings.settings
│   ├── Resources/
│   │   ├── TSQL.xshd
│   │   └── WorkloadAnalysis.sql
│   ├── View/
│   │   ├── ConnectionInfoDialog.xaml
│   │   ├── ConnectionInfoDialog.xaml.cs
│   │   ├── ConnectionInfoDialogStyle.xaml
│   │   ├── ConnectionInfoEditor.xaml
│   │   ├── ConnectionInfoEditor.xaml.cs
│   │   ├── MainWindow.xaml
│   │   └── MainWindow.xaml.cs
│   ├── ViewModel/
│   │   ├── ConnectionInfoEditorViewModel.cs
│   │   ├── DictionaryExtensions.cs
│   │   ├── FilterDefinition.cs
│   │   ├── LinqExtensions.cs
│   │   ├── MainViewModel.cs
│   │   ├── Message.cs
│   │   ├── QueryResult.cs
│   │   ├── SortColMessage.cs
│   │   └── ViewModelLocator.cs
│   ├── WorkloadViewer.csproj
│   └── packages.config
└── build.ps1
Download .txt
SYMBOL INDEX (505 symbols across 93 files)

FILE: ConvertWorkload/EventReader.cs
  class EventReader (line 6) | public abstract class EventReader : IDisposable
    method HasFinished (line 41) | public abstract bool HasFinished();
    method Read (line 43) | public abstract WorkloadEvent Read();
    method HasMoreElements (line 45) | public abstract bool HasMoreElements();
    method Dispose (line 47) | public void Dispose()
    method Dispose (line 55) | protected abstract void Dispose(bool disposing);

FILE: ConvertWorkload/EventWriter.cs
  class EventWriter (line 6) | public abstract class EventWriter : IDisposable
    method Write (line 10) | public abstract void Write(WorkloadEvent evt);
    method Dispose (line 12) | public void Dispose()
    method Dispose (line 19) | protected abstract void Dispose(bool disposing);

FILE: ConvertWorkload/ExtendedEventsEventReader.cs
  class ExtendedEventsEventReader (line 18) | public class ExtendedEventsEventReader : EventReader
    method ExtendedEventsEventReader (line 28) | public ExtendedEventsEventReader(string path)
    method ReadEventsFromFile (line 37) | private void ReadEventsFromFile()
    method HasFinished (line 94) | public override bool HasFinished()
    method HasMoreElements (line 99) | public override bool HasMoreElements()
    method Read (line 104) | public override WorkloadEvent Read()
    method Dispose (line 125) | protected override void Dispose(bool disposing)

FILE: ConvertWorkload/LocalDBManager.cs
  class LocalDBManager (line 15) | internal class LocalDBManager
    method DownloadLocalDB (line 26) | public string DownloadLocalDB()
    method InstallLocalDB (line 40) | public void InstallLocalDB()
    method CanConnectToLocalDB (line 63) | public bool CanConnectToLocalDB()

FILE: ConvertWorkload/Program.cs
  class Program (line 18) | class Program
    method Main (line 24) | static void Main(string[] args)
    method Run (line 52) | private static void Run(Options options)
    method CancelNotification (line 135) | public static void CancelNotification()
    method processConverter (line 140) | public static async Task processConverter(WorkloadConverter converter)
    method GenericErrorHandler (line 150) | static void GenericErrorHandler(object sender, UnhandledExceptionEvent...
  class Options (line 165) | class Options
    method GetUsage (line 191) | [HelpOption]

FILE: ConvertWorkload/SqlTraceEventReader.cs
  class SqlTraceEventReader (line 16) | public class SqlTraceEventReader : EventReader
    method SqlTraceEventReader (line 26) | public SqlTraceEventReader(string path)
    method ReadEventsFromFile (line 35) | private void ReadEventsFromFile()
    method Read (line 91) | public override WorkloadEvent Read()
    method Dispose (line 112) | protected override void Dispose(bool disposing)
    method HasMoreElements (line 122) | public override bool HasMoreElements()
    method HasFinished (line 127) | public override bool HasFinished()

FILE: ConvertWorkload/WorkloadConverter.cs
  class WorkloadConverter (line 11) | public class WorkloadConverter
    method WorkloadConverter (line 25) | public WorkloadConverter(EventReader reader, EventWriter writer)
    method Convert (line 31) | public void Convert()
    method Stop (line 71) | public void Stop()

FILE: ConvertWorkload/WorkloadFileEventWriter.cs
  class WorkloadFileEventWriter (line 11) | public class WorkloadFileEventWriter : EventWriter
    method WorkloadFileEventWriter (line 15) | public WorkloadFileEventWriter(string outputPath)
    method Write (line 23) | public override void Write(WorkloadEvent evt)
    method Dispose (line 28) | protected override void Dispose(bool disposing)

FILE: SqlWorkload/Program.cs
  class Program (line 23) | class Program
    method Main (line 29) | static void Main(string[] args)
    method Run (line 56) | static void Run(Options options)
    method GenericErrorHandler (line 121) | static void GenericErrorHandler(object sender, UnhandledExceptionEvent...
    method processController (line 134) | public static async Task processController(WorkloadController controller)
    method CancelNotification (line 144) | public static void CancelNotification()
  class Options (line 156) | class Options
    method GetUsage (line 170) | [HelpOption]

FILE: SqlWorkload/Properties/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: WorkloadTools/BinarySerializedBufferedEventQueue.cs
  class BinarySerializedBufferedEventQueue (line 13) | public class BinarySerializedBufferedEventQueue : BufferedEventQueue
    method BinarySerializedBufferedEventQueue (line 23) | public BinarySerializedBufferedEventQueue() : base()
    method ReadEvents (line 33) | protected override WorkloadEvent[] ReadEvents(int count)
    method WriteEvents (line 54) | protected override void WriteEvents(WorkloadEvent[] events)
    method Dispose (line 75) | protected override void Dispose(bool disposing)

FILE: WorkloadTools/BufferedEventQueue.cs
  class BufferedEventQueue (line 10) | public abstract class BufferedEventQueue : IEventQueue
    method BufferedEventQueue (line 44) | public BufferedEventQueue()
    method initialize (line 49) | private void initialize()
    method WriteEvents (line 56) | protected abstract void WriteEvents(WorkloadEvent[] events);
    method ReadEvents (line 58) | protected abstract WorkloadEvent[] ReadEvents(int count);
    method Enqueue (line 60) | public virtual void Enqueue(WorkloadEvent evt)
    method EnqueueAll (line 110) | private void EnqueueAll(WorkloadEvent[] source)
    method EnqueueAll (line 115) | private void EnqueueAll(WorkloadEvent[] source, int count)
    method TryDequeue (line 148) | public virtual bool TryDequeue(out WorkloadEvent result)
    method Dispose (line 203) | public void Dispose()
    method Dispose (line 209) | protected abstract void Dispose(bool disposing);
    method HasMoreElements (line 211) | public bool HasMoreElements()

FILE: WorkloadTools/Config/SqlWorkloadConfig.cs
  class SqlWorkloadConfig (line 18) | public class SqlWorkloadConfig
    method SqlWorkloadConfig (line 20) | public SqlWorkloadConfig()
    method LoadFromFile (line 26) | public static SqlWorkloadConfig LoadFromFile(string path)
    method Test (line 60) | public static void Test()

FILE: WorkloadTools/Config/SqlWorkloadConfigTypeResolver.cs
  class SqlWorkloadConfigTypeResolver (line 9) | internal class SqlWorkloadConfigTypeResolver : SimpleTypeResolver
    method SqlWorkloadConfigTypeResolver (line 14) | static SqlWorkloadConfigTypeResolver()
    method ResolveType (line 33) | public override Type ResolveType(string id)
    method ResolveTypeId (line 45) | public override string ResolveTypeId(Type type)

FILE: WorkloadTools/Consumer/Analysis/AnalysisConsumer.cs
  class AnalysisConsumer (line 10) | public class AnalysisConsumer : BufferedWorkloadConsumer
    method ConsumeBuffered (line 44) | public override void ConsumeBuffered(WorkloadEvent evt)
    method HasMoreEvents (line 62) | public override bool HasMoreEvents()
    method Dispose (line 67) | protected override void Dispose(bool disposing)

FILE: WorkloadTools/Consumer/Analysis/DatabaseSchema.sql
  type SchemaName (line 6) | CREATE TABLE [{SchemaName}].[WorkloadDetails](
  type SchemaName (line 90) | CREATE TABLE [{SchemaName}].[Applications](
  type SchemaName (line 155) | CREATE TABLE [{SchemaName}].[DiskPerf] (
  type SchemaName (line 179) | CREATE TABLE [{SchemaName}].[Errors](

FILE: WorkloadTools/Consumer/Analysis/NormalizedSqlText.cs
  class NormalizedSqlText (line 8) | public class NormalizedSqlText
    type CommandTypeEnum (line 10) | public enum CommandTypeEnum
    method NormalizedSqlText (line 21) | public NormalizedSqlText()
    method NormalizedSqlText (line 26) | public NormalizedSqlText(string command) : this()

FILE: WorkloadTools/Consumer/Analysis/SqlTextNormalizer.cs
  class SqlTextNormalizer (line 16) | public class SqlTextNormalizer
    method SqlTextNormalizer (line 56) | static SqlTextNormalizer()
    method NormalizeSqlText (line 85) | public NormalizedSqlText NormalizeSqlText(string sql, int spid)
    method NormalizeSqlText (line 114) | public NormalizedSqlText NormalizeSqlText(string sql, int spid, bool s...
    method TruncateSql (line 313) | private string TruncateSql(string sql)
    method FixComments (line 324) | private string FixComments(string sql)
    method RemoveBlockComments (line 377) | private string RemoveBlockComments(string sql, int position)
    method GetHashCode (line 412) | public long GetHashCode(string text)

FILE: WorkloadTools/Consumer/Analysis/WorkloadAnalyzer.cs
  class WorkloadAnalyzer (line 20) | public class WorkloadAnalyzer : IDisposable
    class NormalizedQuery (line 55) | private class NormalizedQuery
    method WorkloadAnalyzer (line 66) | public WorkloadAnalyzer()
    method CloseInterval (line 86) | private void CloseInterval()
    method ProcessQueue (line 148) | private void ProcessQueue()
    method Add (line 180) | public void Add(WorkloadEvent evt)
    method ProvisionWorker (line 216) | private void ProvisionWorker()
    method InternalAdd (line 257) | private void InternalAdd(WorkloadEvent evt)
    method InternalAdd (line 285) | private void InternalAdd(ErrorWorkloadEvent evt)
    method InternalAdd (line 293) | private void InternalAdd(WaitStatsWorkloadEvent evt)
    method InternalAdd (line 305) | private void InternalAdd(DiskPerfWorkloadEvent evt)
    method InternalAdd (line 317) | private void InternalAdd(CounterWorkloadEvent evt)
    method InternalAdd (line 341) | private void InternalAdd(ExecutionWorkloadEvent evt)
    method Stop (line 437) | public void Stop()
    method WriteToServer (line 462) | [MethodImpl(MethodImplOptions.Synchronized)]
    method WriteWaitsData (line 538) | private void WriteWaitsData(SqlConnection conn, SqlTransaction tran, i...
    method WriteDiskPerf (line 589) | private void WriteDiskPerf(SqlConnection conn, SqlTransaction tran, in...
    method WritePerformanceCounters (line 657) | private void WritePerformanceCounters(SqlConnection conn, SqlTransacti...
    method WriteExecutionSummary (line 706) | private void WriteExecutionSummary(SqlConnection conn, SqlTransaction ...
    method WriteExecutionDetails (line 846) | private void WriteExecutionDetails(SqlConnection conn, SqlTransaction ...
    method WriteExecutionErrors (line 925) | private void WriteExecutionErrors(SqlConnection conn, SqlTransaction t...
    method WriteDictionary (line 968) | private void WriteDictionary(Dictionary<string, int> values, SqlConnec...
    method WriteNormalizedQueries (line 1025) | private void WriteNormalizedQueries(Dictionary<long, NormalizedQuery> ...
    method InvokeGC (line 1091) | private void InvokeGC()
    method ComputeIntervalId (line 1097) | private int ComputeIntervalId(DateTime intervalTime)
    method CreateInterval (line 1103) | private int CreateInterval(SqlConnection conn, SqlTransaction tran, Da...
    method PrepareDataTables (line 1148) | private void PrepareDataTables()
    method PrepareDictionaries (line 1156) | private void PrepareDictionaries()
    method AddAllRows (line 1179) | private void AddAllRows(SqlConnection conn, string sql,  Dictionary<st...
    method CreateTargetTables (line 1208) | protected void CreateTargetTables()
    method CreateTargetDatabase (line 1271) | protected void CreateTargetDatabase()
    method Dispose (line 1309) | public void Dispose()
    class ExecutionDetailKey (line 1317) | internal class ExecutionDetailKey : IEquatable<ExecutionDetailKey>
      method GetHashCode (line 1325) | public override int GetHashCode()
      method Equals (line 1339) | public override bool Equals(object other)
      method Equals (line 1344) | public bool Equals(ExecutionDetailKey other)
    class ExecutionDetailValue (line 1355) | internal class ExecutionDetailValue

FILE: WorkloadTools/Consumer/BufferedWorkloadConsumer.cs
  class BufferedWorkloadConsumer (line 13) | public abstract class BufferedWorkloadConsumer : WorkloadConsumer
    method Consume (line 25) | public override sealed void Consume(WorkloadEvent evt)
    method ProcessBuffer (line 49) | protected void ProcessBuffer()
    method Dispose (line 81) | protected override void Dispose(bool disposing)
    method ConsumeBuffered (line 86) | public abstract void ConsumeBuffered(WorkloadEvent evt);

FILE: WorkloadTools/Consumer/Replay/ReplayCommand.cs
  class ReplayCommand (line 8) | public class ReplayCommand

FILE: WorkloadTools/Consumer/Replay/ReplayConsumer.cs
  class ReplayConsumer (line 13) | public class ReplayConsumer : BufferedWorkloadConsumer
    type ThreadingModeEnum (line 64) | public enum ThreadingModeEnum : int
    method ReplayConsumer (line 72) | public ReplayConsumer()
    method EnsureWatchdogRunning (line 77) | private void EnsureWatchdogRunning()
    method WorkerKey (line 114) | private string WorkerKey(ExecutionWorkloadEvent evnt)
    method ConsumeBuffered (line 132) | public override void ConsumeBuffered(WorkloadEvent evnt)
    method Dispose (line 263) | protected override void Dispose(bool disposing)
    method RunSweeper (line 280) | private void RunSweeper()
    method RemoveWorker (line 307) | private void RemoveWorker(string name)
    method RunWorker (line 319) | private void RunWorker(ReplayWorker wrk)
    method HasMoreEvents (line 437) | public override bool HasMoreEvents()
    method OnWorkerCommandExecuted (line 444) | private void OnWorkerCommandExecuted(object sender, EventArgs e)
    method LogReplayProgress (line 469) | private void LogReplayProgress(long executed, bool forceLog = false)

FILE: WorkloadTools/Consumer/Replay/ReplayWorker.cs
  class ReplayWorker (line 21) | internal class ReplayWorker : IDisposable
    method ReplayWorker (line 59) | public ReplayWorker(string name)
    type UserErrorType (line 87) | private enum UserErrorType
    method InitializeConnection (line 93) | private void InitializeConnection(string applicationName)
    method Start (line 106) | public void Start()
    method Run (line 133) | public void Run()
    method Stop (line 149) | public void Stop()
    method ExecuteNextCommand (line 162) | public void ExecuteNextCommand()
    method GetNextCommand (line 184) | public ReplayCommand GetNextCommand()
    method ExecuteCommand (line 196) | [MethodImpl(MethodImplOptions.Synchronized)]
    method ClearPool (line 503) | private void ClearPool(SqlConnection conn)
    method RaiseTimeoutEvent (line 519) | private void RaiseTimeoutEvent(string commandText)
    method RaiseErrorEvent (line 526) | private void RaiseErrorEvent(ReplayCommand Command, string ErrorMessage)
    method RaiseErrorEvent (line 543) | private void RaiseErrorEvent(string info, string message, UserErrorTyp...
    method AppendCommand (line 577) | public void AppendCommand(ReplayCommand cmd)
    method PreciseDelay (line 582) | private void PreciseDelay(double delayMs)
    method Dispose (line 652) | public void Dispose()
    method Dispose (line 658) | protected void Dispose(bool disposing)

FILE: WorkloadTools/Consumer/Replay/ResultSetConsumer.cs
  class ResultSetConsumer (line 9) | public class ResultSetConsumer : IDisposable
    method ResultSetConsumer (line 13) | public ResultSetConsumer(SqlDataReader sqlDataReader)
    method Consume (line 18) | public void Consume()
    method Dispose (line 26) | public void Dispose()
    method Dispose (line 32) | protected virtual void Dispose(bool disposing) { }

FILE: WorkloadTools/Consumer/WorkloadConsumer.cs
  class WorkloadConsumer (line 8) | public abstract class WorkloadConsumer : IDisposable
    method Consume (line 10) | public abstract void Consume(WorkloadEvent evt);
    method HasMoreEvents (line 12) | public abstract bool HasMoreEvents();
    method Dispose (line 14) | public void Dispose()
    method Dispose (line 20) | protected virtual void Dispose(bool disposing) { }

FILE: WorkloadTools/Consumer/WorkloadFile/WorkloadFileWriterConsumer.cs
  class WorkloadFileWriterConsumer (line 14) | public class WorkloadFileWriterConsumer : BufferedWorkloadConsumer
    method ConsumeBuffered (line 168) | public override void ConsumeBuffered(WorkloadEvent evt)
    method Flush (line 183) | private void Flush()
    method InitializeConnection (line 234) | private void InitializeConnection()
    method UpdateExecutionEvent (line 268) | private void UpdateExecutionEvent(WorkloadEvent evnt)
    method InsertExecutionEvent (line 288) | private void InsertExecutionEvent(WorkloadEvent evnt)
    method InsertEvent (line 311) | private void InsertEvent(WorkloadEvent evnt)
    method InsertWaitEvent (line 366) | private void InsertWaitEvent(WorkloadEvent evnt)
    method InsertDiskPerfEvent (line 403) | private void InsertDiskPerfEvent(WorkloadEvent evnt)
    method InsertCounterEvent (line 451) | private void InsertCounterEvent(WorkloadEvent evnt)
    method InitializeDatabase (line 484) | public void InitializeDatabase()
    method Dispose (line 597) | protected override void Dispose(bool disposing)
    method HasMoreEvents (line 653) | public override bool HasMoreEvents()

FILE: WorkloadTools/CounterWorkloadEvent.cs
  class CounterWorkloadEvent (line 8) | [Serializable]
    type CounterNameEnum (line 11) | public enum CounterNameEnum
    method CounterWorkloadEvent (line 18) | public CounterWorkloadEvent()

FILE: WorkloadTools/DiskPerfWorkloadEvent.cs
  class DiskPerfWorkloadEvent (line 9) | [Serializable]
    method DiskPerfWorkloadEvent (line 14) | public DiskPerfWorkloadEvent()

FILE: WorkloadTools/ErrorWorkloadEvent.cs
  class ErrorWorkloadEvent (line 9) | [Serializable]
    method ErrorWorkloadEvent (line 12) | public ErrorWorkloadEvent()

FILE: WorkloadTools/ExecutionWorkloadEvent.cs
  class ExecutionWorkloadEvent (line 8) | [Serializable]

FILE: WorkloadTools/FilterPredicate.cs
  class FilterPredicate (line 5) | public abstract class FilterPredicate
    type FilterColumnName (line 9) | public enum FilterColumnName : byte
    type FilterComparisonOperator (line 17) | public enum FilterComparisonOperator : byte
    method FilterPredicate (line 29) | public FilterPredicate()
    method FilterPredicate (line 61) | public FilterPredicate(FilterColumnName name)
    method PushDown (line 66) | public abstract string PushDown();
    method EscapeFilter (line 68) | protected string EscapeFilter(string value)
    method ComparisonOperatorAsString (line 73) | public static string ComparisonOperatorAsString(FilterComparisonOperat...

FILE: WorkloadTools/IEventQueue.cs
  type EventQueueType (line 6) | public enum EventQueueType
  type IEventQueue (line 14) | public interface IEventQueue : IDisposable
    method TryDequeue (line 18) | bool TryDequeue(out WorkloadEvent result);
    method HasMoreElements (line 19) | bool HasMoreElements();
    method Enqueue (line 20) | void Enqueue(WorkloadEvent evt);

FILE: WorkloadTools/Listener/ExtendedEvents/ExtendedEventsEventFilter.cs
  class ExtendedEventsEventFilter (line 8) | public class ExtendedEventsEventFilter : WorkloadEventFilter
    method ExtendedEventsEventFilter (line 12) | public ExtendedEventsEventFilter()

FILE: WorkloadTools/Listener/ExtendedEvents/ExtendedEventsFilterPredicate.cs
  class ExtendedEventsFilterPredicate (line 5) | public class ExtendedEventsFilterPredicate : FilterPredicate
    method ExtendedEventsFilterPredicate (line 7) | public ExtendedEventsFilterPredicate(FilterColumnName name) : base(name)
    method PushDown (line 13) | public override string PushDown()

FILE: WorkloadTools/Listener/ExtendedEvents/ExtendedEventsWorkloadListener.cs
  class ExtendedEventsWorkloadListener (line 14) | public class ExtendedEventsWorkloadListener : WorkloadListener
    type ServerType (line 26) | public enum ServerType
    method ExtendedEventsWorkloadListener (line 43) | public ExtendedEventsWorkloadListener() : base()
    method Initialize (line 49) | public override void Initialize()
    method Read (line 166) | public override WorkloadEvent Read()
    method Dispose (line 196) | protected override void Dispose(bool disposing)
    method StopSession (line 226) | private void StopSession(SqlConnection conn)
    method ReadEvents (line 277) | private void ReadEvents()
    method LoadServerType (line 315) | private void LoadServerType(SqlConnection conn)

FILE: WorkloadTools/Listener/ExtendedEvents/FileTargetXEventDataReader.cs
  class FileTargetXEventDataReader (line 15) | public class FileTargetXEventDataReader : XEventDataReader, IDisposable
    method FileTargetXEventDataReader (line 23) | public FileTargetXEventDataReader(string connectionString, string sess...
    method ReadEvents (line 27) | public override void ReadEvents()
    method ReadXEData (line 78) | private void ReadXEData(SqlConnection conn, ReadIteration currentItera...
    method InitializeReadIteration (line 262) | private ReadIteration InitializeReadIteration(SqlConnection conn, Read...
    method parseEvent (line 371) | private ExecutionWorkloadEvent parseEvent(XmlDocument doc)
    method Stop (line 500) | public override void Stop()
    method Dispose (line 505) | public void Dispose()

FILE: WorkloadTools/Listener/ExtendedEvents/StreamXEventDataReader.cs
  class StreamXEventDataReader (line 12) | public class StreamXEventDataReader : XEventDataReader
    type FieldType (line 15) | private enum FieldType
    method StreamXEventDataReader (line 25) | public StreamXEventDataReader(string connectionString, string sessionN...
    method ReadEvents (line 29) | public override void ReadEvents()
    method TryGetValue (line 249) | private object TryGetValue(PublishedEvent evt, FieldType t, string name)
    method TryGetString (line 281) | private string TryGetString(PublishedEvent evt, FieldType t, string name)
    method TryGetInt32 (line 305) | private int? TryGetInt32(PublishedEvent evt, FieldType t, string name)
    method TryGetInt64 (line 318) | private long? TryGetInt64(PublishedEvent evt, FieldType t, string name)
    method Stop (line 331) | public override void Stop()

FILE: WorkloadTools/Listener/ExtendedEvents/XEventDataReader.cs
  class XEventDataReader (line 10) | public abstract class XEventDataReader
    method XEventDataReader (line 19) | public XEventDataReader(
    method ReadEvents (line 32) | public abstract void ReadEvents();
    method Stop (line 34) | public abstract void Stop();

FILE: WorkloadTools/Listener/File/FileEventFilter.cs
  class FileEventFilter (line 8) | public class FileEventFilter : WorkloadEventFilter
    method FileEventFilter (line 12) | public FileEventFilter()

FILE: WorkloadTools/Listener/File/FileFilterPredicate.cs
  class FileFilterPredicate (line 5) | public class FileFilterPredicate : FilterPredicate
    method FileFilterPredicate (line 7) | public FileFilterPredicate(FilterColumnName name) : base(name)
    method PushDown (line 13) | public override string PushDown()

FILE: WorkloadTools/Listener/File/FileWorkloadListener.cs
  class FileWorkloadListener (line 14) | public class FileWorkloadListener : WorkloadListener
    method FileWorkloadListener (line 33) | public FileWorkloadListener() : base()
    method Initialize (line 38) | public override void Initialize()
    method ValidateFile (line 79) | private long ValidateFile()
    method Read (line 130) | public override WorkloadEvent Read()
    method ReadEvent (line 248) | private WorkloadEvent ReadEvent(SQLiteDataReader reader)
    method GetString (line 314) | private string GetString(SQLiteDataReader reader, string columnName)
    method GetInt64 (line 331) | private long? GetInt64(SQLiteDataReader reader, string columnName)
    method Dispose (line 344) | protected override void Dispose(bool disposing)
    method ReadPerfCountersEvents (line 353) | protected override void ReadPerfCountersEvents()
    method ReadWaitStatsEvents (line 357) | protected override void ReadWaitStatsEvents()
    method ReadDiskPerformanceEvents (line 362) | protected override void ReadDiskPerformanceEvents()
    method ReadCounters (line 367) | private void ReadCounters(long row_id, CounterWorkloadEvent cev)
    method GetFilterClause (line 405) | private string GetFilterClause()

FILE: WorkloadTools/Listener/ReadIteration.cs
  class ReadIteration (line 12) | internal class ReadIteration
    method AddOffset (line 24) | private static void AddOffset(string filename, long offset)
    method GetLastOffset (line 54) | public static long GetLastOffset(string filename)
    method GetSecondLastOffset (line 64) | public static long GetSecondLastOffset(string filename)
    method GetXEFilePattern (line 103) | public string GetXEFilePattern()
    method GetInitialOffset (line 115) | public long GetInitialOffset()
    method GetInitialSequence (line 136) | public long GetInitialSequence()

FILE: WorkloadTools/Listener/SqlTransformer.cs
  class SqlTransformer (line 11) | public class SqlTransformer
    method MakeFloat (line 22) | private static string MakeFloat(Match match)
    method Transform (line 34) | public string Transform(string command)
    method Skip (line 89) | public bool Skip(string command)
    method RemoveFirstP1 (line 162) | private string RemoveFirstP1(string command, out string originalP1)
    method RemoveFirstPrepStatementNum (line 184) | private string RemoveFirstPrepStatementNum(string command, out string ...
    method Normalize (line 221) | public NormalizedSqlText Normalize(string command)

FILE: WorkloadTools/Listener/Trace/FileTraceEventDataReader.cs
  class FileTraceEventDataReader (line 14) | public class FileTraceEventDataReader : TraceEventDataReader
    method FileTraceEventDataReader (line 30) | public FileTraceEventDataReader(string connectionString, WorkloadEvent...
    method ReadEvents (line 35) | public override void ReadEvents()
    method InitializeReadIteration (line 95) | private ReadIteration InitializeReadIteration(SqlConnection conn, Read...
    method ReadTraceData (line 223) | private void ReadTraceData(SqlConnection conn, ReadIteration currentIt...
    method Stop (line 393) | public override void Stop()

FILE: WorkloadTools/Listener/Trace/ProfilerEventFilter.cs
  class ProfilerEventFilter (line 8) | public class ProfilerEventFilter : WorkloadEventFilter
    method ProfilerEventFilter (line 11) | public ProfilerEventFilter()

FILE: WorkloadTools/Listener/Trace/ProfilerFilterPredicate.cs
  class ProfilerFilterPredicate (line 8) | public class ProfilerFilterPredicate : FilterPredicate
    method ProfilerFilterPredicate (line 10) | public ProfilerFilterPredicate(FilterColumnName name) : base(name)
    method PushDown (line 14) | public override string PushDown()

FILE: WorkloadTools/Listener/Trace/ProfilerWorkloadListener.cs
  class ProfilerWorkloadListener (line 13) | public class ProfilerWorkloadListener : WorkloadListener
    method ProfilerWorkloadListener (line 20) | public ProfilerWorkloadListener() : base()
    method Initialize (line 27) | public override void Initialize()
    method Read (line 67) | public override WorkloadEvent Read()
    method Dispose (line 76) | protected override void Dispose(bool disposing)
    method ReadEvents (line 96) | private void ReadEvents()

FILE: WorkloadTools/Listener/Trace/SqlConnectionInfoWrapper.cs
  class SqlConnectionInfoWrapper (line 10) | public class SqlConnectionInfoWrapper
    method SqlConnectionInfoWrapper (line 41) | public SqlConnectionInfoWrapper()

FILE: WorkloadTools/Listener/Trace/SqlTraceWorkloadListener.cs
  class SqlTraceWorkloadListener (line 17) | public class SqlTraceWorkloadListener : WorkloadListener
    type StreamSourceEnum (line 21) | public enum StreamSourceEnum
    method SqlTraceWorkloadListener (line 42) | public SqlTraceWorkloadListener() : base()
    method Initialize (line 49) | public override void Initialize()
    method Read (line 110) | public override WorkloadEvent Read()
    method ReadEventsFromTDS (line 139) | private void ReadEventsFromTDS()
    method ReadEventsFromFile (line 151) | private void ReadEventsFromFile()
    method Dispose (line 248) | protected override void Dispose(bool disposing)
    method StopTrace (line 260) | private void StopTrace(SqlConnection conn, int id)

FILE: WorkloadTools/Listener/Trace/TraceEventDataReader.cs
  class TraceEventDataReader (line 10) | public abstract class TraceEventDataReader : IDisposable
    method TraceEventDataReader (line 18) | public TraceEventDataReader(
    method ReadEvents (line 29) | public abstract void ReadEvents();
    method Stop (line 31) | public abstract void Stop();
    method Dispose (line 33) | public void Dispose()

FILE: WorkloadTools/Listener/Trace/TraceEventFilter.cs
  class TraceEventFilter (line 8) | public class TraceEventFilter : WorkloadEventFilter
    method TraceEventFilter (line 11) | public TraceEventFilter()

FILE: WorkloadTools/Listener/Trace/TraceEventParser.cs
  class TraceEventParser (line 10) | public class TraceEventParser
    type EventClassEnum (line 12) | public enum EventClassEnum : int
    method ParseEvent (line 24) | public ExecutionWorkloadEvent ParseEvent(SqlDataReader reader)
    method ExtractTimeoutDuration (line 167) | private long? ExtractTimeoutDuration(object textData)
    method IsValidColumn (line 179) | private bool IsValidColumn(string colName)

FILE: WorkloadTools/Listener/Trace/TraceFileWrapper.cs
  class TraceFileWrapper (line 10) | public class TraceFileWrapper : IDisposable
    method TraceFileWrapper (line 17) | static TraceFileWrapper()
    method TraceFileWrapper (line 37) | public TraceFileWrapper()
    method GetValue (line 64) | public object GetValue(string Name)
    method HasAttribute (line 69) | public bool HasAttribute(string Name)
    method InitializeAsReader (line 82) | public void InitializeAsReader(string fileName)
    method Read (line 95) | public bool Read()
    method Dispose (line 100) | public void Dispose()

FILE: WorkloadTools/Listener/Trace/TraceFilterPredicate.cs
  class TraceFilterPredicate (line 8) | class TraceFilterPredicate : FilterPredicate
    method TraceFilterPredicate (line 10) | public TraceFilterPredicate(FilterColumnName name) : base(name)
    method PushDown (line 14) | public override string PushDown()

FILE: WorkloadTools/Listener/Trace/TraceServerWrapper.cs
  class TraceServerWrapper (line 13) | public class TraceServerWrapper
    method TraceServerWrapper (line 23) | static TraceServerWrapper()
    method TraceServerWrapper (line 41) | public TraceServerWrapper()
    method GetValue (line 63) | public object GetValue(string Name)
    method Read (line 68) | public bool Read()
    method Stop (line 73) | public void Stop()
    method Close (line 80) | public void Close()
    method InitializeAsReader (line 85) | public void InitializeAsReader(SqlConnectionInfoWrapper connectionInfo...

FILE: WorkloadTools/Listener/Trace/TraceUtils.cs
  class TraceUtils (line 10) | internal class TraceUtils
    method GetTraceId (line 12) | public int GetTraceId(SqlConnection conn, string path)
    method GetSqlDefaultLogPath (line 29) | public string GetSqlDefaultLogPath(SqlConnection conn)
    method CheckTraceFormat (line 58) | public bool CheckTraceFormat(SqlConnection conn, string path)

FILE: WorkloadTools/MMFEventQueue.cs
  class MMFEventQueue (line 10) | public class MMFEventQueue : IDisposable , IEventQueue
    method MMFEventQueue (line 18) | public MMFEventQueue()
    method TryDequeue (line 26) | public bool TryDequeue(out WorkloadEvent result)
    method Enqueue (line 46) | public void Enqueue(WorkloadEvent evt)
    method Dispose (line 51) | public void Dispose()
    method HasMoreElements (line 57) | public bool HasMoreElements()

FILE: WorkloadTools/MessagWorkloadEvent.cs
  class MessageWorkloadEvent (line 9) | [Serializable]
    type MessageType (line 12) | public enum MessageType
    method MessageWorkloadEvent (line 20) | public MessageWorkloadEvent()

FILE: WorkloadTools/Properties/Settings.Designer.cs
  class Settings (line 14) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

FILE: WorkloadTools/SqlConnectionInfo.cs
  class SqlConnectionInfo (line 8) | public class SqlConnectionInfo
    method SqlConnectionInfo (line 23) | public SqlConnectionInfo() { }
    method SqlConnectionInfo (line 25) | public SqlConnectionInfo(SqlConnectionInfo info)
    method ConnectionString (line 40) | public string ConnectionString()
    method ConnectionString (line 45) | public string ConnectionString(string applicationName)

FILE: WorkloadTools/SqliteEventQueue.cs
  class SqliteEventQueue (line 9) | public class SqliteEventQueue : BufferedEventQueue
    method SqliteEventQueue (line 12) | public SqliteEventQueue() : base()
    method Dispose (line 16) | protected override void Dispose(bool disposing)
    method ReadEvents (line 21) | protected override WorkloadEvent[] ReadEvents(int count)
    method WriteEvents (line 29) | protected override void WriteEvents(WorkloadEvent[] events)

FILE: WorkloadTools/Util/DataUtils.cs
  class DataUtils (line 10) | public class DataUtils
    method ToDataTable (line 16) | public static DataTable ToDataTable<T>(IEnumerable<T> items)
    method IsNullable (line 46) | public static bool IsNullable(Type t)
    method GetCoreType (line 54) | public static Type GetCoreType(Type t)

FILE: WorkloadTools/Util/ModelConverter.cs
  class ModelConverter (line 15) | public class ModelConverter : JavaScriptConverter
    method Deserialize (line 40) | public override object Deserialize(IDictionary<string, object> diction...
    method GetValueOfType (line 116) | private object GetValueOfType(object v, Type propertyType)
    method Serialize (line 144) | public override IDictionary<string, object> Serialize(object obj, Java...

FILE: WorkloadTools/Util/RingBuffer.cs
  class RingBuffer (line 12) | [DebuggerDisplay("Count = {Count}")]
    method RingBuffer (line 22) | public RingBuffer(int capacity)
    method Last (line 74) | public T Last()
    method Add (line 92) | public void Add(T item)
    method Clear (line 115) | public void Clear()
    method Contains (line 135) | public bool Contains(T item)
    method CopyTo (line 148) | public void CopyTo(T[] array, int arrayIndex)
    method GetEnumerator (line 161) | public IEnumerator<T> GetEnumerator()
    method IndexOf (line 182) | public int IndexOf(T item)
    method Insert (line 221) | public void Insert(int index, T item)
    method Remove (line 275) | public bool Remove(T item)
    method RemoveAt (line 300) | public void RemoveAt(int index)
    method GetEnumerator (line 339) | IEnumerator IEnumerable.GetEnumerator()

FILE: WorkloadTools/Util/StringExtensions.cs
  class StringExtensions (line 9) | public static class StringExtensions
    method Right (line 11) | public static string Right(this string value, int count)
    method ReplaceFirst (line 29) | public static string ReplaceFirst(this string text, string search, str...

FILE: WorkloadTools/WaitStatsWorkloadEvent.cs
  class WaitStatsWorkloadEvent (line 9) | [Serializable]
    method WaitStatsWorkloadEvent (line 14) | public WaitStatsWorkloadEvent()

FILE: WorkloadTools/WorkloadController.cs
  class WorkloadController (line 12) | public class WorkloadController : IDisposable
    method WorkloadController (line 26) | public WorkloadController()
    method Run (line 30) | public void Run()
    method Stop (line 109) | public void Stop()
    method Dispose (line 115) | public void Dispose()

FILE: WorkloadTools/WorkloadEvent.cs
  class WorkloadEvent (line 8) | [Serializable]
    type EventType (line 11) | public enum EventType

FILE: WorkloadTools/WorkloadEventFilter.cs
  class WorkloadEventFilter (line 8) | public abstract class WorkloadEventFilter
    method WorkloadEventFilter (line 15) | public WorkloadEventFilter()
    method Evaluate (line 19) | public bool Evaluate(WorkloadEvent evnt)
    method PushDown (line 73) | public void PushDown(FilterPredicate predicate)

FILE: WorkloadTools/WorkloadListener.cs
  class WorkloadListener (line 14) | public abstract class WorkloadListener : IDisposable
    method WorkloadListener (line 103) | public WorkloadListener()
    method Dispose (line 122) | public void Dispose() {
    method Dispose (line 129) | protected abstract void Dispose(bool disposing);
    method Read (line 131) | public abstract WorkloadEvent Read();
    method Initialize (line 133) | public abstract void Initialize();
    method ReadPerfCountersEvents (line 138) | protected virtual void ReadPerfCountersEvents()
    method GetLastCPUUsage (line 170) | private int GetLastCPUUsage()
    method ReadWaitStatsEvents (line 280) | protected virtual void ReadWaitStatsEvents()
    method GetDiffWaits (line 313) | private DataTable GetDiffWaits(DataTable newWaits, DataTable lastWaits)
    method GetWaits (line 368) | private DataTable GetWaits()
    method ReadDiskPerformanceEvents (line 460) | protected virtual void ReadDiskPerformanceEvents()
    method GetDiffDiskPerf (line 492) | private DataTable GetDiffDiskPerf(DataTable newDiskPerf, DataTable las...
    method GetDiskPerf (line 579) | private DataTable GetDiskPerf()
    method SetTransactionMark (line 653) | protected virtual void SetTransactionMark(bool allDatabases)

FILE: WorkloadToolsTests/WorkloadTools/BinarySerializedBufferedEventQueueTest.cs
  class BinarySerializedBufferedEventQueueTest (line 8) | [TestClass]
    method TestEnqueueDequeueFixedList (line 11) | [TestMethod]
    method TestEnqueueRandomDequeueAll (line 146) | [TestMethod]

FILE: WorkloadToolsTests/WorkloadTools/SqlTextNormalizerTest.cs
  class SqlTextNormalizerTest (line 6) | [TestClass]
    method Initialize (line 11) | [TestInitialize]
    method NormalizeSqlText_SimpleStringParam_Normalized (line 17) | [TestMethod]
    method NormalizeSqlText_StringParamWithDoubleQuotes_Normalized (line 27) | [TestMethod]
    method NormalizeSqlText_StringParamWithEscapedSingleQuotes_Normalized (line 39) | [TestMethod]

FILE: WorkloadViewer/App.xaml.cs
  class App (line 19) | public partial class App : Application
    method OnStartup (line 25) | protected override void OnStartup(StartupEventArgs e)
  class Options (line 68) | public class Options
    method GetUsage (line 109) | [HelpOption]

FILE: WorkloadViewer/Comparer/QueryResultEqualityComparer.cs
  class QueryResultEqualityComparer (line 5) | public class QueryResultEqualityComparer : IEqualityComparer<QueryResult>
    method Equals (line 7) | public bool Equals(QueryResult x, QueryResult y)
    method GetHashCode (line 12) | public int GetHashCode(QueryResult obj)

FILE: WorkloadViewer/Model/NormalizedQuery.cs
  class NormalizedQuery (line 9) | public class NormalizedQuery

FILE: WorkloadViewer/Model/QueryDetails.cs
  class QueryDetails (line 14) | public class QueryDetails
    method QueryDetails (line 20) | public QueryDetails(NormalizedQuery query, WorkloadAnalysis baseline, ...
    method LoadQueryStats (line 45) | private DataTable LoadQueryStats()
    method LoadPlotModel (line 213) | private PlotModel LoadPlotModel()
    method LoadDurationSeries (line 259) | private Series LoadDurationSeries(WorkloadAnalysis analysis, OxyColor ...

FILE: WorkloadViewer/Model/SqlConnectionInfo.cs
  class SqlConnectionInfo (line 9) | public class SqlConnectionInfo

FILE: WorkloadViewer/Model/WorkloadAnalysis.cs
  class WorkloadAnalysis (line 14) | public class WorkloadAnalysis
    method Load (line 26) | public void Load()

FILE: WorkloadViewer/Model/WorkloadAnalysisPoint.cs
  class WorkloadAnalysisPoint (line 9) | public class WorkloadAnalysisPoint

FILE: WorkloadViewer/Properties/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: WorkloadViewer/Properties/Settings.Designer.cs
  class Settings (line 14) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

FILE: WorkloadViewer/View/ConnectionInfoDialog.xaml.cs
  class ConnectionInfoDialog (line 20) | public partial class ConnectionInfoDialog : MahApps.Metro.Controls.Dialo...
    method ConnectionInfoDialog (line 22) | public ConnectionInfoDialog()

FILE: WorkloadViewer/View/ConnectionInfoEditor.xaml.cs
  class ConnectionInfoEditor (line 26) | public partial class ConnectionInfoEditor : UserControl
    method ConnectionInfoEditor (line 28) | public ConnectionInfoEditor()
    method ReceiveMessage (line 35) | private void ReceiveMessage(Message msg)
    method Baseline_PasswordChanged (line 48) | private void Baseline_PasswordChanged(object sender, RoutedEventArgs e)
    method Benchmark_PasswordChanged (line 54) | private void Benchmark_PasswordChanged(object sender, RoutedEventArgs e)

FILE: WorkloadViewer/View/MainWindow.xaml.cs
  class MainWindow (line 28) | public partial class MainWindow : MetroWindow
    method MainWindow (line 30) | public MainWindow()
    method ReceiveSortMessage (line 49) | private void ReceiveSortMessage(SortColMessage msg)
    method DataGridDoubleClick (line 69) | private void DataGridDoubleClick(object sender, MouseButtonEventArgs e)
    method QueryText_MouseDoubleClick (line 78) | private void QueryText_MouseDoubleClick(object sender, MouseButtonEven...
    method OpenFileWithDefaultApp (line 83) | private void OpenFileWithDefaultApp(object sender)

FILE: WorkloadViewer/ViewModel/ConnectionInfoEditorViewModel.cs
  class ConnectionInfoEditorViewModel (line 15) | public class ConnectionInfoEditorViewModel : ViewModelBase
    method ConnectionInfoEditorViewModel (line 67) | public ConnectionInfoEditorViewModel()
    method KeyDown (line 77) | private void KeyDown(KeyEventArgs e)
    method Cancel_Pressed (line 86) | private async void Cancel_Pressed(RoutedEventArgs e)
    method OK_Pressed (line 93) | private async void OK_Pressed(RoutedEventArgs e)

FILE: WorkloadViewer/ViewModel/DictionaryExtensions.cs
  class DictionaryExtensions (line 9) | public static class DictionaryExtensions
    method AddOrUpdate (line 11) | public static void AddOrUpdate<TKey, TValue>(
    method AddOrUpdate (line 26) | public static TValue AddOrUpdate<TKey, TValue>(
    method AddOrUpdate (line 47) | public static TValue AddOrUpdate<TKey, TValue>(

FILE: WorkloadViewer/ViewModel/FilterDefinition.cs
  class FilterDefinition (line 9) | public class FilterDefinition : IComparable, IEquatable<FilterDefinition>
    method CompareTo (line 14) | public int CompareTo(object obj)
    method Equals (line 24) | public bool Equals(FilterDefinition other)

FILE: WorkloadViewer/ViewModel/LinqExtensions.cs
  class LinqExtensions (line 10) | public static class LinqExtensions
    method FullOuterJoin (line 12) | public static IEnumerable<TResult> FullOuterJoin<TLeft, TRight, TKey, ...
    method FullOuterJoinIterator (line 51) | internal static IEnumerable<TResult> FullOuterJoinIterator<TLeft, TRig...

FILE: WorkloadViewer/ViewModel/MainViewModel.cs
  class MainViewModel (line 23) | public class MainViewModel : ViewModelBase
    method MainViewModel (line 83) | public MainViewModel()
    method ApplyFilters (line 93) | private void ApplyFilters(EventArgs obj)
    method Rendered (line 100) | private void Rendered(EventArgs ev)
    method InitializeAll (line 115) | private async void InitializeAll()
    method ShowConnectionInfoDialog (line 154) | private async void ShowConnectionInfoDialog()
    method SetConnectionInfo (line 173) | public async void SetConnectionInfo(ConnectionInfoEditorViewModel view...
    method Loaded (line 203) | private void Loaded(EventArgs ev)
    method InitializeWorkloadAnalysis (line 211) | private void InitializeWorkloadAnalysis()
    method InitializeQueries (line 240) | private void InitializeQueries()
    method ParseOptions (line 409) | private bool ParseOptions()
    method KeyDown (line 427) | private void KeyDown(KeyEventArgs e)
    method RefreshAllCharts (line 441) | private void RefreshAllCharts()
    method InitializeCharts (line 449) | private void InitializeCharts()
    method InitializePlotModel (line 490) | private PlotModel InitializePlotModel(bool dateXAxis)
    method SynchronizeCharts (line 549) | private void SynchronizeCharts(PlotModel plotModel, object sender, Axi...
    method LoadCpuSeries (line 587) | private Series LoadCpuSeries(WorkloadAnalysis analysis, OxyColor color...
    method LoadDurationSeries (line 646) | private Series LoadDurationSeries(WorkloadAnalysis analysis, OxyColor ...
    method LoadBatchesSeries (line 704) | private Series LoadBatchesSeries(WorkloadAnalysis analysis, OxyColor c...
    method InitializeFilters (line 762) | private void InitializeFilters()
    method ShowStatusMessage (line 855) | private void ShowStatusMessage(string message)

FILE: WorkloadViewer/ViewModel/Message.cs
  class Message (line 10) | public class Message
    method Message (line 14) | public Message(string name)

FILE: WorkloadViewer/ViewModel/QueryResult.cs
  class QueryResult (line 5) | public class QueryResult

FILE: WorkloadViewer/ViewModel/SortColMessage.cs
  class SortColMessage (line 10) | public class SortColMessage
    method SortColMessage (line 15) | public SortColMessage(string columnName, ListSortDirection direction)

FILE: WorkloadViewer/ViewModel/ViewModelLocator.cs
  class ViewModelLocator (line 26) | public class ViewModelLocator
    method ViewModelLocator (line 31) | public ViewModelLocator()
    method Cleanup (line 57) | public static void Cleanup()
Condensed preview — 176 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (975K chars).
[
  {
    "path": ".config/dotnet-tools.json",
    "chars": 142,
    "preview": "{\n  \"version\": 1,\n  \"isRoot\": true,\n  \"tools\": {\n    \"wix\": {\n      \"version\": \"4.0.5\",\n      \"commands\": [\n        \"wix"
  },
  {
    "path": ".editorconfig",
    "chars": 11977,
    "preview": "# Remove the line below if you want to inherit .editorconfig settings from higher directories\nroot = true\n\n# C# files\n[*"
  },
  {
    "path": ".gitattributes",
    "chars": 2518,
    "preview": "###############################################################################\n# Set default behavior to automatically "
  },
  {
    "path": ".gitignore",
    "chars": 4448,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": "ConvertWorkload/App.config",
    "chars": 582,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup useLegacyV2RuntimeActivationPolicy=\"true\"> \n        "
  },
  {
    "path": "ConvertWorkload/ConvertWorkload.csproj",
    "chars": 6071,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "ConvertWorkload/EventReader.cs",
    "chars": 1511,
    "preview": "using System;\nusing WorkloadTools;\n\nnamespace ConvertWorkload\n{\n    public abstract class EventReader : IDisposable\n   "
  },
  {
    "path": "ConvertWorkload/EventWriter.cs",
    "chars": 422,
    "preview": "using System;\nusing WorkloadTools;\n\nnamespace ConvertWorkload\n{\n    public abstract class EventWriter : IDisposable\n   "
  },
  {
    "path": "ConvertWorkload/ExtendedEventsEventReader.cs",
    "chars": 3974,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.IO;\nusing System."
  },
  {
    "path": "ConvertWorkload/LocalDBManager.cs",
    "chars": 2657,
    "preview": "using System;\r\nusing System.Collections.Generic;\r\nusing System.Data.SqlClient;\r\nusing System.Diagnostics;\r\nusing System"
  },
  {
    "path": "ConvertWorkload/NLog.config",
    "chars": 929,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<nlog xmlns=\"http://www.nlog-project.org/schemas/NLog.xsd\"\n      xmlns:xsi=\"htt"
  },
  {
    "path": "ConvertWorkload/Program.cs",
    "chars": 6768,
    "preview": "using CommandLine;\nusing CommandLine.Text;\nusing NLog;\nusing NLog.Targets;\nusing System;\nusing System.Collections.Gener"
  },
  {
    "path": "ConvertWorkload/Properties/AssemblyInfo.cs",
    "chars": 457,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n\n// Setting ComV"
  },
  {
    "path": "ConvertWorkload/SqlTraceEventReader.cs",
    "chars": 3858,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.IO;\nusing System."
  },
  {
    "path": "ConvertWorkload/WorkloadConverter.cs",
    "chars": 1940,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threadin"
  },
  {
    "path": "ConvertWorkload/WorkloadFileEventWriter.cs",
    "chars": 755,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "ConvertWorkload/packages.config",
    "chars": 1465,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"n"
  },
  {
    "path": "DebuggingTools/capture.json",
    "chars": 882,
    "preview": "{\n    \"Controller\": {\n\n        \"Listener\":\n        {\n            \"__type\": \"SqlTraceWorkloadListener\",\n            \"Conn"
  },
  {
    "path": "DebuggingTools/capture_trace.json",
    "chars": 877,
    "preview": "{\n    \"Controller\": {\n\n        \"Listener\":\n        {\n            \"__type\": \"SqlTraceWorkloadListener\",\n            \"Conn"
  },
  {
    "path": "DebuggingTools/capture_xel.json",
    "chars": 888,
    "preview": "{\n    \"Controller\": {\n\n        \"Listener\":\n        {\n            \"__type\": \"ExtendedEventsWorkloadListener\",\n           "
  },
  {
    "path": "DebuggingTools/generate-allWorkload.bat",
    "chars": 494,
    "preview": "del \"c:\\temp\\workloadtools\\debug\\capture.sqlite\"\nsqlcmd -S(local) -dbenchmark -Q\"TRUNCATE TABLE dbo.benchmark\"\nstart \"\" "
  },
  {
    "path": "DebuggingTools/generate-workload.ps1",
    "chars": 666,
    "preview": "param (\n    [int]$start\n)\nGet-Date -Format \"yyyy-MM-dd HH:mm:ss\"\n$connectionString = \"Data Source=(local);Integrated Sec"
  },
  {
    "path": "DebuggingTools/replay.json",
    "chars": 627,
    "preview": "{\n    \"Controller\": {\n \n        \"Listener\":\n        {\n            \"__type\": \"FileWorkloadListener\",\n            \"Source\""
  },
  {
    "path": "DebuggingTools/report.bat",
    "chars": 136,
    "preview": "\"c:\\Program Files\\WorkloadTools\\WorkloadViewer.exe\" --BaselineServer (local) --BaselineSchema test --BaselineDatabase be"
  },
  {
    "path": "DebuggingTools/setup.bat",
    "chars": 254,
    "preview": "sqlcmd -S(local) -Q\"CREATE DATABASE benchmark\"\nsqlcmd -S(local) -dbenchmark -Q\"CREATE TABLE dbo.benchmark ( i int NULL )"
  },
  {
    "path": "DebuggingTools/start-capture.bat",
    "chars": 779,
    "preview": "del \"c:\\temp\\workloadtools\\debug\\capture.sqlite\"\nsqlcmd -S(local) -dbenchmark_analysis -Q\"TRUNCATE TABLE test.Applicatio"
  },
  {
    "path": "DebuggingTools/start-capture_trace.bat",
    "chars": 736,
    "preview": "sqlcmd -S(local) -dbenchmark_analysis -Q\"TRUNCATE TABLE test.Applications\"\nsqlcmd -S(local) -dbenchmark_analysis -Q\"TRUN"
  },
  {
    "path": "DebuggingTools/start-capture_xel.bat",
    "chars": 734,
    "preview": "sqlcmd -S(local) -dbenchmark_analysis -Q\"TRUNCATE TABLE test.Applications\"\nsqlcmd -S(local) -dbenchmark_analysis -Q\"TRUN"
  },
  {
    "path": "DebuggingTools/start-replay.bat",
    "chars": 811,
    "preview": "echo %time%\nsqlcmd -S(local) -dbenchmark -Q\"TRUNCATE TABLE benchmark\"\nsqlcmd -S(local) -dbenchmark_analysis -Q\"TRUNCATE "
  },
  {
    "path": "LICENSE.md",
    "chars": 1073,
    "preview": "MIT License\n\nCopyright (c) 2018 Gianluca Sartori\n\nPermission is hereby granted, free of charge, to any person obtaining "
  },
  {
    "path": "README.md",
    "chars": 7724,
    "preview": "![](https://countrush-prod.azurewebsites.net/l/badge/?repository=spaghettidba.WorkloadTools)\n# WorkloadTools\n\n*WorkloadT"
  },
  {
    "path": "Reports/README.md",
    "chars": 4888,
    "preview": "# WorkloadTools Power BI Report\n\nTo analyze the data produced by WorkloadTools you can use the provided Power BI Templat"
  },
  {
    "path": "Setup/Product.wxs",
    "chars": 2671,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">\n\n  <?if $(var.Platform) = "
  },
  {
    "path": "Setup/Setup.wixproj",
    "chars": 3890,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  WiX v3 MSBuild project. Requires WiX Toolset v3.x to be installed.\n  See "
  },
  {
    "path": "Setup/SignMsi.ps1",
    "chars": 950,
    "preview": "[CmdletBinding()]\nParam(\n    [Parameter(Mandatory=$True,Position=1)]\n    [string]$InputFile,\n    [Parameter(Mandatory=$"
  },
  {
    "path": "Setup/buildmsi.ps1",
    "chars": 6800,
    "preview": "param (\n    [Parameter(Mandatory=$false)]\n    [string]$BuildVersion = \"1.0.0.0\",\n    [Parameter(Mandatory=$false)]\n    ["
  },
  {
    "path": "Setup/postbuild.bat",
    "chars": 120,
    "preview": "powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File %~dp0\\SignMsi.ps1 -InputFile %1 -OutputFile %2\n\n"
  },
  {
    "path": "Setup/transform-nodirs.xsl",
    "chars": 1007,
    "preview": "<?xml version=\"1.0\" ?>\n<xsl:stylesheet version=\"1.0\"\n    xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n    xmlns:wix="
  },
  {
    "path": "Setup/transform.xsl",
    "chars": 817,
    "preview": "<?xml version=\"1.0\" ?>\n<xsl:stylesheet version=\"1.0\"\n    xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n    xmlns:wix"
  },
  {
    "path": "Setup/transform2.xsl",
    "chars": 2497,
    "preview": "<?xml version=\"1.0\" ?>\n<xsl:stylesheet version=\"1.0\"\n    xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n    xmlns:wix="
  },
  {
    "path": "Setup/transform3.xsl",
    "chars": 1340,
    "preview": "<?xml version=\"1.0\" ?>\n<xsl:stylesheet version=\"1.0\"\n    xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n    xmlns:wix="
  },
  {
    "path": "SetupBootstrapper/Bundle.wxs",
    "chars": 1931,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\"\n     xmlns:bal=\"http://sche"
  },
  {
    "path": "SetupBootstrapper/License/License.rtf",
    "chars": 44906,
    "preview": "{\\rtf1\\adeflang1025\\ansi\\ansicpg1252\\uc1\\adeff0\\deff0\\stshfdbch0\\stshfloch31506\\stshfhich31506\\stshfbi31506\\deflang1033\\"
  },
  {
    "path": "SetupBootstrapper/SetupBootstrapper.wixproj",
    "chars": 3847,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  WiX v3 MSBuild project. Requires WiX Toolset v3.x to be installed.\n  See "
  },
  {
    "path": "SetupBootstrapper/SignMsi.ps1",
    "chars": 1230,
    "preview": "[CmdletBinding()]\nParam(\n    [Parameter(Mandatory=$True,Position=1)]\n    [string]$InputFile,\n    [Parameter(Mandatory=$"
  },
  {
    "path": "SetupBootstrapper/buildexe.ps1",
    "chars": 3693,
    "preview": "param (\n    [Parameter(Mandatory=$false)]\n    [string]$BuildVersion = \"1.0.0.0\",\n    [Parameter(Mandatory=$false)]\n    ["
  },
  {
    "path": "SetupBootstrapper/postbuild.bat",
    "chars": 120,
    "preview": "powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File %~dp0\\SignMsi.ps1 -InputFile %1 -OutputFile %2\n\n"
  },
  {
    "path": "SharedAssemblyInfo.cs",
    "chars": 1271,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "SqlWorkload/NLog.config",
    "chars": 1274,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<nlog xmlns=\"http://www.nlog-project.org/schemas/NLog.xsd\"\n      xmlns:xsi=\"htt"
  },
  {
    "path": "SqlWorkload/Program.cs",
    "chars": 5997,
    "preview": "using CommandLine;\nusing CommandLine.Text;\nusing NLog;\nusing NLog.Targets;\nusing System;\nusing System.Collections.Gener"
  },
  {
    "path": "SqlWorkload/Properties/AssemblyInfo.cs",
    "chars": 349,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "SqlWorkload/Properties/Resources.Designer.cs",
    "chars": 3070,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "SqlWorkload/Properties/Resources.resx",
    "chars": 5784,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "SqlWorkload/SqlWorkload.csproj",
    "chars": 5847,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "SqlWorkload/app.config",
    "chars": 567,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <startup>\n    <supportedRuntime version=\"v4.0\" sku=\".NETFramewo"
  },
  {
    "path": "SqlWorkload/packages.config",
    "chars": 377,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"CommandLineParser\" version=\"1.9.71\" targetFramework=\"n"
  },
  {
    "path": "WorkloadTools/BinarySerializedBufferedEventQueue.cs",
    "chars": 3144,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Thr"
  },
  {
    "path": "WorkloadTools/BufferedEventQueue.cs",
    "chars": 7292,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threadin"
  },
  {
    "path": "WorkloadTools/Config/AnalysisSample.json",
    "chars": 799,
    "preview": "{\n    \"Controller\": {\n\n        \"Listener\":\n        {\n            \"__type\": \"ExtendedEventsWorkloadListener\",\n          "
  },
  {
    "path": "WorkloadTools/Config/ReplaySample.json",
    "chars": 1125,
    "preview": "{\n    \"Controller\": {\n\n        \"Listener\":\n        {\n            \"__type\": \"ExtendedEventsWorkloadListener\",\n          "
  },
  {
    "path": "WorkloadTools/Config/Sample.json",
    "chars": 1127,
    "preview": "{\n    \"Controller\": {\n\n        \"Listener\":\n        {\n            \"__type\": \"ExtendedEventsWorkloadListener\",\n          "
  },
  {
    "path": "WorkloadTools/Config/SqlWorkloadConfig.cs",
    "chars": 3826,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threadin"
  },
  {
    "path": "WorkloadTools/Config/SqlWorkloadConfigTypeResolver.cs",
    "chars": 1409,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Web.Script.Ser"
  },
  {
    "path": "WorkloadTools/Consumer/Analysis/AnalysisConsumer.cs",
    "chars": 2142,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing WorkloadTools.C"
  },
  {
    "path": "WorkloadTools/Consumer/Analysis/DatabaseSchema.sql",
    "chars": 4684,
    "preview": "IF SCHEMA_ID('{SchemaName}') IS NULL\n    EXEC('CREATE SCHEMA [{SchemaName}]');\n\nIF OBJECT_ID('{SchemaName}.WorkloadDeta"
  },
  {
    "path": "WorkloadTools/Consumer/Analysis/NormalizedSqlText.cs",
    "chars": 1038,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Consumer"
  },
  {
    "path": "WorkloadTools/Consumer/Analysis/SqlTextNormalizer.cs",
    "chars": 19137,
    "preview": "using NLog;\nusing System;\nusing System.Collections;\nusing System.Collections.Concurrent;\nusing System.Collections.Gener"
  },
  {
    "path": "WorkloadTools/Consumer/Analysis/WorkloadAnalyzer.cs",
    "chars": 52017,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data;\nusing System.Data.SqlClient;\nusing Syste"
  },
  {
    "path": "WorkloadTools/Consumer/Analysis/createAnalysisView.sql",
    "chars": 38182,
    "preview": "ALTER PROCEDURE [dbo].[createAnalysisView]\n\t@baselineSchema AS nvarchar(max),\n\t@replaySchema AS nvarchar(max)\nAS\nBEGIN\n"
  },
  {
    "path": "WorkloadTools/Consumer/BufferedWorkloadConsumer.cs",
    "chars": 2487,
    "preview": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Te"
  },
  {
    "path": "WorkloadTools/Consumer/Replay/ReplayCommand.cs",
    "chars": 487,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Consumer"
  },
  {
    "path": "WorkloadTools/Consumer/Replay/ReplayConsumer.cs",
    "chars": 20130,
    "preview": "using System;\nusing System.CodeDom.Compiler;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusin"
  },
  {
    "path": "WorkloadTools/Consumer/Replay/ReplayWorker.cs",
    "chars": 29098,
    "preview": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Data;\nusing System.Da"
  },
  {
    "path": "WorkloadTools/Consumer/Replay/ReplayWorker.cs.bak",
    "chars": 5449,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.Linq;\nusing Syste"
  },
  {
    "path": "WorkloadTools/Consumer/Replay/ResultSetConsumer.cs",
    "chars": 743,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.Linq;\nusing System.Text;\n\nnam"
  },
  {
    "path": "WorkloadTools/Consumer/WorkloadConsumer.cs",
    "chars": 476,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Consumer"
  },
  {
    "path": "WorkloadTools/Consumer/WorkloadFile/WorkloadFileWriterConsumer.cs",
    "chars": 23980,
    "preview": "using NLog;\n\nusing System;\nusing System.Collections.Generic;\nusing System.Data;\nusing System.Data.SQLite;\nusing System."
  },
  {
    "path": "WorkloadTools/CounterWorkloadEvent.cs",
    "chars": 531,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools\n{\n    [S"
  },
  {
    "path": "WorkloadTools/DiskPerfWorkloadEvent.cs",
    "chars": 356,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\n\nnamespace Wor"
  },
  {
    "path": "WorkloadTools/ErrorWorkloadEvent.cs",
    "chars": 312,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadTools/ExecutionWorkloadEvent.cs",
    "chars": 904,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools\n{\n    [S"
  },
  {
    "path": "WorkloadTools/FilterPredicate.cs",
    "chars": 3357,
    "preview": "using System;\n\nnamespace WorkloadTools\n{\n    public abstract class FilterPredicate\n    {\n        private string[] _pred"
  },
  {
    "path": "WorkloadTools/IEventQueue.cs",
    "chars": 379,
    "preview": "using System;\n\nnamespace WorkloadTools\n{\n\n    public enum EventQueueType\n    {\n        MMF,\n        Sqlite,\n        Lit"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/ExtendedEventsEventFilter.cs",
    "chars": 1099,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Listener"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/ExtendedEventsFilterPredicate.cs",
    "chars": 3244,
    "preview": "using System;\n\nnamespace WorkloadTools.Listener.ExtendedEvents\n{\n    public class ExtendedEventsFilterPredicate : Filte"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/ExtendedEventsWorkloadListener.cs",
    "chars": 11472,
    "preview": "using Microsoft.SqlServer.XEvent.Linq;\nusing NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data.Sq"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/FileTargetXEventDataReader.cs",
    "chars": 22206,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Data.SqlC"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/StreamXEventDataReader.cs",
    "chars": 15782,
    "preview": "using Microsoft.SqlServer.XEvent.Linq;\nusing NLog;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Coll"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/XEventDataReader.cs",
    "chars": 1049,
    "preview": "using Microsoft.SqlServer.XEvent.Linq;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Gene"
  },
  {
    "path": "WorkloadTools/Listener/ExtendedEvents/sqlworkload.sql",
    "chars": 2220,
    "preview": "\nCREATE EVENT SESSION [sqlworkload] ON {1}\nADD EVENT sqlserver.attention (\n\tACTION(\t\n\t\tpackage0.event_sequence, \n\t\tsqls"
  },
  {
    "path": "WorkloadTools/Listener/File/FileEventFilter.cs",
    "chars": 692,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Listener"
  },
  {
    "path": "WorkloadTools/Listener/File/FileFilterPredicate.cs",
    "chars": 1813,
    "preview": "using System;\n\nnamespace WorkloadTools.Listener.File\n{\n    public class FileFilterPredicate : FilterPredicate\n    {\n   "
  },
  {
    "path": "WorkloadTools/Listener/File/FileWorkloadListener.cs",
    "chars": 16105,
    "preview": "using System;\nusing System.Data;\nusing System.Data.Common;\nusing System.Data.SQLite;\nusing System.Linq;\nusing System.Te"
  },
  {
    "path": "WorkloadTools/Listener/ReadIteration.cs",
    "chars": 4597,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadTools/Listener/SqlTransformer.cs",
    "chars": 11167,
    "preview": "using Microsoft.SqlServer.Management.SqlParser.Metadata;\nusing System;\nusing System.Collections.Generic;\nusing System.L"
  },
  {
    "path": "WorkloadTools/Listener/Trace/FileTraceEventDataReader.cs",
    "chars": 16003,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.IO;\nusing System."
  },
  {
    "path": "WorkloadTools/Listener/Trace/ProfilerEventFilter.cs",
    "chars": 673,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Listener"
  },
  {
    "path": "WorkloadTools/Listener/Trace/ProfilerFilterPredicate.cs",
    "chars": 427,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Listener"
  },
  {
    "path": "WorkloadTools/Listener/Trace/ProfilerWorkloadListener.cs",
    "chars": 5124,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\nusi"
  },
  {
    "path": "WorkloadTools/Listener/Trace/SqlConnectionInfoWrapper.cs",
    "chars": 2902,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Te"
  },
  {
    "path": "WorkloadTools/Listener/Trace/SqlTraceWorkloadListener.cs",
    "chars": 10199,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Data;\nusi"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceEventDataReader.cs",
    "chars": 958,
    "preview": "using Microsoft.SqlServer.XEvent.Linq;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Gene"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceEventFilter.cs",
    "chars": 655,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Listener"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceEventParser.cs",
    "chars": 6616,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.Linq;\nusing System.Text;\nusin"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceFileWrapper.cs",
    "chars": 3372,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Te"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceFilterPredicate.cs",
    "chars": 1877,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools.Listener"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceServerWrapper.cs",
    "chars": 3991,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.Linq;\nusing Syste"
  },
  {
    "path": "WorkloadTools/Listener/Trace/TraceUtils.cs",
    "chars": 2374,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Data.SqlClient;\nusing System.Linq;\nusing System.Text;\nusin"
  },
  {
    "path": "WorkloadTools/Listener/Trace/sqlworkload.sql",
    "chars": 4822,
    "preview": "\n-- Create a Queue\ndeclare @rc int\ndeclare @TraceID int\ndeclare @maxfilesize bigint\nset @maxfilesize = '{0}';\n\ndeclare "
  },
  {
    "path": "WorkloadTools/MMFEventQueue.cs",
    "chars": 1561,
    "preview": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Te"
  },
  {
    "path": "WorkloadTools/MessagWorkloadEvent.cs",
    "chars": 496,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadTools/Properties/AssemblyInfo.cs",
    "chars": 247,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// The following"
  },
  {
    "path": "WorkloadTools/Properties/Settings.Designer.cs",
    "chars": 1880,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "WorkloadTools/Properties/Settings.settings",
    "chars": 603,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\""
  },
  {
    "path": "WorkloadTools/Properties/SharedAssemblyInfo.cs",
    "chars": 1267,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "WorkloadTools/SqlConnectionInfo.cs",
    "chars": 3239,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools\n{\n    pu"
  },
  {
    "path": "WorkloadTools/SqliteEventQueue.cs",
    "chars": 943,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadTools/Util/DataUtils.cs",
    "chars": 1880,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Data;\nusing System.Linq;\nusing System.Reflection;\nusing Sy"
  },
  {
    "path": "WorkloadTools/Util/ModelConverter.cs",
    "chars": 5406,
    "preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing S"
  },
  {
    "path": "WorkloadTools/Util/RingBuffer.cs",
    "chars": 12501,
    "preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace Workload"
  },
  {
    "path": "WorkloadTools/Util/StringExtensions.cs",
    "chars": 1100,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadTools/WaitStatsWorkloadEvent.cs",
    "chars": 357,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Data;\nusing System.Linq;\nusing System.Text;\n\nnamespace Wor"
  },
  {
    "path": "WorkloadTools/WorkloadController.cs",
    "chars": 4246,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threadin"
  },
  {
    "path": "WorkloadTools/WorkloadEvent.cs",
    "chars": 671,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools\n{\n    [S"
  },
  {
    "path": "WorkloadTools/WorkloadEventFilter.cs",
    "chars": 2954,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace WorkloadTools\n{\n    pu"
  },
  {
    "path": "WorkloadTools/WorkloadListener.cs",
    "chars": 31091,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Data;\nusi"
  },
  {
    "path": "WorkloadTools/WorkloadTools.csproj",
    "chars": 22380,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "WorkloadTools/app.config",
    "chars": 1412,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <configSections>\n        <sectionGroup name=\"applicationSetti"
  },
  {
    "path": "WorkloadTools/packages.config",
    "chars": 539,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"DouglasCrockford.JsMin\" version=\"1.1.3\" targetFramewor"
  },
  {
    "path": "WorkloadTools.sln",
    "chars": 8585,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.6.3382"
  },
  {
    "path": "WorkloadToolsTests/Properties/AssemblyInfo.cs",
    "chars": 162,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n\n[assembly: Guid("
  },
  {
    "path": "WorkloadToolsTests/WorkloadTools/BinarySerializedBufferedEventQueueTest.cs",
    "chars": 6472,
    "preview": "using System;\nusing System.Diagnostics;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing WorkloadTools;\n\nnames"
  },
  {
    "path": "WorkloadToolsTests/WorkloadTools/SqlTextNormalizerTest.cs",
    "chars": 1986,
    "preview": "using Microsoft.VisualStudio.TestTools.UnitTesting;\nusing WorkloadTools.Consumer.Analysis;\n\nnamespace WorkloadToolsTests"
  },
  {
    "path": "WorkloadToolsTests/WorkloadToolsTests.csproj",
    "chars": 5509,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.micros"
  },
  {
    "path": "WorkloadToolsTests/app.config",
    "chars": 520,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com"
  },
  {
    "path": "WorkloadToolsTests/packages.config",
    "chars": 222,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"MSTest.TestAdapter\" version=\"1.3.2\" targetFramework=\"n"
  },
  {
    "path": "WorkloadViewer/App.config",
    "chars": 178,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NET"
  },
  {
    "path": "WorkloadViewer/App.xaml",
    "chars": 1499,
    "preview": "<Application x:Class=\"WorkloadViewer.App\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"htt"
  },
  {
    "path": "WorkloadViewer/App.xaml.cs",
    "chars": 3926,
    "preview": "using CommandLine;\nusing CommandLine.Text;\nusing NLog;\nusing NLog.Targets;\nusing System;\nusing System.Collections.Gener"
  },
  {
    "path": "WorkloadViewer/Comparer/QueryResultEqualityComparer.cs",
    "chars": 366,
    "preview": "using System.Collections.Generic;\n\nusing WorkloadViewer.ViewModel;\n\npublic class QueryResultEqualityComparer : IEqualit"
  },
  {
    "path": "WorkloadViewer/Model/NormalizedQuery.cs",
    "chars": 337,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadViewer/Model/QueryDetails.cs",
    "chars": 12251,
    "preview": "using OxyPlot;\nusing OxyPlot.Axes;\nusing OxyPlot.Series;\nusing System;\nusing System.Collections.Generic;\nusing System.D"
  },
  {
    "path": "WorkloadViewer/Model/SqlConnectionInfo.cs",
    "chars": 2050,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadViewer/Model/WorkloadAnalysis.cs",
    "chars": 6803,
    "preview": "using NLog;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Data.Sql"
  },
  {
    "path": "WorkloadViewer/Model/WorkloadAnalysisPoint.cs",
    "chars": 1282,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadViewer/NLog.config",
    "chars": 928,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<nlog xmlns=\"http://www.nlog-project.org/schemas/NLog.xsd\"\n      xmlns:xsi=\"htt"
  },
  {
    "path": "WorkloadViewer/Properties/AssemblyInfo.cs",
    "chars": 1742,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "WorkloadViewer/Properties/Resources.Designer.cs",
    "chars": 4162,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "WorkloadViewer/Properties/Resources.resx",
    "chars": 6308,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "WorkloadViewer/Properties/Settings.Designer.cs",
    "chars": 1069,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "WorkloadViewer/Properties/Settings.settings",
    "chars": 193,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"uri:settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    "
  },
  {
    "path": "WorkloadViewer/Resources/TSQL.xshd",
    "chars": 106335,
    "preview": "<?xml version=\"1.0\"?>\n<!-- Shades of Red-Brown: #a31515, #cf4315, #ffb96e, #ffdc95 -->\n<!-- Shades of Bright-Blue: #007"
  },
  {
    "path": "WorkloadViewer/Resources/WorkloadAnalysis.sql",
    "chars": 2302,
    "preview": "WITH baseData AS (\n\tSELECT \n\t\tDATEDIFF(minute, Base.end_time, bIn.end_time) AS offset_minutes,\n\t\tbWD.sql_hash, \n\t\tbWD.a"
  },
  {
    "path": "WorkloadViewer/View/ConnectionInfoDialog.xaml",
    "chars": 801,
    "preview": "<Dialog:CustomDialog x:Class=\"WorkloadViewer.View.ConnectionInfoDialog\"\n        xmlns=\"http://schemas.microsoft.com/win"
  },
  {
    "path": "WorkloadViewer/View/ConnectionInfoDialog.xaml.cs",
    "chars": 675,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusi"
  },
  {
    "path": "WorkloadViewer/View/ConnectionInfoDialogStyle.xaml",
    "chars": 4204,
    "preview": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http"
  },
  {
    "path": "WorkloadViewer/View/ConnectionInfoEditor.xaml",
    "chars": 5550,
    "preview": "<UserControl x:Class=\"WorkloadViewer.View.ConnectionInfoEditor\"\n             xmlns=\"http://schemas.microsoft.com/winfx/"
  },
  {
    "path": "WorkloadViewer/View/ConnectionInfoEditor.xaml.cs",
    "chars": 1949,
    "preview": "using GalaSoft.MvvmLight.Messaging;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Tex"
  },
  {
    "path": "WorkloadViewer/View/MainWindow.xaml",
    "chars": 29993,
    "preview": "<Controls:MetroWindow x:Class=\"WorkloadViewer.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/p"
  },
  {
    "path": "WorkloadViewer/View/MainWindow.xaml.cs",
    "chars": 3425,
    "preview": "using GalaSoft.MvvmLight.Messaging;\nusing ICSharpCode.AvalonEdit;\nusing MahApps.Metro.Controls;\nusing System;\nusing Sys"
  },
  {
    "path": "WorkloadViewer/ViewModel/ConnectionInfoEditorViewModel.cs",
    "chars": 3449,
    "preview": "using GalaSoft.MvvmLight;\nusing GalaSoft.MvvmLight.Command;\nusing GalaSoft.MvvmLight.Messaging;\nusing MahApps.Metro.Con"
  },
  {
    "path": "WorkloadViewer/ViewModel/DictionaryExtensions.cs",
    "chars": 1772,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadViewer/ViewModel/FilterDefinition.cs",
    "chars": 703,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "WorkloadViewer/ViewModel/LinqExtensions.cs",
    "chars": 2700,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Text;\nus"
  },
  {
    "path": "WorkloadViewer/ViewModel/MainViewModel.cs",
    "chars": 34625,
    "preview": "using GalaSoft.MvvmLight;\nusing GalaSoft.MvvmLight.Command;\nusing MahApps.Metro.Controls.Dialogs;\nusing OxyPlot;\nusing O"
  },
  {
    "path": "WorkloadViewer/ViewModel/Message.cs",
    "chars": 346,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\nusin"
  },
  {
    "path": "WorkloadViewer/ViewModel/QueryResult.cs",
    "chars": 1661,
    "preview": "using WorkloadViewer.Model;\n\nnamespace WorkloadViewer.ViewModel\n{\n    public class QueryResult\n    {\n        public lon"
  },
  {
    "path": "WorkloadViewer/ViewModel/SortColMessage.cs",
    "chars": 506,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\nusin"
  },
  {
    "path": "WorkloadViewer/ViewModel/ViewModelLocator.cs",
    "chars": 1755,
    "preview": "/*\n  In App.xaml:\n  <Application.Resources>\n      <vm:ViewModelLocator xmlns:vm=\"clr-namespace:WorkloadViewer\"\n         "
  },
  {
    "path": "WorkloadViewer/WorkloadViewer.csproj",
    "chars": 10835,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "WorkloadViewer/packages.config",
    "chars": 1862,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"AvalonEdit\" version=\"5.0.4\" targetFramework=\"net461\" /"
  },
  {
    "path": "build.ps1",
    "chars": 1364,
    "preview": "\n# ---------------------------------------------------------------------------\n# Locate MSBuild via vswhere (ships with "
  }
]

// ... and 4 more files (download for full content)

About this extraction

This page contains the full source code of the spaghettidba/WorkloadTools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 176 files (904.9 KB), approximately 218.5k tokens, and a symbol index with 505 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!