Full Code of yarseyah/sentinel for AI

master 93aa321bb74e cached
280 files
767.7 KB
151.3k tokens
873 symbols
1 requests
Download .txt
Showing preview only (843K chars total). Download the full file or copy to clipboard to get everything.
Repository: yarseyah/sentinel
Branch: master
Commit: 93aa321bb74e
Files: 280
Total size: 767.7 KB

Directory structure:
gitextract_gjrp28h9/

├── .gitattributes
├── .github/
│   └── dependabot.yml
├── .gitignore
├── CONTRIBUTING.md
├── CustomDictionary.xml
├── GitVersion.yml
├── LICENSE.md
├── README.md
├── Sentinel/
│   ├── .vscode/
│   │   ├── launch.json
│   │   └── tasks.json
│   ├── Classification/
│   │   ├── Classifier.cs
│   │   ├── ClassifyingService.cs
│   │   ├── Gui/
│   │   │   ├── AddClassifier.cs
│   │   │   ├── AddEditClassifier.cs
│   │   │   ├── AddEditClassifierWindow.xaml
│   │   │   ├── AddEditClassifierWindow.xaml.cs
│   │   │   ├── ClassificationsControl.xaml
│   │   │   ├── ClassificationsControl.xaml.cs
│   │   │   ├── EditClassifier.cs
│   │   │   └── RemoveClassifier.cs
│   │   └── Interfaces/
│   │       ├── IAddClassifyingService.cs
│   │       ├── IClassifier.cs
│   │       ├── IClassifyingService.cs
│   │       ├── IEditClassifyingService.cs
│   │       └── IRemoveClassifyingService.cs
│   ├── Controls/
│   │   ├── AboutWindow.xaml
│   │   ├── AboutWindow.xaml.cs
│   │   ├── ImageTypesControl.xaml
│   │   ├── ImageTypesControl.xaml.cs
│   │   ├── IntegerTextBox.cs
│   │   ├── LogActivityControl.xaml
│   │   ├── LogActivityControl.xaml.cs
│   │   ├── MainWindow.xaml
│   │   ├── MainWindow.xaml.cs
│   │   ├── PersistingSettings.cs
│   │   ├── PreferencesControl.xaml
│   │   ├── PreferencesControl.xaml.cs
│   │   ├── PreferencesWindow.xaml
│   │   ├── PreferencesWindow.xaml.cs
│   │   ├── RecentFileInfo.cs
│   │   └── WindowPlacementInfo.cs
│   ├── EventLogMonitor/
│   │   ├── CommandLineOptions.cs
│   │   ├── EventLogEntry.cs
│   │   └── Interfaces/
│   │       └── IEventLogEntry.cs
│   ├── Extractors/
│   │   ├── ExtractingService.cs
│   │   ├── Extractor.cs
│   │   ├── Gui/
│   │   │   ├── AddEditExtractor.cs
│   │   │   ├── AddEditExtractorWindow.xaml
│   │   │   ├── AddEditExtractorWindow.xaml.cs
│   │   │   ├── AddExtractor.cs
│   │   │   ├── EditExtractor.cs
│   │   │   ├── ExtractorsControl.xaml
│   │   │   ├── ExtractorsControl.xaml.cs
│   │   │   └── RemoveExtractor.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddExtractorService.cs
│   │   │   ├── IEditExtractorService.cs
│   │   │   ├── IExtractingService.cs
│   │   │   ├── IExtractor.cs
│   │   │   ├── IRemoveExtractorService.cs
│   │   │   └── ISearchExtractor.cs
│   │   └── SearchExtractor.cs
│   ├── FileMonitor/
│   │   ├── CustomMessageDecoderPage.xaml
│   │   ├── CustomMessageDecoderPage.xaml.cs
│   │   ├── FileMonitorProviderPage.xaml
│   │   ├── FileMonitorProviderPage.xaml.cs
│   │   ├── FileMonitoringProvider.cs
│   │   ├── FileMonitoringProviderSettings.cs
│   │   ├── IFileMonitoringProviderSettings.cs
│   │   ├── LogEntry.cs
│   │   ├── MessageFormatPage.xaml
│   │   ├── MessageFormatPage.xaml.cs
│   │   └── ProviderRegistrationInformation.cs
│   ├── Filters/
│   │   ├── Filter.cs
│   │   ├── FilteringService.cs
│   │   ├── Gui/
│   │   │   ├── AddEditFilter.cs
│   │   │   ├── AddEditFilterWindow.xaml
│   │   │   ├── AddEditFilterWindow.xaml.cs
│   │   │   ├── AddFilter.cs
│   │   │   ├── EditFilter.cs
│   │   │   ├── FiltersControl.xaml
│   │   │   ├── FiltersControl.xaml.cs
│   │   │   └── RemoveFilter.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddFilterService.cs
│   │   │   ├── IEditFilterService.cs
│   │   │   ├── IFilter.cs
│   │   │   ├── IFilteringService.cs
│   │   │   ├── IRemoveFilterService.cs
│   │   │   ├── ISearchFilter.cs
│   │   │   └── IStandardDebuggingFilter.cs
│   │   ├── SearchFilter.cs
│   │   └── StandardFilter.cs
│   ├── Highlighters/
│   │   ├── Gui/
│   │   │   ├── AddEditHighlighter.cs
│   │   │   ├── AddEditHighlighterWindow.xaml
│   │   │   ├── AddEditHighlighterWindow.xaml.cs
│   │   │   ├── AddNewHighlighterService.cs
│   │   │   ├── EditHighlighterService.cs
│   │   │   ├── HighlightersControl.xaml
│   │   │   ├── HighlightersControl.xaml.cs
│   │   │   └── RemoveHighlighterService.cs
│   │   ├── Highlighter.cs
│   │   ├── HighlighterConverter.cs
│   │   ├── HighlighterStyle.cs
│   │   ├── HighlightingSelector.cs
│   │   ├── HighlightingService.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddHighlighterService.cs
│   │   │   ├── IEditHighlighterService.cs
│   │   │   ├── IHighlighter.cs
│   │   │   ├── IHighlightingService.cs
│   │   │   ├── IRemoveHighlighterService.cs
│   │   │   ├── ISearchHighlighter.cs
│   │   │   └── IStandardDebuggingHighlighter.cs
│   │   ├── SearchHighlighter.cs
│   │   └── StandardHighlighter.cs
│   ├── Images/
│   │   ├── AddEditTypeImageViewModel.cs
│   │   ├── AddTypeImageService.cs
│   │   ├── Controls/
│   │   │   ├── AddImageWindow.xaml
│   │   │   └── AddImageWindow.xaml.cs
│   │   ├── EditTypeImageMapping.cs
│   │   ├── ImageQuality.cs
│   │   ├── ImageTypeRecord.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddTypeImage.cs
│   │   │   ├── IEditTypeImage.cs
│   │   │   ├── IRemoveTypeImage.cs
│   │   │   ├── ITypeImageService.cs
│   │   │   └── ImageOptions.cs
│   │   ├── RemoveTypeImageMapping.cs
│   │   └── TypeToImageService.cs
│   ├── Interfaces/
│   │   ├── CaseInsensitiveComparer.cs
│   │   ├── CodeContracts/
│   │   │   ├── ThrowIfNull.cs
│   │   │   ├── ThrowIfNullOrWhitespace.cs
│   │   │   └── ValidatedNotNullAttribute.cs
│   │   ├── CollectionChangeHelper.cs
│   │   ├── EnumerableExtensions.cs
│   │   ├── IDefaultInitialisation.cs
│   │   ├── IHighlighterStyle.cs
│   │   ├── ILogEntry.cs
│   │   ├── ILogger.cs
│   │   ├── IUserPreferences.cs
│   │   ├── LinqHelpers.cs
│   │   ├── LogEntryFields.cs
│   │   ├── MatchMode.cs
│   │   └── Providers/
│   │       ├── ILogProvider.cs
│   │       ├── INetworkProvider.cs
│   │       ├── IProviderInfo.cs
│   │       ├── IProviderRegistrationRecord.cs
│   │       └── IProviderSettings.cs
│   ├── Log4Net/
│   │   ├── ConfigurationPage.xaml
│   │   ├── ConfigurationPage.xaml.cs
│   │   ├── IUdpAppenderListenerSettings.cs
│   │   ├── Log4NetProvider.cs
│   │   ├── LogEntry.cs
│   │   ├── ProviderRegistrationInformation.cs
│   │   ├── UdpAppenderSettings.cs
│   │   └── XElementHelpers.cs
│   ├── Logger/
│   │   ├── ILogViewerDetails.cs
│   │   ├── IUdpLogViewer.cs
│   │   └── LogWriter.cs
│   ├── Logs/
│   │   ├── Gui/
│   │   │   ├── AddNewLoggerWelcomePage.xaml
│   │   │   ├── AddNewLoggerWelcomePage.xaml.cs
│   │   │   ├── NewLoggerSettings.cs
│   │   │   ├── NewLoggerSummaryPage.xaml
│   │   │   ├── NewLoggerSummaryPage.xaml.cs
│   │   │   ├── NewLoggerWizard.cs
│   │   │   ├── ProvidersPage.xaml
│   │   │   ├── ProvidersPage.xaml.cs
│   │   │   ├── SetLoggerNamePage.xaml
│   │   │   ├── SetLoggerNamePage.xaml.cs
│   │   │   ├── ViewSelectionPage.xaml
│   │   │   └── ViewSelectionPage.xaml.cs
│   │   ├── Interfaces/
│   │   │   ├── ILogFileExporter.cs
│   │   │   └── ILogManager.cs
│   │   ├── Log.cs
│   │   ├── LogFileExporter.cs
│   │   └── LogManager.cs
│   ├── MSBuild/
│   │   ├── ConfigurationPage.xaml
│   │   ├── ConfigurationPage.xaml.cs
│   │   ├── IMSBuildListenerSettings.cs
│   │   ├── LogEntry.cs
│   │   ├── MSBuildListenerSettings.cs
│   │   ├── MSBuildProvider.cs
│   │   ├── ProviderInfo.cs
│   │   └── ProviderRegistrationInformation.cs
│   ├── MainApplication.xaml
│   ├── MainApplication.xaml.cs
│   ├── NLog/
│   │   ├── INLogAppenderSettings.cs
│   │   ├── LogEntry.cs
│   │   ├── NLogViewerProvider.cs
│   │   ├── NetworkClientWrapper.cs
│   │   ├── NetworkConfigurationPage.xaml
│   │   ├── NetworkConfigurationPage.xaml.cs
│   │   ├── NetworkProtocol.cs
│   │   ├── NetworkSettings.cs
│   │   ├── ProviderInfo.cs
│   │   ├── ProviderRegistrationInformation.cs
│   │   └── ProviderSettings.cs
│   ├── Preferences/
│   │   └── UserPreferences.cs
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Resources.Designer.cs
│   │   ├── Resources.resx
│   │   ├── Settings.Designer.cs
│   │   ├── Settings.settings
│   │   └── app.manifest
│   ├── Providers/
│   │   ├── Interfaces/
│   │   │   ├── INewProviderWizard.cs
│   │   │   ├── IProviderManager.cs
│   │   │   └── PendingProviderRecord.cs
│   │   ├── NewProviderWizard.cs
│   │   ├── ProviderInfo.cs
│   │   ├── ProviderManager.cs
│   │   ├── ProviderRegistrationRecord.cs
│   │   ├── ProviderSettings.cs
│   │   ├── SelectProviderPage.xaml
│   │   └── SelectProviderPage.xaml.cs
│   ├── Sentinel.csproj
│   ├── Services/
│   │   ├── AttributeHelper.cs
│   │   ├── DictionaryHelper.cs
│   │   ├── Interfaces/
│   │   │   └── ISessionManager.cs
│   │   ├── ServiceLocator.cs
│   │   └── SessionManager.cs
│   ├── StartUp/
│   │   ├── IOptions.cs
│   │   ├── Log4NetOptions.cs
│   │   └── NLogOptions.cs
│   ├── Support/
│   │   ├── Converters/
│   │   │   ├── BooleanToWidthConverter.cs
│   │   │   ├── CollapseIfNullConverter.cs
│   │   │   ├── DatePreferenceConverter.cs
│   │   │   ├── ImageLibraryConverter.cs
│   │   │   ├── LongPathToShortPathConverter.cs
│   │   │   ├── MessageHasExceptionMetadataConverter.cs
│   │   │   ├── MetaDataConverter.cs
│   │   │   ├── MetaDataParameterConverter.cs
│   │   │   ├── TimePreferenceConverter.cs
│   │   │   ├── TimeSinceDateTimeConverter.cs
│   │   │   ├── TypeToImageConverter.cs
│   │   │   ├── TypeToLargeImageConverter.cs
│   │   │   ├── TypeToMediumImageConverter.cs
│   │   │   └── TypeToSmallImageConverter.cs
│   │   ├── GridViewSort.cs
│   │   ├── JsonHelper.cs
│   │   ├── ScrollingHelper.cs
│   │   └── Wpf/
│   │       ├── DataBoundToolbar.cs
│   │       ├── FixedWidthColumn.cs
│   │       ├── ObservableDictionary.cs
│   │       └── ThemeInfo.cs
│   ├── Views/
│   │   ├── Gui/
│   │   │   ├── LogMessages.cs
│   │   │   ├── LogMessagesControl.xaml
│   │   │   ├── LogMessagesControl.xaml.cs
│   │   │   ├── LogViewerToolbarButton.cs
│   │   │   ├── MultipleViewFrame.xaml
│   │   │   ├── MultipleViewFrame.xaml.cs
│   │   │   └── ViewInformation.cs
│   │   ├── Heartbeat/
│   │   │   ├── HeartbeatControl.xaml
│   │   │   ├── HeartbeatControl.xaml.cs
│   │   │   ├── MessageHeatbeat.cs
│   │   │   └── ViewInformation.cs
│   │   ├── Interfaces/
│   │   │   ├── ILogViewer.cs
│   │   │   ├── ILogViewerToolbarButton.cs
│   │   │   ├── IViewInformation.cs
│   │   │   ├── IViewManager.cs
│   │   │   └── IWindowFrame.cs
│   │   └── ViewManager.cs
│   └── WpfExtras/
│       ├── Converters/
│       │   ├── BooleanInvertingValueConverter.cs
│       │   ├── BooleanToDisabledConverter.cs
│       │   ├── CollapseIfFalseConverter.cs
│       │   ├── CollapseIfZeroConverter.cs
│       │   ├── ColourConverter.cs
│       │   ├── VisibilityToCollapsedConverter.cs
│       │   └── VisibilityToHiddenConverter.cs
│       ├── DelegateCommand.cs
│       ├── EstablishPossibleNavigation.cs
│       ├── IWizardPage.cs
│       ├── PageChange.cs
│       ├── PageNavigationTreeEntry.cs
│       ├── ViewModelBase.cs
│       ├── Wizard.xaml
│       └── Wizard.xaml.cs
├── Sentinel.sln
├── Sentinel.sln.DotSettings
├── Settings.StyleCop
├── SharedAssemblyInfo.cs
├── StyleCop/
│   └── StyleCopRules.ruleset
└── docs/
    └── Home.md

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

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

###############################################################################
# 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: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  - package-ecosystem: "nuget"
    directory: "/" # Location of package manifests
    schedule:
      interval: "daily"


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

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

# Build results
Installs/
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
.vs/

# Squirrel releases
Releases/
*.nupkg
*.nuspec

# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/

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

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

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

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

# Guidance Automation Toolkit
*.gpState

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

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
*.ncrunch*
.*crunch*.local.xml

# 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
*.Publish.xml

# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/

# Windows Azure Build Output
csx
*.build.csdef

# Windows Store app package directory
AppPackages/

# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings

# 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
App_Data/*.mdf
App_Data/*.ldf


#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml

# =========================
# Windows detritus
# =========================

# Windows image file caches
Thumbs.db
ehthumbs.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Mac desktop service store files
.DS_Store

# Nuget
packages
/.vs
/.idea


================================================
FILE: CONTRIBUTING.md
================================================
Releases are made from the master branch, but new developments are done on the develop branch.  There are a lot of new developments on that branch, so please be aware as changes to master directly may not merge nicely.


================================================
FILE: CustomDictionary.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<Dictionary>
  <Words>
    <Recognized>
      <Word>Colour</Word>
      <Word>Colours</Word>
      <Word>Initialise</Word>
      <Word>Initialisation</Word>
      <Word>Appender</Word>
      <Word>Ms</Word>
      <Word>Gui</Word>
      <Word>Mvvm</Word>
    </Recognized>
    <!--<Deprecated>
      <Term PreferredAlternate="ModelViewViewModel">Mvvm</Term>
    </Deprecated>-->
  </Words>
  <Acronyms>
    <CasingExceptions>
    </CasingExceptions>
  </Acronyms>

</Dictionary>

================================================
FILE: GitVersion.yml
================================================
mode: Mainline
branches: {}
ignore:
  sha: []
merge-message-formats: {}


================================================
FILE: LICENSE.md
================================================
# Microsoft Public License (Ms-PL)

Microsoft Public License (Ms-PL)

This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.

1. Definitions

The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.

A "contribution" is the original software, or any additions or changes to the software.

A "contributor" is any person that distributes its contribution under this license.

"Licensed patents" are a contributor's patent claims that read directly on its contribution.

2. Grant of Rights

(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.

(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.

3. Conditions and Limitations

(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.

(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.

(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.

(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.

(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.


================================================
FILE: README.md
================================================
# ![](docs/Debug.png) sentinel
Log-viewer with filtering and highlighting

![](docs/Home_sentinel-0.11.0.0.png)

## Log Sources 
Sentinel is a viewer for log-files - specifically I designed it to act as a network end-point for the likes of nLog and log4net, additionally it then works really well for capturing log entries from multiple sources.  

Source                | Status
--------------------- | ------
Log4Net UdpAppender   | Supported 
nLog's nLogViewer     | Supported
Trace Listener        | Planned
Log-File Watcher      | Experimental
Custom, via plug-in   | Planned
MSBuild               | Plug-in in source-repo

## Command-Line usage
There are command line options that allow control over Sentinel when started, options available include the following:
* Loading of a saved Session File
* nLog network listener
* log4net network listener

## Command line options
If no command line options are specified, the standard New Session wizard will launch at start-up.

### Launch with NLog listener enabled
```
sentinel nlog [--port <port-number>] [--tcp]
```
Defaults to port 9999 and Udp if not specified.

### Launch with Log4Net listener enabled
```
sentinel log4net [--port <port-number>]
```
Defaults to port 9998 if not specified.

### Launch with previously saved session file
```
sentinel filename.SNTL
```

## nLog's NLogViewer target configuration
To allow a nLog based application transmit its log messages to Sentinel, use a configuration like the one shown below:
```xml
<?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">
  <targets>
    <target xsi:type="NLogViewer"
            name="viewer"
            address="udp://127.0.0.1:9999"/>
  </targets>
  <rules>
    <logger name="*"
            minlevel="Debug"
            writeTo="viewer" />
  </rules>
</nlog>
```

### Showing nLog debug information (0.12.0.0 onwards)
If the above configuration is adjusted to enable {{includeSourceInfo}} then it is possible to see the file, class, method and line number corresponding to where the message is emitted.  Some of this information is only reported if the source program is compiled in DEBUG mode (e.g. RELEASE mode strips this information)
```xml
<target name="viewer"
        xsi:type="NLogViewer"
        includeSourceInfo="true"
        address="udp://127.0.0.1:9999" />
```

## Log4Net UdpAppender configuration
To allow a log4net application transmit its log messages to Sentinel, use a configuration like the one shown below:
```xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net"
             type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

  <log4net>
    <appender name="udp"
              type="log4net.Appender.UdpAppender">

      <RemoteAddress value="127.0.0.2"/>
      <RemotePort value="9999"/>
      <layout type="log4net.Layout.XmlLayout"/>
      <encoding value="utf-8" />
    </appender>

    <root>
      <appender-ref ref="udp"/>
    </root>
  </log4net>
</configuration>
```
### Showing log4net debug information (0.12.1.0 onwards)
If the above configuration is adjusted to enable {{locationInfo}} then it is possible to see the file, class, method and line number corresponding to where the message is emitted.  Some of this information is only reported if the source program is compiled in DEBUG mode (e.g. RELEASE mode strips this information)
```xml
<layout type="log4net.Layout.XmlLayout">
    <locationInfo value="true" />
</layout>
```

## Log Entries
Log file entries map the the following interface.  This is core record for a log-file entry and used to populate the columns within the live-log view.  Note, by using [Classifiers](#Classifiers) it is possible to rearrange and/or change the content of these fields upon receiving a new log-entry.

```c#
public interface ILogEntry
{
    string Classification { get; set; }
    DateTime DateTime { get; set; }
    string Description { get; set; }
    string Source { get; set; }
    string System { get; set; }
    string Thread { get; set; }
    string Type { get; set; }
}
```

Log entries may be classified, highlighted and filtered based upon special services:
* Classifiers can change the properties of a log entry
* Highlighters can change its appearance.
* Filters can be used to suppress the displaying of matching entries.

## Classifiers
Upon receiving a new log-entry it is processed through registered classifiers.  Classifiers have the ability to rewrite the log-entry prior to passing it to the visualisation aspect of Sentinel. 

As an example, suppose the incoming message when starting with the phrase "Sleeping for another" is intended to be switched from its supplied type (e.g. DEBUG or INFO) to its own type **Timing**.  The ClassifierViewModel registers this on construction.  Note that the regular expression below also rewrites the Description to the named-capture _description_, effectively stripping off the prefix "Sleeping for another" - information no longer needed due to the reclassification.

```c#
items.Add(
	new DescriptionTypeClassifier("Timing", "Timing")
		{
			Enabled = true,
			Name = "Timing messages",
			RegexString = @"^Sleeping for another (?<description>[^$](^$)+)$"
		});
```

In addition to reclassifying messages, the Classifier mechanism is currently used to make other changes to the message appearance.  Continuing the example above, using a {{TypeImageClassifier}} it is possible to specify the image to be used for entries with a type of **Timing**.

```c#
items.Add(
	new TypeImageClassifier("Timing", "/Resources/Clock.png")
		{
			Enabled = true,
			Name = "Timing Image",
		});
```
The classifiers can be seen in the Preferences dialog-box.

![Preferences - Classifiers](docs/Home_Preferences-Classifiers.png)
## Highlighters
Customisable and extendible highlighters that may be toggled on and off during live preview.  The current implementation limits pattern matching to the Type and System fields, although this will be extended to all fields.  An example of why this is useful, in the classifiers section above, a new type of "Timing" was added, this type can get its own highlighting style.  

![Preferences - Highlighters](docs/Home_Preferences-Highlighters.png)

Highlighters can match the contents of the Type and System fields
* Exact Strings
* Substrings
* Regular Expressions

![Adding Regex Highlighter](docs/Home_Add%20Highlighter%20-%20Regex.png)

If the matching field is set to **Type** an the match string specified as "Timing", a new highlighter for the timing can be added.  User-defined highlighters are automatically added to the toolbar for ease of enabling and disabling of the highlighting.  

![Toolbar - User defined highlighters](docs/Home_Toolbar%20-%20User%20defined%20highlighter.png)

The highlighters work on a first-come, wins principle.  Therefore, the order of the entries in the highlighters section of the Preferences dialog-box are important.  It is possible to hide the highlighting of  FATAL messages if a highlighter is positioned before FATAL and gets a match.

## Filters
Filters are very much like highlighters except their purpose is to remove log-entries from the displayed values (note, the values are not lost, just hidden).  Filters may be toggled on and off during the session.  Filters are evaluated in the order specified, but since filters works on an any-match = hide principle the evaluation stops on the first match, resulting on the entry being hidden.  Note, this means that messages displayed have travelled through ALL of the filters without being matched, this isn't a cost free aspect, so be careful about how many enabled filters you have!

## Extractors
Extractors are the inverse of Filters, log entries must match the extractor to be visible.  This can be very useful if you, for example, define an extractor for a specific logging condition and want to quickly see if and how often it happened.


================================================
FILE: Sentinel/.vscode/launch.json
================================================
{
   // Use IntelliSense to find out which attributes exist for C# debugging
   // Use hover for the description of the existing attributes
   // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
   "version": "0.2.0",
   "configurations": [
        {
            "name": ".NET Core Launch (console)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            // If you have changed target frameworks, make sure to update the program path.
            "program": "${workspaceFolder}/bin/Debug/net5.0/Sentinel.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
            "console": "internalConsole",
            "stopAtEntry": false
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

================================================
FILE: Sentinel/.vscode/tasks.json
================================================
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "command": "dotnet",
            "type": "process",
            "args": [
                "build",
                "${workspaceFolder}/Sentinel.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "publish",
            "command": "dotnet",
            "type": "process",
            "args": [
                "publish",
                "${workspaceFolder}/Sentinel.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "watch",
            "command": "dotnet",
            "type": "process",
            "args": [
                "watch",
                "run",
                "${workspaceFolder}/Sentinel.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        }
    ]
}

================================================
FILE: Sentinel/Classification/Classifier.cs
================================================
namespace Sentinel.Classification
{
    using System.Diagnostics;
    using System.Runtime.Serialization;
    using System.Text.RegularExpressions;

    using Sentinel.Classification.Interfaces;
    using Sentinel.Interfaces;

    using WpfExtras;

    [DataContract]
    public class Classifier : ViewModelBase, IClassifier
    {
        private bool enabled = true;

        private LogEntryFields field;

        private MatchMode mode;

        private string name;

        private string type;

        private string pattern;

        private Regex regex;

        public Classifier()
        {
            PropertyChanged += (sender, e) =>
                {
                    if (e.PropertyName == "Field" || e.PropertyName == "Mode" || e.PropertyName == "Pattern")
                    {
                        if (Mode == MatchMode.RegularExpression && Pattern != null)
                        {
                            regex = new Regex(Pattern);
                        }

                        OnPropertyChanged(nameof(Description));
                    }
                };
        }

        public Classifier(string name, bool enabled, LogEntryFields field, MatchMode mode, string pattern, string type)
        {
            Name = name;
            Enabled = enabled;
            Field = field;
            Mode = mode;
            Pattern = pattern;
            Type = type;
            regex = new Regex(pattern);

            PropertyChanged += (sender, e) =>
                {
                    if (e.PropertyName == "Field" || e.PropertyName == "Mode" || e.PropertyName == "Pattern")
                    {
                        if (Mode == MatchMode.RegularExpression && Pattern != null)
                        {
                            regex = new Regex(Pattern);
                        }

                        OnPropertyChanged(nameof(Description));
                    }
                };
        }

        public string Description
        {
            get
            {
                var modeDescription = "Exact";

                switch (Mode)
                {
                    case MatchMode.RegularExpression:
                        modeDescription = "RegEx";
                        break;
                    case MatchMode.CaseSensitive:
                        modeDescription = "Case sensitive";
                        break;
                    case MatchMode.CaseInsensitive:
                        modeDescription = "Case insensitive";
                        break;
                }

                return $"{modeDescription} match of {Pattern} in the {Field} field";
            }
        }

        public bool Enabled
        {
            get
            {
                return enabled;
            }

            set
            {
                if (enabled != value)
                {
                    enabled = value;
                    OnPropertyChanged(nameof(Enabled));
                }
            }
        }

        public LogEntryFields Field
        {
            get
            {
                return field;
            }

            set
            {
                field = value;
                OnPropertyChanged(nameof(Field));
            }
        }

        public string HighlighterType => "Basic Highlighter";

        public MatchMode Mode
        {
            get
            {
                return mode;
            }

            set
            {
                if (mode != value)
                {
                    mode = value;
                    OnPropertyChanged(nameof(Mode));
                }
            }
        }

        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        public string Pattern
        {
            get
            {
                return pattern;
            }

            set
            {
                if (pattern != value)
                {
                    pattern = value;
                    OnPropertyChanged(nameof(Pattern));
                }
            }
        }

        public string Type
        {
            get
            {
                return type;
            }

            set
            {
                if (type != value)
                {
                    type = value;
                    OnPropertyChanged(nameof(Type));
                }
            }
        }

        public ILogEntry Classify(ILogEntry logEntry)
        {
            Debug.Assert(logEntry != null, "logEntry can not be null.");

            if (IsMatch(logEntry))
            {
                logEntry.MetaData["Classification"] = Type;
                logEntry.Type = Type;
            }

            return logEntry;
        }

        public bool IsMatch(ILogEntry logEntry)
        {
            Debug.Assert(logEntry != null, "logEntry can not be null.");

            if (string.IsNullOrWhiteSpace(Pattern))
            {
                return false;
            }

            string target;

            switch (Field)
            {
                case LogEntryFields.None:
                    target = string.Empty;
                    break;
                case LogEntryFields.Type:
                    target = logEntry.Type;
                    break;
                case LogEntryFields.System:
                    target = logEntry.System;
                    break;
                case LogEntryFields.Classification:
                    target = string.Empty;
                    break;
                case LogEntryFields.Thread:
                    target = logEntry.Thread;
                    break;
                case LogEntryFields.Source:
                    target = logEntry.Source;
                    break;
                case LogEntryFields.Description:
                    target = logEntry.Description;
                    break;
                case LogEntryFields.Host:
                    target = string.Empty;
                    break;
                default:
                    target = string.Empty;
                    break;
            }

            switch (Mode)
            {
                case MatchMode.Exact:
                    return target.Equals(Pattern);
                case MatchMode.CaseSensitive:
                    return target.Contains(Pattern);
                case MatchMode.CaseInsensitive:
                    return target.ToLower().Contains(Pattern.ToLower());
                case MatchMode.RegularExpression:
                    return regex != null && regex.IsMatch(target);
            }

            return false;
        }
    }
}

================================================
FILE: Sentinel/Classification/ClassifyingService.cs
================================================
namespace Sentinel.Classification
{
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Windows.Input;

    using Sentinel.Classification.Gui;
    using Sentinel.Classification.Interfaces;
    using Sentinel.Interfaces;

    using WpfExtras;

    /// <summary>
    /// View Model for classifier collection.  This has been written to operate
    /// as a ServiceLocator provided resource, so there is only one collection
    /// across the whole of the system.
    /// </summary>
    /// <typeparam name="T">The first generic type parameter.</typeparam>
    [DataContract]
    public class ClassifyingService<T> : ViewModelBase, IClassifyingService<T>, IDefaultInitialisation
        where T : class, IClassifier
    {
        private readonly CollectionChangeHelper<T> collectionHelper = new CollectionChangeHelper<T>();

        private readonly IAddClassifyingService addClassifyingService = new AddClassifier();

        private readonly IEditClassifyingService editClassifyingService = new EditClassifier();

        private readonly IRemoveClassifyingService removeClassifyingService = new RemoveClassifier();

        private int selectedIndex = -1;

        /// <summary>
        /// Initializes a new instance of the <see cref="ClassifyingService{T}"/> class.
        /// </summary>
        public ClassifyingService()
        {
            Add = new DelegateCommand(AddClassifier);
            Edit = new DelegateCommand(EditClassifier, e => SelectedIndex != -1);
            Remove = new DelegateCommand(RemoveClassifier, e => SelectedIndex != -1);
            OrderEarlier = new DelegateCommand(MoveItemUp, e => SelectedIndex > 0);
            OrderLater = new DelegateCommand(
                MoveItemDown,
                e => SelectedIndex < (Classifiers.Count - 1) && SelectedIndex != -1);

            Classifiers = new ObservableCollection<T>();

            // Register self as an observer of the collection.
            collectionHelper.ManagerName = "Classifiers";
            collectionHelper.OnPropertyChanged += CustomClassifierPropertyChanged;
            collectionHelper.NameLookup += e => e.Name;
            Classifiers.CollectionChanged += collectionHelper.AttachDetach;
        }

        /// <summary>
        /// Gets the <c>ICommand</c> providing the add-classifier functionality.
        /// </summary>
        public ICommand Add { get; private set; }

        /// <summary>
        /// Gets the <c>ICommand</c> providing the edit-classifier functionality.
        /// </summary>
        public ICommand Edit { get; private set; }

        /// <summary>
        /// Gets or sets the <c>ObservableCollection</c> of items representing the
        /// collection of Classifiers.
        /// </summary>
        public ObservableCollection<T> Classifiers { get; set; }

        /// <summary>
        /// Gets the <c>ICommand</c> providing the functionality to
        /// move the currently selected element to an earlier position
        /// in the ordered list of classifiers.
        /// </summary>
        public ICommand OrderEarlier { get; private set; }

        /// <summary>
        /// Gets the <c>ICommand</c> providing the functionality to
        /// move the currently selected element to a later position
        /// in the ordered list of classifiers.
        /// </summary>
        public ICommand OrderLater { get; private set; }

        /// <summary>
        /// Gets the <c>ICommand</c> providing the functionality to
        /// remove the selected element from the list of classifiers.
        /// </summary>
        public ICommand Remove { get; private set; }

        /// <summary>
        /// Gets or sets the index for the selected item in the list
        /// of classifiers.  The selected index is used for commands
        /// such as <seealso cref="OrderEarlier">OrderEarlier</seealso>,
        /// <seealso cref="OrderLater">OrderLater</seealso>
        /// and <seealso cref="Remove">Remove</seealso>.
        /// </summary>
        public int SelectedIndex
        {
            get => selectedIndex;

            set
            {
                if (value != selectedIndex)
                {
                    selectedIndex = value;
                    OnPropertyChanged(nameof(SelectedIndex));
                    CommandManager.InvalidateRequerySuggested();
                }
            }
        }

        public void Initialise()
        {
            Classifiers.Add(new Classifier("Timing messages", true, LogEntryFields.Description, MatchMode.RegularExpression, @"^\[SimulationTime\] (?<description>[^$]+)$", "TIMING") as T);
            Classifiers.Add(new Classifier("Smp messages", true, LogEntryFields.Description, MatchMode.RegularExpression, "Src:'(?<system>[^']+)', Msg:'(?<description>.*)'$", "TIMING") as T);
            Classifiers.Add(new Classifier("SimSat messages", true, LogEntryFields.Description, MatchMode.RegularExpression, "SIMSAT:'(?<system>[^']+)', Msg:'(?<description>.*)'$", "TIMING") as T);
        }

        public ILogEntry Classify(ILogEntry entry)
        {
            return Classifiers
                .Where(classifier => classifier.Enabled)
                .Aggregate(entry, (current, classifier) => classifier.Classify(current));
        }

        /// <summary>
        /// Add a new classifier to the collection of classifiers.
        /// <para>
        /// Private method that implements the <c>ICommand</c> <seealso cref="Add">
        /// Add</seealso> through a <c>DelegateCommand</c>.
        /// </para>
        /// </summary>
        /// <param name="obj">Delegate object data - unused.</param>
        private void AddClassifier(object obj)
        {
            addClassifyingService.Add();
        }

        /// <summary>
        /// Edit the currently selected classifier (defined by the
        /// <seealso cref="SelectedIndex">SelectedIndex</seealso>
        /// property).
        /// <para>
        /// Private method that implements the <c>ICommand</c> <seealso cref="Edit">
        /// Edit</seealso> through a <c>DelegateCommand</c>.
        /// </para>
        /// </summary>
        /// <param name="obj">Delegate object data - unused.</param>
        private void EditClassifier(object obj)
        {
            var classifier = Classifiers.ElementAt(SelectedIndex);
            if (classifier != null)
            {
                editClassifyingService.Edit(classifier);
            }
        }

        /// <summary>
        /// Move the currently selected classifier (defined by the
        /// <seealso cref="SelectedIndex">SelectedIndex</seealso>
        /// property) to later in the ordered list.
        /// <para>
        /// Private method that implements the <c>ICommand</c> <seealso cref="OrderLater">
        /// OrderLater</seealso> through a <c>DelegateCommand</c>.
        /// </para>
        /// </summary>
        /// <param name="obj">Delegate object data - unused.</param>
        private void MoveItemDown(object obj)
        {
            if (selectedIndex != -1)
            {
                lock (this)
                {
                    Debug.Assert(
                        selectedIndex >= 0,
                        "SelectedIndex must be >= 0.");
                    Debug.Assert(
                        selectedIndex < Classifiers.Count - 1,
                        "SelectedIndex must be within the index range of Items collection");
                    Debug.Assert(
                        Classifiers.Count > 1,
                        "Can not move an item unless there is more than one.");

                    lock (Classifiers)
                    {
                        Classifiers.Swap(selectedIndex, selectedIndex + 1);
                    }
                }
            }
        }

        /// <summary>
        /// Move the currently selected classifier (defined by the
        /// <seealso cref="SelectedIndex">SelectedIndex</seealso>
        /// property) to earlier in the ordered list.
        /// <para>
        /// Private method that implements the <c>ICommand</c> <seealso cref="OrderEarlier">
        /// OrderEarlier</seealso> through a <c>DelegateCommand</c>.
        /// </para>
        /// </summary>
        /// <param name="obj">Delegate object data - unused.</param>
        private void MoveItemUp(object obj)
        {
            if (selectedIndex != -1)
            {
                lock (this)
                {
                    Debug.Assert(selectedIndex >= 0, "SelectedIndex must be valid, e.g. >= 0");
                    Debug.Assert(Classifiers.Count > 1, "Can only move item if more than one.");

                    lock (Classifiers)
                    {
                        Classifiers.Swap(selectedIndex, selectedIndex - 1);
                    }
                }
            }
        }

        /// <summary>
        /// Removes the currently selected classifier (defined by the
        /// <seealso cref="SelectedIndex">SelectedIndex</seealso>
        /// property).
        /// <para>
        /// Private method that implements the <c>ICommand</c> <seealso cref="Remove">
        /// Remove</seealso> through a <c>DelegateCommand</c>.
        /// </para>
        /// </summary>
        /// <param name="obj">Delegate object data - unused.</param>
        private void RemoveClassifier(object obj)
        {
            var classifier = Classifiers.ElementAt(SelectedIndex);
            removeClassifyingService.Remove(classifier);
        }

        private void CustomClassifierPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var classifier = sender as IClassifier;
            if (classifier != null)
            {
                Trace.WriteLine(
                    string.Format(
                        "ClassifyingService saw some activity on {0} (IsEnabled = {1})",
                        classifier.Name,
                        classifier.Enabled));
            }

            OnPropertyChanged(string.Empty);
        }
    }
}

================================================
FILE: Sentinel/Classification/Gui/AddClassifier.cs
================================================
namespace Sentinel.Classification.Gui
{
    using System.Windows;

    using Sentinel.Classification.Interfaces;
    using Sentinel.Services;

    public class AddClassifier : IAddClassifyingService
    {
        public void Add()
        {
            var classifierWindow = new AddEditClassifierWindow();
            using (var data = new AddEditClassifier(classifierWindow, false))
            {
                classifierWindow.DataContext = data;
                classifierWindow.Owner = Application.Current.MainWindow;

                var dialogResult = classifierWindow.ShowDialog();
                if (dialogResult != null && (bool)dialogResult)
                {
                    var classifier = Construct(data);
                    if (classifier != null)
                    {
                        var service = ServiceLocator.Instance.Get<IClassifyingService<IClassifier>>();
                        service?.Classifiers.Add(classifier);
                    }
                }
            }
        }

        private static Classifier Construct(AddEditClassifier data)
        {
            return new Classifier
                       {
                           Name = data.Name,
                           Type = data.Type,
                           Field = data.Field,
                           Mode = data.Mode,
                           Pattern = data.Pattern,
                           Enabled = true,
                       };
        }
    }
}

================================================
FILE: Sentinel/Classification/Gui/AddEditClassifier.cs
================================================
namespace Sentinel.Classification.Gui
{
    using System.Windows;
    using System.Windows.Input;

    using Sentinel.Interfaces;

    using WpfExtras;

    public class AddEditClassifier : ViewModelBase
    {
        private readonly Window window;

        private string name = "Unnamed";

        private string pattern = "pattern";

        private LogEntryFields field;

        private MatchMode mode;

        private string type;

        public AddEditClassifier(Window window, bool editMode)
        {
            this.window = window;
            if (window != null)
            {
                window.Title = $"{(editMode ? "Edit" : "Register")} Classifier";
            }

            Accept = new DelegateCommand(AcceptDialog, Validates);
            Reject = new DelegateCommand(RejectDialog);
        }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Accept { get; private set; }

        public LogEntryFields Field
        {
            get
            {
                return field;
            }

            set
            {
                field = value;
                OnPropertyChanged(nameof(Field));
            }
        }

        public MatchMode Mode
        {
            get
            {
                return mode;
            }

            set
            {
                mode = value;
                OnPropertyChanged(nameof(Mode));
            }
        }

        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        public string Pattern
        {
            get
            {
                return pattern;
            }

            set
            {
                if (value != pattern)
                {
                    pattern = value;
                    OnPropertyChanged(nameof(Pattern));
                }
            }
        }

        public string Type
        {
            get
            {
                return type;
            }

            set
            {
                if (value != type)
                {
                    type = value;
                    OnPropertyChanged(nameof(Type));
                }
            }
        }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Reject { get; private set; }

        private void AcceptDialog(object obj)
        {
            window.DialogResult = true;
            window.Close();
        }

        private void RejectDialog(object obj)
        {
            window.DialogResult = false;
            window.Close();
        }

        private bool Validates(object obj)
        {
            return Name.Length > 0 && Pattern.Length > 0;
        }
    }
}

================================================
FILE: Sentinel/Classification/Gui/AddEditClassifierWindow.xaml
================================================
<Window x:Class="Sentinel.Classification.Gui.AddEditClassifierWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:interfaces="clr-namespace:Sentinel.Interfaces"
        Title="Add / Edit Classifier"
        ResizeMode="NoResize"
        SizeToContent="WidthAndHeight"
        WindowStyle="SingleBorderWindow"
        Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
        WindowStartupLocation="CenterOwner">

    <Window.Resources>

        <ObjectDataProvider x:Key="LogEntryFields"
                            MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="interfaces:LogEntryFields" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

        <ObjectDataProvider x:Key="MatchMode"
                            MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="interfaces:MatchMode" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

    </Window.Resources>

    <DockPanel Height="Auto"
               Margin="5">
        <StackPanel Orientation="Horizontal"
                    DockPanel.Dock="Bottom"
                    Height="36"
                    HorizontalAlignment="Right"
                    Margin="0,10,0,0">
            <Button Content="_OK"
                    Command="{Binding Accept}"
                    Width="80"
                    Margin="0,5"
                    IsDefault="True" />
            <Button Content="_Cancel"
                    Command="{Binding Reject}"
                    Width="80"
                    Margin="5,5,0,5"
                    IsCancel="True" />
        </StackPanel>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Label Content="Classifier name : "
                   Margin="5" />
            <TextBox Grid.Row="0"
                     Grid.Column="1"
                     Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     Margin="5"
                     VerticalContentAlignment="Center" />

            <Label Content="Type to classify : "
                   Margin="5"
                   Grid.Row="1"
                   Grid.Column="0" />
            <TextBox Grid.Column="1"
                     Grid.Row="1"
                     Text="{Binding Type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     Margin="5"
                     VerticalContentAlignment="Center" />

            <Label Content="Field to match against : "
                   Grid.Row="2"
                   Grid.Column="0"
                   Margin="5" />
            <ComboBox Grid.Column="1"
                      Grid.Row="2"
                      SelectedItem="{Binding Field, UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Source={StaticResource LogEntryFields}}"
                      Margin="5"
                      VerticalContentAlignment="Center" />

            <Label Content="Match method : "
                   Margin="5"
                   Grid.Row="3"
                   Grid.Column="0" />
            <ComboBox Grid.Column="1"
                      Grid.Row="3"
                      SelectedItem="{Binding Mode, UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Source={StaticResource MatchMode}}"
                      Margin="5"
                      VerticalContentAlignment="Center" />

            <Label Content="Match string :"
                   Margin="5"
                   Grid.Row="4"
                   Grid.Column="0" />
            <TextBox x:Name="MatchText"
                     Margin="5"
                     MinWidth="205"
                     Grid.Row="4"
                     Grid.Column="1"
                     Text="{Binding Pattern, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     VerticalContentAlignment="Center" />
        </Grid>
    </DockPanel>
</Window>

================================================
FILE: Sentinel/Classification/Gui/AddEditClassifierWindow.xaml.cs
================================================
namespace Sentinel.Classification.Gui
{
    /// <summary>
    /// Interaction logic for AddEditClassifierWindow.xaml.
    /// </summary>
    public partial class AddEditClassifierWindow
    {
        public AddEditClassifierWindow()
        {
            InitializeComponent();
        }
    }
}


================================================
FILE: Sentinel/Classification/Gui/ClassificationsControl.xaml
================================================
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:wpf="clr-namespace:Sentinel.Support.Wpf"
             x:Class="Sentinel.Classification.Gui.ClassificationsControl"
             mc:Ignorable="d">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
            <ColumnDefinition Width="80" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Row="0"
                    Grid.Column="0"
                    Grid.RowSpan="4"
                    Orientation="Vertical"
                    VerticalAlignment="Center">
            <Button Command="{Binding Classifier.OrderEarlier}"
                    Margin="5"
                    Content="Up"/>
            <Button Command="{Binding Classifier.OrderLater}"
                    Margin="5"
                    Content="Down"/>
        </StackPanel>
        <ListView Grid.Row="0"
                  SelectedIndex="{Binding Classifier.SelectedIndex, Mode=OneWayToSource}"
                  Grid.Column="1"
                  Grid.RowSpan="4"
                  MinHeight="200"
                  ItemsSource="{Binding Classifier.Classifiers}"
                  SelectionMode="Single">
            <ListView.View>
                <GridView>
                    <wpf:FixedWidthColumn FixedWidth="28">
                        <wpf:FixedWidthColumn.HeaderTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="True"
                                          IsEnabled="False"
                                          ToolTipService.ShowOnDisabled="True"
                                          ToolTip="Is the classifier enabled?" />
                            </DataTemplate>
                        </wpf:FixedWidthColumn.HeaderTemplate>
                        <wpf:FixedWidthColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Enabled}"
                                          Margin="2,3,0,3" />
                            </DataTemplate>
                        </wpf:FixedWidthColumn.CellTemplate>
                    </wpf:FixedWidthColumn>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="Type"
                                    DisplayMemberBinding="{Binding Type}" />
                    <GridViewColumn Header="Field"
                                    DisplayMemberBinding="{Binding Field}" />
                    <GridViewColumn Header="Mode"
                                    DisplayMemberBinding="{Binding Mode}" />
                    <GridViewColumn Header="Description"
                                    DisplayMemberBinding="{Binding Description}" />
                </GridView>
            </ListView.View>
        </ListView>
        <Button Content="_Add"
                Command="{Binding Classifier.Add}"
                Grid.Row="0"
                Margin="5,0,5,5"
                Grid.Column="2" />
        <Button Content="_Edit"
                Command="{Binding Classifier.Edit}"
                Grid.Row="1"
                Margin="5,0,5,5"
                Grid.Column="2" />
        <Button Content="_Remove"
                Command="{Binding Classifier.Remove}"
                Grid.Row="2"
                Margin="5,0,5,5"
                Grid.Column="2" />
    </Grid>
</UserControl>

================================================
FILE: Sentinel/Classification/Gui/ClassificationsControl.xaml.cs
================================================
namespace Sentinel.Classification.Gui
{
    using System.Windows.Controls;

    using Sentinel.Classification.Interfaces;
    using Sentinel.Services;

    /// <summary>
    /// Interaction logic for ClassificationsControl.xaml.
    /// </summary>
    public partial class ClassificationsControl : UserControl
    {
        public ClassificationsControl()
        {
            InitializeComponent();
            Classifier = ServiceLocator.Instance.Get<IClassifyingService<IClassifier>>();
            DataContext = this;
        }

        // ReSharper disable once MemberCanBePrivate.Global
        // ReSharper disable once UnusedAutoPropertyAccessor.Global
        public IClassifyingService<IClassifier> Classifier { get; private set; }
    }
}

================================================
FILE: Sentinel/Classification/Gui/EditClassifier.cs
================================================
namespace Sentinel.Classification.Gui
{
    using System.Diagnostics;
    using System.Windows;

    using Sentinel.Classification.Interfaces;

    public class EditClassifier : IEditClassifyingService
    {
        public void Edit(IClassifier classifier)
        {
            Debug.Assert(classifier != null, "Extractor must be supplied to allow editing.");

            var window = new AddEditClassifierWindow();
            var data = new AddEditClassifier(window, true);
            window.DataContext = data;
            window.Owner = Application.Current.MainWindow;

            data.Name = classifier.Name;
            data.Field = classifier.Field;
            data.Pattern = classifier.Pattern;
            data.Mode = classifier.Mode;
            data.Type = classifier.Type;

            var dialogResult = window.ShowDialog();

            if (dialogResult != null && (bool)dialogResult)
            {
                classifier.Name = data.Name;
                classifier.Pattern = data.Pattern;
                classifier.Mode = data.Mode;
                classifier.Field = data.Field;
                classifier.Type = data.Type;
            }
        }
    }
}


================================================
FILE: Sentinel/Classification/Gui/RemoveClassifier.cs
================================================
namespace Sentinel.Classification.Gui
{
    using System.Windows;

    using Sentinel.Classification.Interfaces;
    using Sentinel.Services;

    public class RemoveClassifier : IRemoveClassifyingService
    {
        public void Remove(IClassifier classifier)
        {
            var service = ServiceLocator.Instance.Get<IClassifyingService<IClassifier>>();

            if (service != null)
            {
                var prompt =
                    "Are you sure you want to remove the selected classifier?\r\n\r\n" +
                    $"Classifier Name = \"{classifier.Name}\"";

                var result = MessageBox.Show(
                    prompt,
                    "Remove Extractor",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question,
                    MessageBoxResult.No);

                if (result == MessageBoxResult.Yes)
                {
                    service.Classifiers.Remove(classifier);
                }
            }
        }
    }
}

================================================
FILE: Sentinel/Classification/Interfaces/IAddClassifyingService.cs
================================================
namespace Sentinel.Classification.Interfaces
{
    public interface IAddClassifyingService
    {
        void Add();
    }
}

================================================
FILE: Sentinel/Classification/Interfaces/IClassifier.cs
================================================
namespace Sentinel.Classification.Interfaces
{
    using System.Runtime.Serialization;

    using Sentinel.Interfaces;

    public interface IClassifier
    {
        [DataMember]
        string Name { get; set; }

        [DataMember]
        string Type { get; set; }

        [DataMember]
        bool Enabled { get; set; }

        [DataMember]
        string Pattern { get; set; }

        [DataMember]
        string Description { get; }

        [DataMember]
        LogEntryFields Field { get; set; }

        [DataMember]
        MatchMode Mode { get; set; }

        bool IsMatch(ILogEntry entry);

        ILogEntry Classify(ILogEntry entry);
    }
}

================================================
FILE: Sentinel/Classification/Interfaces/IClassifyingService.cs
================================================
namespace Sentinel.Classification.Interfaces
{
    using System.Collections.ObjectModel;
    using System.Runtime.Serialization;
    using System.Windows.Input;

    using Sentinel.Interfaces;

    public interface IClassifyingService<T>
    {
        ICommand Add { get; }

        ICommand Edit { get; }

        [DataMember]
        ObservableCollection<T> Classifiers { get; }

        ICommand OrderEarlier { get; }

        ICommand OrderLater { get; }

        ICommand Remove { get; }

        int SelectedIndex { get; set; }

        ILogEntry Classify(ILogEntry entry);
    }
}

================================================
FILE: Sentinel/Classification/Interfaces/IEditClassifyingService.cs
================================================
namespace Sentinel.Classification.Interfaces
{
    public interface IEditClassifyingService
    {
        void Edit(IClassifier classifier);
    }
}

================================================
FILE: Sentinel/Classification/Interfaces/IRemoveClassifyingService.cs
================================================
namespace Sentinel.Classification.Interfaces
{
    public interface IRemoveClassifyingService
    {
        void Remove(IClassifier classifier);
    }
}

================================================
FILE: Sentinel/Controls/AboutWindow.xaml
================================================
<Window x:Class="Sentinel.Controls.AboutWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="About"
        Height="222"
        Width="450"
        SizeToContent="Height"
        ResizeMode="NoResize"
        WindowStartupLocation="CenterOwner" >

    <Grid x:Name="LayoutRoot" Margin="0,0,0,4">
        <DockPanel Margin="5">
            <StackPanel DockPanel.Dock="Top">
                <TextBlock Margin="5,5,0,0" FontSize="18" FontWeight="Bold">
                    <Run Name="AssemblyNameLabel" Text="Assembly Name"/>
                </TextBlock>
                <TextBlock Margin="5,0,0,10" FontSize="14" TextWrapping="WrapWithOverflow">                    
                    <Run Name="DescriptionLabel" Text="Description" />
                </TextBlock>
                <TextBlock Margin="5" FontSize="14" TextWrapping="WrapWithOverflow">
                    <Run Text="Version - " />
                    <Run Name="VersionNumberLabel" Text="" />
                </TextBlock>
                <TextBlock Margin="5"
                           FontSize="14"
                           TextWrapping="WrapWithOverflow">
                    <Run Text="Created By - " />
                    <Run Name="CreatorInfoLabel"
                         Text="Ray Hayes" />
                </TextBlock>
                <TextBlock Margin="5" FontSize="14" TextWrapping="WrapWithOverflow">
                    <Run Text="Contributors - " />
                    <Run Name="DeveloperInfoLabel" Text="Ishmal Lewis" />
                </TextBlock>
                <TextBlock Margin="5" FontSize="14" TextWrapping="WrapWithOverflow">
                    <Run Name="CopyrightInfoLabel" Text="Copyright info" />
                </TextBlock>
            </StackPanel>
        </DockPanel>
    </Grid>
</Window>


================================================
FILE: Sentinel/Controls/AboutWindow.xaml.cs
================================================
namespace Sentinel.Controls
{
    using System.Diagnostics;
    using System.IO;
    using System.Reflection;
    using System.Windows;

    /// <summary>
    /// Interaction logic for AboutWindow.xaml.
    /// </summary>
    public partial class AboutWindow
    {
        public AboutWindow(Window parent)
        {
            InitializeComponent();

            Owner = parent;

            try
            {
                var assembly = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);
                AssemblyNameLabel.Text = assembly.ProductName;
                VersionNumberLabel.Text = assembly.ProductVersion;
                DescriptionLabel.Text = assembly.Comments;
                DeveloperInfoLabel.Text = assembly.CompanyName;
                CopyrightInfoLabel.Text = assembly.LegalCopyright;
            }
            catch (FileNotFoundException)
            {
                // Can be thrown by the GetVersionInfo call
            }
        }
    }
}


================================================
FILE: Sentinel/Controls/ImageTypesControl.xaml
================================================
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
			 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
			 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
			 mc:Ignorable="d"
			 x:Class="Sentinel.Controls.ImageTypesControl"
			 x:Name="UserControl"
			 d:DesignWidth="445.9"
			 d:DesignHeight="80.88">

	<UserControl.Resources>
		<Style TargetType="{x:Type ListView}"
			   BasedOn="{StaticResource {x:Type ListBox}}">
			<Setter Property="BorderBrush"
					Value="Black" />
			<Setter Property="BorderThickness"
					Value="0.5" />
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate>
						<Border Name="bd"
								BorderBrush="{TemplateBinding BorderBrush}"
								BorderThickness="{TemplateBinding BorderThickness}"
								Background="{TemplateBinding Background}"
								Margin="{TemplateBinding Margin}">
							<ScrollViewer Margin="{TemplateBinding Padding}">
								<WrapPanel ItemWidth="100"
										   IsItemsHost="True"
										   MinWidth="100"
										   Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}">
								</WrapPanel>
							</ScrollViewer>
						</Border>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>

		<Style TargetType='{x:Type ListViewItem}'
			   BasedOn='{StaticResource {x:Type ListBoxItem}}'>
			<Setter Property='Padding'
					Value='3' />
			<Setter Property='Margin'
					Value='5' />
			<Setter Property='HorizontalContentAlignment'
					Value='Center' />
			<Setter Property="ContentTemplate">
				<Setter.Value>
					<DataTemplate>
						<StackPanel Orientation="Vertical">
							<Image Margin="3"
								   Width="16"
								   Height="16"
								   VerticalAlignment="Center"
								   HorizontalAlignment="Center"
								   Source="{Binding Image}" />
							<Label Content="{Binding Name}"
								   VerticalAlignment="Center"
								   HorizontalAlignment="Center" />
							<Label Content="{Binding Quality}"
								   FontSize="10"
								   VerticalAlignment="Center"
								   HorizontalAlignment="Center" />
						</StackPanel>
					</DataTemplate>
				</Setter.Value>
			</Setter>
		</Style>
	</UserControl.Resources>

	<Grid x:Name="LayoutRoot">
		<Grid d:LayoutOverrides="Height">
			<Grid.ColumnDefinitions>
				<ColumnDefinition />
				<ColumnDefinition Width="80" />
			</Grid.ColumnDefinitions>
			<Grid.RowDefinitions>
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
				<RowDefinition Height="Auto" />
				<RowDefinition Height="*" />
			</Grid.RowDefinitions>

			<ListView Grid.RowSpan="4"
					  ItemsSource="{Binding Images.ImageMappings}"
					  SelectedIndex="{Binding Images.SelectedIndex}"					  
					  SelectionMode="Single">
			</ListView>

			<Button Grid.Column="1"
					Content="_Add"
					Command="{Binding Images.Add}"
					Margin="5,0,5,5" />
			<Button Grid.Column="1"
					Command="{Binding Images.Edit}"
					Grid.Row="1"
					Content="_Edit"
					Margin="5,0,5,5" />
			<Button Grid.Column="1"
					Grid.Row="2"
					Command="{Binding Images.Remove}"
					Content="_Remove"
					Margin="5,0,5,5" />
		</Grid>
	</Grid>
</UserControl>

================================================
FILE: Sentinel/Controls/ImageTypesControl.xaml.cs
================================================
namespace Sentinel.Controls
{
    using System.Windows.Controls;

    using Sentinel.Images.Interfaces;
    using Sentinel.Services;

    /// <summary>
    /// Interaction logic for ImageTypesControl.xaml.
    /// </summary>
    public partial class ImageTypesControl : UserControl
    {
        public ImageTypesControl()
        {
            InitializeComponent();
            Images = ServiceLocator.Instance.Get<ITypeImageService>();
            DataContext = this;
        }

        public ITypeImageService Images { get; private set; }
    }
}

================================================
FILE: Sentinel/Controls/IntegerTextBox.cs
================================================
namespace Sentinel.Controls
{
    using System.Linq;
    using System.Windows.Controls;
    using System.Windows.Input;

    public class IntegerTextBox : TextBox
    {
        protected override void OnPreviewTextInput(TextCompositionEventArgs e)
        {
            e.Handled = !e.Text.All(char.IsDigit);

            base.OnPreviewTextInput(e);
        }
    }
}

================================================
FILE: Sentinel/Controls/LogActivityControl.xaml
================================================
<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:converters="clr-namespace:Sentinel.Support.Converters"
    xmlns:support="clr-namespace:Sentinel.Support"
    mc:Ignorable="d"
    x:Class="Sentinel.Controls.LogActivityControl"
    x:Name="UserControl"
    d:DesignWidth="376.654"
    d:DesignHeight="50">

    <UserControl.Resources>
        <Style
            x:Key="ActivityRowStyle"
            TargetType="{x:Type ListViewItem}">
            <Style.Triggers>
                <DataTrigger
                    Binding="{Binding Preferences.CurrentThemeName, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"
                    Value="Aero">
                    <!-- Get rid of the space between rows -->
                    <Setter
                        Property="Margin"
                        Value="0,-1,0,-1" />
                </DataTrigger>

                <!--<DataTrigger Binding="{Binding Highlight.Active, RelativeSource={RelativeSource AncestorType={x:Type Controls:LogActivityControl}, Mode=FindAncestor}}"
                             Value="true">
                    <Setter Property="Background"
                            Value="{Binding LastActivityType, Converter={StaticResource typeToBackgroundConverter}}" />
                    <Setter Property="Foreground"
                            Value="{Binding LastActivityType, Converter={StaticResource typeToForegroundConverter}}" />
                </DataTrigger>-->

            </Style.Triggers>
        </Style>

        <converters:TimeSinceDateTimeConverter
            x:Key="TimeSinceDateTimeConverter" />

    </UserControl.Resources>

    <Grid
        x:Name="LayoutRoot">

        <ListView
            x:Name="Updates"
            support:GridViewSort.AutoSort="True"
            support:GridViewSort.SortGlyphAscending="/Resources/Glyphs/SortUpArrow.png"
            support:GridViewSort.SortGlyphDescending="/Resources/Glyphs/SortDownArrow.png"
            ItemContainerStyle="{StaticResource ActivityRowStyle}"
            ItemsSource="{Binding Activity.Details}">
            <ListView.ContextMenu>
                <ContextMenu
                    x:Name="ActivityLbContextMenu">
                    <MenuItem
                        Header="Clear"
                        Command="{Binding ClearActivity}" />
                </ContextMenu>
            </ListView.ContextMenu>
            <ListView.View>
                <GridView
                    AllowsColumnReorder="False">
                    <GridViewColumn
                        Header="System"
                        DisplayMemberBinding="{Binding System}" />
                    <GridViewColumn
                        Header="Classification"
                        DisplayMemberBinding="{Binding Classification}" />
                    <GridViewColumn
                        Header="Since last seen"
                        support:GridViewSort.PropertyName="LastActivity"
                        DisplayMemberBinding="{Binding LastActivity, Converter={StaticResource TimeSinceDateTimeConverter}}" />
                    <GridViewColumn
                        Header="Since Error"
                        support:GridViewSort.PropertyName="LastError"
                        DisplayMemberBinding="{Binding LastError, Converter={StaticResource TimeSinceDateTimeConverter}}" />
                    <GridViewColumn
                        Header="Since Warning"
                        support:GridViewSort.PropertyName="LastWarning"
                        DisplayMemberBinding="{Binding LastWarning, Converter={StaticResource TimeSinceDateTimeConverter}}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</UserControl>

================================================
FILE: Sentinel/Controls/LogActivityControl.xaml.cs
================================================
namespace Sentinel.Controls
{
    using Sentinel.Highlighters.Interfaces;
    using Sentinel.Services;

    /// <summary>
    /// Interaction logic for LogActivityControl.xaml.
    /// </summary>
    public partial class LogActivityControl
    {
        public LogActivityControl()
        {
            InitializeComponent();
            Highlight = ServiceLocator.Instance.Get<IHighlightingService<IHighlighter>>();
        }

        public IHighlightingService<IHighlighter> Highlight { get; private set; }
    }
}

================================================
FILE: Sentinel/Controls/MainWindow.xaml
================================================
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:sentinelInterfaces="clr-namespace:Sentinel.Interfaces"
    xmlns:converters="clr-namespace:Sentinel.Support.Converters"
    x:Class="Sentinel.Controls.MainWindow"
    Title="Sentinel"
    Height="600"
    Width="1024"
    mc:Ignorable="d"
    OverridesDefaultStyle="False"
    Loaded="OnLoaded"
    Closing="OnClosed"
    ResizeMode="CanResizeWithGrip">

    <Window.Resources>
        <Style
            TargetType="{x:Type Image}">
            <Setter
                Property="Width"
                Value="16" />
            <Setter
                Property="Height"
                Value="16" />
            <Setter
                Property="RenderOptions.BitmapScalingMode"
                Value="NearestNeighbor" />

            <Style.Triggers>
                <!-- If the parent is a button, then disable image (visually) when parent is not enabled -->
                <DataTrigger
                    Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorLevel=1, AncestorType={x:Type Button}}}"
                    Value="False">
                    <Setter
                        Property="Opacity"
                        Value="0.50" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        
        <ObjectDataProvider x:Key="LogEntryField"
                            MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="sentinelInterfaces:LogEntryFields" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <ObjectDataProvider x:Key="MatchMode"
                            MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="sentinelInterfaces:MatchMode" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

        <converters:TypeToLargeImageConverter
            x:Key="TypeToLargeImage" />
        <converters:TypeToMediumImageConverter
            x:Key="TypeToMediumImage" />
        <converters:TypeToSmallImageConverter
            x:Key="TypeToSmallImage" />
        <converters:LongPathToShortPathConverter
            x:Key="LongPathToShortPath" />
    </Window.Resources>

    <DockPanel>

        <Ribbon
            SelectedIndex="0"
            DockPanel.Dock="Top"
            ShowQuickAccessToolBarOnTop="False" Margin="0,-22,0,0">

            <Ribbon.ApplicationMenu>
                <RibbonApplicationMenu>

                    <RibbonApplicationMenu.SmallImageSource>
                        <DrawingImage>
                            <DrawingImage.Drawing>
                                <GeometryDrawing>
                                    <GeometryDrawing.Geometry>
                                        <RectangleGeometry Rect="0,0,20,20"></RectangleGeometry>
                                    </GeometryDrawing.Geometry>
                                    <GeometryDrawing.Brush>
                                        <VisualBrush Stretch="Uniform">
                                            <VisualBrush.Visual>
                                                <TextBlock Text="File" FontSize="16" Foreground="White" />
                                            </VisualBrush.Visual>
                                        </VisualBrush>
                                    </GeometryDrawing.Brush>
                                </GeometryDrawing>
                            </DrawingImage.Drawing>
                        </DrawingImage>
                    </RibbonApplicationMenu.SmallImageSource>

                    <RibbonApplicationMenuItem
                        Header="New Session"
                        ImageSource="/Resources/Large/Add.PNG"
                        KeyTip="N"
                        Command="{Binding NewSession}"/>

                    <RibbonApplicationMenuItem
                        Header="Load Session"
                        ImageSource="/Resources/Large/Open.PNG"
                        KeyTip="L"
                        Command="{Binding LoadSession}"/>

                    <RibbonApplicationMenuItem
                        Header="Save Session"
                        ImageSource="/Resources/Large/Save.PNG"
                        KeyTip="S"
                        Command="{Binding SaveSession}"/>                    
                    
                    <RibbonApplicationMenuItem
                        Header="Export Logs"
                        ImageSource="/Resources/Large/Export.PNG"
                        Command="{Binding ExportLogs}"
                        KeyTip="E" />
                    
                    <RibbonApplicationMenuItem
                        Header="Preferences"
                        Command="{Binding ShowPreferences}"
                        CommandParameter="0"
                        ImageSource="/Resources/Large/Settings.PNG"
                        ToolTip="Show Preferences Dialog" />

                    <RibbonApplicationMenuItem
                        Header="About"
                        ImageSource="/Resources/Large/Info.PNG"
                        KeyTip="A"
                        Command="{Binding About}"/>

                    <RibbonApplicationMenu.FooterPaneContent>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition
                                    Width="Auto" />
                                <ColumnDefinition
                                    Width="*" />
                                <ColumnDefinition
                                    Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <RibbonButton
                                SmallImageSource="/Resources/Small/Exit.PNG"
                                Label="Exit"
                                HorizontalAlignment="Right"
                                Command="{Binding Exit}"
                                Grid.Column="2" />
                        </Grid>
                    </RibbonApplicationMenu.FooterPaneContent>

                    <RibbonApplicationMenu.AuxiliaryPaneContent>
                        <StackPanel>
                            <TextBlock HorizontalAlignment="Center" Text="Recently Opened Sessions" FontSize="16" Opacity="0.40" />
                            <RibbonGroup ItemsSource="{Binding RecentFiles}">
                                <RibbonGroup.ItemTemplate>
                                    <DataTemplate>
                                        <RibbonButton Label="{Binding ., Converter={StaticResource LongPathToShortPath}}"
                                                      Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.LoadSession}"
                                                      CommandParameter="{Binding .}"
                                                      HorizontalContentAlignment="Left"
                                                      VerticalContentAlignment="Bottom"
                                                  ToolTipTitle="{Binding .}"
                                                  ToolTipDescription="Click to open this session." />                                        
                                    </DataTemplate>
                                </RibbonGroup.ItemTemplate>                                
                            </RibbonGroup>                            
                        </StackPanel>
                    </RibbonApplicationMenu.AuxiliaryPaneContent>
                    
                </RibbonApplicationMenu>
            </Ribbon.ApplicationMenu>

            <RibbonTab Header="Home">
                <RibbonGroup Header="General">
                    <RibbonButton Label="Add Provider"
                                    ToolTip="Add a new log viewer"
                                    SmallImageSource="/Resources/Small/Add.png"
                                    Command="{Binding Add}" />
                    
                    <RibbonButton ToolTip="Export the logs currently in the viewer to a file"
                                          Command="{Binding ExportLogs}"
                                          SmallImageSource="/Resources/Small/Export.png"
                                          Label="Export Logs" />
                    
                    <RibbonButton ToolTip="Show the Preferences dialog"
                                          Command="{Binding ShowPreferences}"
                                          CommandParameter="0"
                                          SmallImageSource="/Resources/Small/Settings.png"
                                          Label="Preferences" />
                </RibbonGroup>

                <!-- Standard highlighters -->
                <RibbonGroup Name="StandardHighlightersRibbonGroup" Header="Highlighters"> <!--ItemsSource="{Binding Source={StaticResource standardHighlighters}}"-->                               
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton Label="{Binding Name}"
                                                  IsChecked="{Binding Enabled}"
                                                  HorizontalContentAlignment="Center"
                                                  VerticalContentAlignment="Bottom"
                                                  SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                                  LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                                  ToolTipTitle="{Binding Name, StringFormat=Highlighter for {0}}"
                                                  ToolTipDescription="{Binding Description}"
                                                  ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                                  ToolTipFooterTitle="Using Highlighters"
                                                  ToolTipFooterDescription="Note, when a highlighter is enabled, matching messages are highlighted."
                                                  ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
                <RibbonGroup Name="StandardFiltersRibbonGroup" Header="Filters"><!--ItemsSource="{Binding Source={StaticResource standardFilters}}"-->
                               
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton Label="{Binding Name}"
                                                  IsChecked="{Binding Enabled}"
                                                  HorizontalContentAlignment="Center"
                                                  VerticalContentAlignment="Bottom"
                                                  SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                                  LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                                  ToolTipTitle="{Binding Name, StringFormat=Filter for {0}}"
                                                  ToolTipDescription="{Binding Description}"
                                                  ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                                  ToolTipFooterTitle="Using Filters"
                                                  ToolTipFooterDescription="Note, when a filter is enabled, matching messages are omitted."
                                                  ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
                <RibbonGroup Header="Search" IsEnabled="True">
                    <StackPanel>
                        <RibbonTextBox Name="SearchRibbonTextBox" TextBoxWidth="200" />
                        
                        <ComboBox Name="SearchTargetComboBox" HorizontalAlignment="Left" Margin="5,0,0,0" MinWidth="100" IsEditable="True" IsReadOnly="True" ItemsSource="{Binding Source={StaticResource LogEntryField}}" />

                        <StackPanel Orientation="Horizontal">

                            <RibbonToggleButton x:Name="HighlightToggleButton" Margin="5,0,0,0" Label="Highlight"
                                              HorizontalAlignment="Left"                                               
                                              VerticalContentAlignment="Center" Checked="SearchToggleButtonChecked"/>
                            <RibbonToggleButton x:Name="FilterToggleButton" Margin="20,0,0,0" Label="Filter"
                                              HorizontalAlignment="Left"                                              
                                              VerticalContentAlignment="Center" Checked="SearchToggleButtonChecked" />
                            <RibbonToggleButton x:Name="ExtractToggleButton" Margin="20,0,0,0" Label="Extract"
                                              HorizontalAlignment="Left"                                              
                                              VerticalContentAlignment="Center" Checked="SearchToggleButtonChecked" />                            
                        </StackPanel>
                    </StackPanel>
                    
                    <ListBox Name="SearchModeListBox" Margin="2,2,2,0" ItemsSource="{Binding Source={StaticResource MatchMode}}" />
                </RibbonGroup>
                <RibbonGroup Header="Show Columns">
                    <RibbonToggleButton Name="ExceptionRibbonToggleButton" Label="Exception"                                          
                                          HorizontalContentAlignment="Center"
                                          VerticalContentAlignment="Bottom"
                                          SmallImageSource="../Resources/Small/Exception.png"
                                          LargeImageSource="../Resources/Large/Exception.png"
                                          ToolTipTitle="Show Exceptions"
                                          ToolTipDescription="Shows the Exception column when enabled."
                                          ToolTipImageSource="../Resources/Small/Exception.png" />
                    <RibbonToggleButton Name="ThreadRibbonToggleButton" Label="Thread"
                                          HorizontalContentAlignment="Center"
                                          VerticalContentAlignment="Bottom"
                                          SmallImageSource="../Resources/Small/Thread.png"
                                          LargeImageSource="../Resources/Large/Thread.png"
                                          ToolTipTitle="Show Threads"
                                          ToolTipDescription="Shows the Thread column when enabled."
                                          ToolTipImageSource="../Resources/Small/Thread.png" />
                    <RibbonToggleButton Name="SourceHostRibbonToggleButton"
                                        Label="Source Host"
                                        HorizontalContentAlignment="Center"
                                        VerticalContentAlignment="Bottom"
                                        SmallImageSource="../Resources/Small/Network.png"
                                        LargeImageSource="../Resources/Large/Network.png"
                                        ToolTipTitle="Show source machine name"
                                        ToolTipDescription="Shows the host name of the machine originating the message."
                                        ToolTipImageSource="../Resources/Medium/Network.png" />
                    <RibbonToggleButton Name="DebugSourceRibbonToggleButton"
                                        Label="Debug Sources"
                                        HorizontalContentAlignment="Center"
                                        VerticalContentAlignment="Bottom"
                                        SmallImageSource="../Resources/Small/DebugSource.png"
                                        LargeImageSource="../Resources/Large/DebugSource.png"
                                        ToolTipTitle="Show source code debug information"
                                        ToolTipDescription="Shows the debugging columns when enabled."
                                        ToolTipImageSource="../Resources/Small/DebugSource.png" />
                    <RibbonToggleButton Name="ContextRibbonToggleButton"
                                        Label="Context"
                                        HorizontalContentAlignment="Center"
                                        VerticalContentAlignment="Bottom"
                                        SmallImageSource="../Resources/Small/Context.png"
                                        LargeImageSource="../Resources/Large/Context.png"
                                        ToolTipTitle="Show context (hardcoded to property UnitTest)"
                                        ToolTipDescription="Shows the debugging columns when enabled."
                                        ToolTipImageSource="../Resources/Small/Context.png" />
                </RibbonGroup>
            </RibbonTab>
            <RibbonTab Header="Classifiers">
                <RibbonGroup Header="Options">
                    <RibbonButton Label="Add New Classifier"
                                    LargeImageSource="/Resources/Large/Add.png"
                                    Command="{Binding ShowPreferences}"
                                    CommandParameter="1" />
                </RibbonGroup>
                <RibbonGroup Name="CustomClassifiersRibbonGroupOnTab" Header="Custom Classifiers">                    
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton Label="{Binding Name}"
                                                  IsChecked="{Binding Enabled}"
                                                  HorizontalContentAlignment="Center"
                                                  VerticalContentAlignment="Bottom"
                                                  SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                                  LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                                  ToolTipTitle="{Binding Name, StringFormat=Classifier for {0}}"
                                                  ToolTipDescription="{Binding Description}"
                                                  ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                                  ToolTipFooterTitle="Using Classifiers"
                                                  ToolTipFooterDescription="Note, when a classifier is enabled, incoming messages will have their type modified to the type of the last applicable classifier.  This is a custom classifier."
                                                  ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
            </RibbonTab>

            <RibbonTab
                Header="Highlighters">
                <RibbonGroup
                    Header="Options">
                    <RibbonButton
                        Label="Add New Highlighter"
                        Command="{Binding ShowPreferences}"
                        CommandParameter="2"
                        LargeImageSource="/Resources/Large/Add.png" />
                </RibbonGroup>
                <RibbonGroup
                    Name="StandardHighlighterRibbonGroupOnTab" Header="Standard Highlighters">
                    <!--ItemsSource="{Binding Source={StaticResource standardHighlighters}}"
                    Visibility="{Binding Source={StaticResource standardHighlighters}, Path=Count, Converter={StaticResource collapseIfZero}}">-->                    
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton
                                Label="{Binding Name}"
                                IsChecked="{Binding Enabled}"
                                HorizontalContentAlignment="Center"
                                VerticalContentAlignment="Bottom"
                                SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                ToolTipTitle="{Binding Name, StringFormat=Highlighter for {0}}"
                                ToolTipDescription="{Binding Description}"
                                ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                ToolTipFooterTitle="Using Highlighters"
                                ToolTipFooterDescription="Note, when a highlighter is enabled, matching messages are highlighted.  This is a standard highlighter."
                                ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
                <RibbonGroup Name="CustomHighlighterRibbonGroupOnTab" Header="Custom Highlighters">
                    <!--ItemsSource="{Binding Source={StaticResource customHighlighters}}"
                    Visibility="{Binding Source={StaticResource customHighlighters}, Path=Count, Converter={StaticResource collapseIfZero}}">-->                    
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton
                                Label="{Binding Name}"
                                IsChecked="{Binding Enabled}"
                                HorizontalContentAlignment="Center"
                                VerticalContentAlignment="Bottom"
                                SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                ToolTipTitle="{Binding Name, StringFormat=Highlighter for {0}}"
                                ToolTipDescription="{Binding Description}"
                                ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                ToolTipFooterTitle="Using Highlighters"
                                ToolTipFooterDescription="Note, when a highlighter is enabled, matching messages are highlighted.  This is a custom highlighter."
                                ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
            </RibbonTab>
            <RibbonTab Header="Filters">
                <RibbonGroup Header="Options">
                    <RibbonButton Label="Add New Filter"
                                  Command="{Binding ShowPreferences}"
                                    CommandParameter="3"
                                    LargeImageSource="/Resources/Large/Add.png" />
                </RibbonGroup>
                <RibbonGroup Name="StandardFiltersRibbonGroupOnTab" Header="Standard Filters">
                    <!--ItemsSource="{Binding Source={StaticResource standardFilters}}"
                    Visibility="{Binding Source={StaticResource standardFilters}, Path=Count, Converter={StaticResource collapseIfZero}}"-->
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton Label="{Binding Name}"
                                                  IsChecked="{Binding Enabled}"
                                                  HorizontalContentAlignment="Center"
                                                  VerticalContentAlignment="Bottom"
                                                  SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                                  LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                                  ToolTipTitle="{Binding Name, StringFormat=Filter for {0}}"
                                                  ToolTipDescription="{Binding Description}"
                                                  ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                                  ToolTipFooterTitle="Using Filters"
                                                  ToolTipFooterDescription="Note, when a filter is enabled, matching messages are omitted.  This is a standard filter."
                                                  ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
                <RibbonGroup
                    Name="CustomFiltersRibbonGroupOnTab" Header="Custom Filters">
                    <!--ItemsSource="{Binding Source={StaticResource customFilters}}"
                        Visibility="{Binding Source={StaticResource customFilters}, Path=Count, Converter={StaticResource collapseIfZero}}"-->                               
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton Label="{Binding Name}"
                                                  IsChecked="{Binding Enabled}"
                                                  HorizontalContentAlignment="Center"
                                                  VerticalContentAlignment="Bottom"
                                                  SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                                  LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                                  ToolTipTitle="{Binding Name, StringFormat=Filter for {0}}"
                                                  ToolTipDescription="{Binding Description}"
                                                  ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                                  ToolTipFooterTitle="Using Filters"
                                                  ToolTipFooterDescription="Note, when a filter is enabled, matching messages are omitted.  This is a custom filter."
                                                  ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
            </RibbonTab>
            <RibbonTab Header="Extractors">
                <RibbonGroup Header="Options">
                    <RibbonButton Label="Add New Extractor"
                                    LargeImageSource="/Resources/Large/Add.png"
                                    Command="{Binding ShowPreferences}"
                                    CommandParameter="4" />
                </RibbonGroup>
                <RibbonGroup Name="CustomExtractorsRibbonGroupOnTab" Header="Custom Extractors">
                    <!--ItemsSource="{Binding Source={StaticResource customExtractors}}"-->
                    <RibbonGroup.ItemTemplate>
                        <DataTemplate>
                            <RibbonToggleButton Label="{Binding Name}"
                                                  IsChecked="{Binding Enabled}"
                                                  HorizontalContentAlignment="Center"
                                                  VerticalContentAlignment="Bottom"
                                                  SmallImageSource="{Binding Name, Converter={StaticResource TypeToSmallImage}}"
                                                  LargeImageSource="{Binding Name, Converter={StaticResource TypeToMediumImage}}"
                                                  ToolTipTitle="{Binding Name, StringFormat=Extractor for {0}}"
                                                  ToolTipDescription="{Binding Description}"
                                                  ToolTipImageSource="{Binding Name, Converter={StaticResource TypeToLargeImage}}"
                                                  ToolTipFooterTitle="Using Extractors"
                                                  ToolTipFooterDescription="Note, when an extractor is enabled, only matching messages are shown.  This is a custom extractor."
                                                  ToolTipFooterImageSource="/Resources/Small/Info.png">
                            </RibbonToggleButton>
                        </DataTemplate>
                    </RibbonGroup.ItemTemplate>
                </RibbonGroup>
            </RibbonTab>            
        </Ribbon>

        <DockPanel>
            <TabControl x:Name="TabControl"
                        Grid.Row="1">
            </TabControl>
        </DockPanel>
    </DockPanel>
</Window>

================================================
FILE: Sentinel/Controls/MainWindow.xaml.cs
================================================
namespace Sentinel.Controls
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Controls.Ribbon;
    using System.Windows.Data;
    using System.Windows.Input;
    using CommandLine;
    using log4net;
    using Microsoft.Win32;
    using Sentinel.Classification.Interfaces;
    using Sentinel.Extractors.Interfaces;
    using Sentinel.Filters.Interfaces;
    using Sentinel.Highlighters.Interfaces;
    using Sentinel.Interfaces;
    using Sentinel.Interfaces.CodeContracts;
    using Sentinel.Log4Net;
    using Sentinel.Logs.Interfaces;
    using Sentinel.NLog;
    using Sentinel.Providers.Interfaces;
    using Sentinel.Services;
    using Sentinel.Services.Interfaces;
    using Sentinel.StartUp;
    using Sentinel.Support;
    using Sentinel.Views.Interfaces;
    using WpfExtras;
    using WpfExtras.Converters;

    /// <summary>
    /// Interaction logic for MainWindow.xaml.
    /// </summary>
    public partial class MainWindow
    {
        private static readonly ILog Log = log4net.LogManager.GetLogger(typeof(MainWindow));

        private readonly string persistingFilename;

        private readonly string persistingRecentFileName;

        private List<string> recentFilePathList;

        private PreferencesWindow preferencesWindow;

        private int preferencesWindowTabSelected;

        public MainWindow()
        {
            InitializeComponent();
            var savingDirectory = ServiceLocator.Instance.SaveLocation;
            persistingFilename = Path.Combine(savingDirectory, "MainWindow");
            persistingRecentFileName = Path.Combine(savingDirectory, "RecentFiles");
            var fileName = Path.ChangeExtension(persistingFilename, ".json");

            var settings = PersistingSettings.Load(fileName);

            // Restore persisted window placement if provided
            if (settings?.WindowPlacementInfo != null)
            {
                RestoreWindowPosition(settings.WindowPlacementInfo);
            }

            if (settings?.UserPreferences != null)
            {
                // TODO: is this already set?
                Preferences = settings.UserPreferences;
            }

            // Get recently opened files
            GetRecentlyOpenedFiles();
        }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Add { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand About { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand ShowPreferences { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand ExportLogs { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Exit { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand NewSession { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand SaveSession { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand LoadSession { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public IUserPreferences Preferences { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public IViewManager ViewManager { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public IFilteringService<IFilter> Filters => ServiceLocator.Instance.Get<IFilteringService<IFilter>>();

        // ReSharper disable once MemberCanBePrivate.Global
        public IHighlightingService<IHighlighter> Highlighters
            => ServiceLocator.Instance.Get<IHighlightingService<IHighlighter>>();

        // ReSharper disable once MemberCanBePrivate.Global
        public IClassifyingService<IClassifier> ClassifyingService
            => ServiceLocator.Instance.Get<IClassifyingService<IClassifier>>();

        // ReSharper disable once MemberCanBePrivate.Global
        public IExtractingService<IExtractor> Extractors
            => ServiceLocator.Instance.Get<IExtractingService<IExtractor>>();

        // ReSharper disable once MemberCanBePrivate.Global
        public ISearchHighlighter Search => ServiceLocator.Instance.Get<ISearchHighlighter>();

        // ReSharper disable once MemberCanBePrivate.Global
        public ISearchFilter SearchFilter => ServiceLocator.Instance.Get<ISearchFilter>();

        // ReSharper disable once MemberCanBePrivate.Global
        public ISearchExtractor SearchExtractor => ServiceLocator.Instance.Get<ISearchExtractor>();

        // ReSharper disable once MemberCanBePrivate.Global
        public ObservableCollection<string> RecentFiles { get; private set; }

        private static WindowPlacementInfo ValidateScreenPosition(WindowPlacementInfo wp)
        {
            if (wp == null)
            {
                return null;
            }

            try
            {
                var virtualScreen = new Rect(
                    SystemParameters.VirtualScreenLeft,
                    SystemParameters.VirtualScreenTop,
                    SystemParameters.VirtualScreenWidth,
                    SystemParameters.VirtualScreenHeight);
                var window = new Rect(wp.Left, wp.Top, wp.Width, wp.Height);
                return virtualScreen.IntersectsWith(window) ? wp : null;
            }
            catch (Exception e)
            {
                Log.Error("Unable to calculate rectangle or perform intersection with window", e);
            }

            return null;
        }

        private void ShowPreferencesAction(object obj)
        {
            preferencesWindowTabSelected = Convert.ToInt32(obj);
            Preferences.Show = true;
        }

        private void ExportLogsAction(object obj)
        {
            // Get Log
            var tab = (TabItem)TabControl.SelectedItem;
            var frame = (IWindowFrame)tab.Content;
            var restartLogging = false;

            // Notify user that log messages will be paused during this operation
            if (frame.Log.Enabled)
            {
                var messageBoxResult =
                    MessageBox.Show(
                        "The log viewer must be paused momentarily for this operation to continue. Is it OK to pause logging?",
                        "Sentinel",
                        MessageBoxButton.YesNo,
                        MessageBoxImage.Warning);

                if (messageBoxResult == MessageBoxResult.Yes)
                {
                    frame.Log.Enabled = false;
                    restartLogging = true;
                }
                else
                {
                    return;
                }
            }

            // Open a save file dialog
            var savefile = new SaveFileDialog
            {
                FileName = frame.Log.Name,
                DefaultExt = ".log",
                Filter = "Log documents (.log)|*.log|Text documents (.txt)|*.txt",
                FilterIndex = 0,
            };

            if (savefile.ShowDialog(this) == true)
            {
                var logFileExporter = ServiceLocator.Instance.Get<ILogFileExporter>();
                logFileExporter.SaveLogViewerToFile(frame, savefile.FileName);
            }

            frame.Log.Enabled = restartLogging;
        }

        private void SaveSessionAction(object obj)
        {
            var sessionManager = ServiceLocator.Instance.Get<ISessionManager>();

            // Open a save file dialog
            var savefile = new SaveFileDialog
            {
                FileName = sessionManager.Name,
                DefaultExt = ".sntl",
                Filter = "Sentinel session (.sntl)|*.sntl",
                FilterIndex = 0,
            };

            if (savefile.ShowDialog(this) == true)
            {
                sessionManager.SaveSession(savefile.FileName);
                AddToRecentFiles(savefile.FileName);
            }
        }

        private void AddToRecentFiles(string fileName)
        {
            if (RecentFiles.Contains(fileName))
            {
                RecentFiles.Move(RecentFiles.IndexOf(fileName), 0);
            }
            else
            {
                RecentFiles.Insert(0, fileName);
            }

            // Keep list at no more than 13
            if (RecentFiles.Count > 13)
            {
                RecentFiles.Remove(RecentFiles.LastOrDefault());
            }
        }

        private void NewSessionAction(object obj)
        {
            var sessionManager = ServiceLocator.Instance.Get<ISessionManager>();

            if (!sessionManager.IsSaved)
            {
                var userResult = MessageBox.Show(
                    "Do you want to save changes you made to " + sessionManager.Name + "?",
                    "Sentinel",
                    MessageBoxButton.YesNoCancel,
                    MessageBoxImage.Warning);

                if (userResult == MessageBoxResult.Cancel)
                {
                    return;
                }

                if (userResult == MessageBoxResult.Yes)
                {
                    SaveSession.Execute(null);

                    // if the user clicked "Cancel" at the save dialog box
                    if (!sessionManager.IsSaved)
                    {
                        return;
                    }
                }
            }

            // Remove the tab control.
            if (TabControl.Items.Count > 0)
            {
                var tab = TabControl.SelectedItem;
                TabControl.Items.Remove(tab);
            }

            Add.Execute(null);
        }

        private void LoadSessionAction(object obj)
        {
            var sessionManager = ServiceLocator.Instance.Get<ISessionManager>();
            var fileNameToLoad = (string)obj;

            if (!sessionManager.IsSaved)
            {
                var userResult = MessageBox.Show(
                    "Do you want to save changes you made to " + sessionManager.Name + "?",
                    "Sentinel",
                    MessageBoxButton.YesNoCancel,
                    MessageBoxImage.Warning);

                if (userResult == MessageBoxResult.Cancel)
                {
                    return;
                }

                if (userResult == MessageBoxResult.Yes)
                {
                    SaveSession.Execute(null);

                    // if the user clicked "Cancel" at the save dialog box
                    if (!sessionManager.IsSaved)
                    {
                        return;
                    }
                }
            }

            if (fileNameToLoad == null)
            {
                // open a save file dialog
                var openFile = new OpenFileDialog
                {
                    FileName = sessionManager.Name,
                    DefaultExt = ".sntl",
                    Filter = "Sentinel session (.sntl)|*.sntl",
                    FilterIndex = 0,
                };

                if (openFile.ShowDialog(this) == true)
                {
                    fileNameToLoad = openFile.FileName;
                }
                else
                {
                    return;
                }
            }

            // Remove the tab control.
            if (TabControl.Items.Count > 0)
            {
                var tab = TabControl.SelectedItem;
                TabControl.Items.Remove(tab);
            }

            RemoveBindingReferences();

            sessionManager.LoadSession(fileNameToLoad);
            AddToRecentFiles(fileNameToLoad);

            BindViewToViewModel();

            if (!sessionManager.ProviderSettings.Any())
            {
                return;
            }

            var frame = ServiceLocator.Instance.Get<IWindowFrame>();

            // Add to the tab control.
            var newTab = new TabItem { Header = sessionManager.Name, Content = frame };
            TabControl.Items.Add(newTab);
            TabControl.SelectedItem = newTab;
        }

        /// <summary>
        /// AddNewListenerAction method provides a mechanism for the user to add additional
        /// listeners to the log-viewer.
        /// </summary>
        /// <param name="obj">Object to add as a new listener.</param>
        private void AddNewListenerAction(object obj)
        {
            // Load a new session
            var sessionManager = ServiceLocator.Instance.Get<ISessionManager>();

            RemoveBindingReferences();

            sessionManager.LoadNewSession(this);

            BindViewToViewModel();

            if (!sessionManager.ProviderSettings.Any())
            {
                return;
            }

            var frame = ServiceLocator.Instance.Get<IWindowFrame>();

            // Add to the tab control.
            var tab = new TabItem { Header = sessionManager.Name, Content = frame };
            TabControl.Items.Add(tab);
            TabControl.SelectedItem = tab;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Exit = new DelegateCommand(ee => Close());
            About = new DelegateCommand(
                ee =>
                {
                    var about = new AboutWindow(this);
                    about.ShowDialog();
                });

            Add = new DelegateCommand(AddNewListenerAction, b => TabControl.Items.Count < 1);
            ShowPreferences = new DelegateCommand(ShowPreferencesAction);
            ExportLogs = new DelegateCommand(ExportLogsAction, b => TabControl.Items.Count > 0);
            SaveSession = new DelegateCommand(SaveSessionAction);
            NewSession = new DelegateCommand(NewSessionAction);
            LoadSession = new DelegateCommand(LoadSessionAction);
            RecentFiles = new ObservableCollection<string>(recentFilePathList.Take(13));

            BindViewToViewModel();

            var commandLine = Environment.GetCommandLineArgs();
            if (commandLine.Length == 1)
            {
                Add.Execute(null);
            }
            else
            {
                ProcessCommandLine(commandLine.Skip(1));
            }

            // Debug the available loggers.
            var logManager = ServiceLocator.Instance.Get<Logs.Interfaces.ILogManager>();
            foreach (var logger in logManager)
            {
                Log.DebugFormat("Log: {0}", logger.Name);
            }

            var providerManager = ServiceLocator.Instance.Get<IProviderManager>();
            foreach (var instance in providerManager.Instances)
            {
                Log.DebugFormat("Provider: {0}", instance.Name);
                Log.DebugFormat("   - is {0}active", instance.IsActive ? string.Empty : "not ");
                Log.DebugFormat("   - logger = {0}", instance.Logger);
            }
        }

        private void ProcessCommandLine(IEnumerable<string> commandLine)
        {
            commandLine.ThrowIfNull(nameof(commandLine));

            var commandLineArguments = commandLine as string[] ?? commandLine.ToArray();
            if (!commandLineArguments.Any())
            {
                throw new ArgumentException("Collection must have at least one element", nameof(commandLine));
            }

            var sessionManager = ServiceLocator.Instance.Get<ISessionManager>();

            var unknownCommandLine = false;
            var args = commandLineArguments.ToArray();

            var options = Parser.Default.ParseArguments<Log4NetOptions, NLogOptions>(args).MapResult(
                (Log4NetOptions o) => Tuple.Create<string, IOptions>("log4net", o),
                (NLogOptions o) => Tuple.Create<string, IOptions>("nlog", o),
                _ => Tuple.Create<string, IOptions>(string.Empty, null));

            var verb = options.Item1;

            if (string.IsNullOrWhiteSpace(options.Item1))
            {
                var filePath = commandLineArguments.FirstOrDefault();
                if (!File.Exists(filePath) || Path.GetExtension(filePath)?.ToUpper() != ".SNTL")
                {
                    unknownCommandLine = true;
                }
            }

            if (unknownCommandLine)
            {
                // TODO: command line usage dialog
                MessageBox.Show(
                    "File does not exist or is not a Sentinel session file.",
                    "Sentinel",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                return;
            }

            RemoveBindingReferences();

            switch (verb)
            {
                case "nlog":
                    CreateDefaultNLogListener((NLogOptions)options.Item2, sessionManager);
                    break;
                case "log4net":
                    CreateDefaultLog4NetListener((Log4NetOptions)options.Item2, sessionManager);
                    break;
                default:
                    sessionManager.LoadSession(commandLineArguments.FirstOrDefault());
                    break;
            }

            BindViewToViewModel();

            var frame = ServiceLocator.Instance.Get<IWindowFrame>();

            // Add to the tab control.
            var newTab = new TabItem { Header = sessionManager.Name, Content = frame };
            TabControl.Items.Add(newTab);
            TabControl.SelectedItem = newTab;
        }

        private void CreateDefaultLog4NetListener(Log4NetOptions log4NetOptions, ISessionManager sessionManager)
        {
            var info = $"Using log4net listener on Udp port {log4NetOptions.Port}";
            Log.Debug(info);

            var providerSettings = new UdpAppenderSettings
            {
                Port = log4NetOptions.Port,
                Name = info,
                Info = Log4NetProvider.ProviderRegistrationInformation.Info,
            };

            var providers =
                Enumerable.Repeat(
                    new PendingProviderRecord
                    {
                        Info = Log4NetProvider.ProviderRegistrationInformation.Info,
                        Settings = providerSettings,
                    },
                    1);

            sessionManager.LoadProviders(providers);
        }

        private void CreateDefaultNLogListener(NLogOptions verbOptions, ISessionManager sessionManager)
        {
            var name = $"Using nlog listener on {(verbOptions.IsUdp ? "Udp" : "Tcp")} port {verbOptions.Port}";
            var info = NLogViewerProvider.ProviderRegistrationInformation.Info;
            Log.Debug(name);

            var providerSettings = new NetworkSettings
            {
                Protocol =
                    verbOptions.IsUdp
                        ? NetworkProtocol.Udp
                        : NetworkProtocol.Tcp,
                Port = verbOptions.Port,
                Name = name,
                Info = info,
            };
            var providers = Enumerable.Repeat(
                new PendingProviderRecord { Info = info, Settings = providerSettings },
                1);

            sessionManager.LoadProviders(providers);
        }

        private void RestoreWindowPosition(WindowPlacementInfo wp)
        {
            _ = wp ?? throw new ArgumentNullException(nameof(wp));

            // Validation routine will cope with Null being passed and if it finds an error, it returns null.
            wp = ValidateScreenPosition(wp);

            if (wp != null)
            {
                Log.DebugFormat(
                    "Window position being restored to ({0},{1})-({2},{3}) {4}",
                    wp.Top,
                    wp.Left,
                    wp.Top + wp.Height,
                    wp.Left + wp.Width,
                    wp.WindowState);

                Top = wp.Top;
                Left = wp.Left;
                Width = wp.Width;
                Height = wp.Height;

                // TODO: would it make sense to start up minimized if that was how it was terminated?
                WindowState = wp.WindowState;
            }
        }

        private void PreferencesChanged(object sender, PropertyChangedEventArgs e)
        {
            if (Preferences != null)
            {
                if (e.PropertyName == "Show")
                {
                    if (Preferences.Show)
                    {
                        preferencesWindow = new PreferencesWindow(preferencesWindowTabSelected) { Owner = this };
                        preferencesWindow.Show();
                    }
                    else if (preferencesWindow != null)
                    {
                        preferencesWindow.Close();
                        preferencesWindow = null;
                    }
                }
            }
        }

        private void ViewManagerChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                TabControl.SelectedIndex = TabControl.Items.Count - 1;
            }
        }

        private void OnClosed(object sender, CancelEventArgs e)
        {
            var windowInfo = new WindowPlacementInfo
            {
                Height = (int)Height,
                Top = (int)Top,
                Left = (int)Left,
                Width = (int)Width,
                WindowState = WindowState,
            };

            var filename = Path.ChangeExtension(persistingFilename, ".json");
            PersistingSettings.Save(filename, windowInfo, Preferences);

            var recentFileInfo = new RecentFileInfo { RecentFilePaths = RecentFiles.ToList() };

            JsonHelper.SerializeToFile(recentFileInfo, Path.ChangeExtension(persistingRecentFileName, ".json"));
        }

        private void RetainOnlyStandardFilters(object sender, FilterEventArgs e)
        {
            sender.ThrowIfNull(nameof(sender));
            e.ThrowIfNull(nameof(e));
            e.Accepted = e.Item is IStandardDebuggingFilter;
        }

        private void ExcludeStandardFilters(object sender, FilterEventArgs e)
        {
            sender.ThrowIfNull(nameof(sender));
            e.ThrowIfNull(nameof(e));
            e.Accepted = !(e.Item is IStandardDebuggingFilter || e.Item is ISearchFilter);
        }

        private void RetainOnlyStandardHighlighters(object sender, FilterEventArgs e)
        {
            sender.ThrowIfNull(nameof(sender));
            e.ThrowIfNull(nameof(e));
            e.Accepted = e.Item is IStandardDebuggingHighlighter;
        }

        private void ExcludeStandardHighlighters(object sender, FilterEventArgs e)
        {
            sender.ThrowIfNull(nameof(sender));
            e.ThrowIfNull(nameof(e));
            e.Accepted = !(e.Item is IStandardDebuggingHighlighter);
        }

        private void SearchToggleButtonChecked(object sender, RoutedEventArgs e)
        {
            Debug.Assert(
                sender.GetType() == typeof(RibbonToggleButton),
                $"A {sender.GetType()} accessed the wrong method");

            var button = (RibbonToggleButton)sender;
            switch (button.Label)
            {
                case "Highlight":
                    BindSearchToSearchHighlighter();
                    break;
                case "Filter":
                    BindSearchToSearchFilter();
                    break;
                case "Extract":
                    BindSearchToSearchExtractor();
                    break;
            }
        }

        private void BindSearchToSearchExtractor()
        {
            SearchRibbonTextBox.SetBinding(TextBox.TextProperty, CreateBinding("Pattern", SearchExtractor));
            SearchModeListBox.SetBinding(Selector.SelectedItemProperty, CreateBinding("Mode", SearchExtractor));
            SearchTargetComboBox.SetBinding(Selector.SelectedItemProperty, CreateBinding("Field", SearchExtractor));

            HighlightToggleButton.IsChecked = false;
            FilterToggleButton.IsChecked = false;
        }

        private Binding CreateBinding(string path, object source)
        {
            return new Binding
            {
                Source = source,
                Path = new PropertyPath(path),
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            };
        }

        private void BindSearchToSearchFilter()
        {
            SearchRibbonTextBox.SetBinding(TextBox.TextProperty, CreateBinding("Pattern", SearchFilter));
            SearchModeListBox.SetBinding(Selector.SelectedItemProperty, CreateBinding("Mode", SearchFilter));
            SearchTargetComboBox.SetBinding(Selector.SelectedItemProperty, CreateBinding("Field", SearchFilter));
            HighlightToggleButton.IsChecked = false;
            ExtractToggleButton.IsChecked = false;
        }

        private void BindSearchToSearchHighlighter()
        {
            SearchRibbonTextBox.SetBinding(TextBox.TextProperty, CreateBinding("Search", Search));
            SearchModeListBox.SetBinding(Selector.SelectedItemProperty, CreateBinding("Mode", Search));
            SearchTargetComboBox.SetBinding(Selector.SelectedItemProperty, CreateBinding("Field", Search));
            FilterToggleButton.IsChecked = false;
            ExtractToggleButton.IsChecked = false;
        }

        private void RemoveBindingReferences()
        {
            var notifyPropertyChanged = Preferences as INotifyPropertyChanged;
            if (notifyPropertyChanged != null)
            {
                notifyPropertyChanged.PropertyChanged -= PreferencesChanged;
            }

            ViewManager.Viewers.CollectionChanged -= ViewManagerChanged;
        }

        private void BindViewToViewModel()
        {
            // Append version number to caption (to save effort of producing an about screen)
            Title =
                $"{Assembly.GetExecutingAssembly().GetName().Name} ({Assembly.GetExecutingAssembly().GetName().Version})"
                + $" {ServiceLocator.Instance.Get<ISessionManager>().Name}";

            // Preferences, if initialised, has come from persistence, so register current copy
            // otherwise, ask for one that will be shared.
            if (Preferences != null)
            {
                ServiceLocator.Instance.Register<IUserPreferences>(Preferences);
            }
            else
            {
                Preferences = ServiceLocator.Instance.Get<IUserPreferences>();
            }

            ViewManager = ServiceLocator.Instance.Get<IViewManager>();

            // Maintaining column widths is proving difficult in Xaml alone, so
            // add an observer here and deal with it in code.
            if (Preferences is INotifyPropertyChanged changed)
            {
                changed.PropertyChanged += PreferencesChanged;
            }

            DataContext = this;

            // When a new item is added, select the newest one.
            ViewManager.Viewers.CollectionChanged += ViewManagerChanged;

            // View-specific bindings
            var collapseIfZero = new CollapseIfZeroConverter();

            var standardHighlighters = new CollectionViewSource { Source = Highlighters.Highlighters };
            standardHighlighters.View.Filter = c => c is IStandardDebuggingHighlighter;

            var customHighlighters = new CollectionViewSource { Source = Highlighters.Highlighters };
            customHighlighters.View.Filter = c => !(c is IStandardDebuggingHighlighter);

            StandardHighlightersRibbonGroup.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = standardHighlighters });

            StandardHighlighterRibbonGroupOnTab.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = standardHighlighters });
            var collapsingStandardHighlightersBinding = new Binding
            {
                Source = standardHighlighters,
                Path = new PropertyPath("Count"),
                Converter = collapseIfZero,
            };
            StandardHighlighterRibbonGroupOnTab.SetBinding(VisibilityProperty, collapsingStandardHighlightersBinding);

            CustomHighlighterRibbonGroupOnTab.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = customHighlighters });

            var collapsingCustomHighlightersBinding = new Binding
            {
                Source = customHighlighters,
                Path = new PropertyPath("Count"),
                Converter = collapseIfZero,
            };
            CustomHighlighterRibbonGroupOnTab.SetBinding(VisibilityProperty, collapsingCustomHighlightersBinding);

            var standardFilters = new CollectionViewSource { Source = Filters.Filters };
            standardFilters.View.Filter = c => c is IStandardDebuggingFilter;

            var customFilters = new CollectionViewSource { Source = Filters.Filters };
            customFilters.View.Filter = c => !(c is IStandardDebuggingFilter);

            StandardFiltersRibbonGroup.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = standardFilters });

            StandardFiltersRibbonGroupOnTab.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = standardFilters });

            StandardFiltersRibbonGroupOnTab.SetBinding(
                VisibilityProperty,
                new Binding { Source = standardFilters, Path = new PropertyPath("Count"), Converter = collapseIfZero });
            CustomFiltersRibbonGroupOnTab.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = customFilters });
            CustomFiltersRibbonGroupOnTab.SetBinding(
                VisibilityProperty,
                new Binding { Source = customFilters, Path = new PropertyPath("Count"), Converter = collapseIfZero });

            var customExtractors = Extractors.Extractors;
            CustomExtractorsRibbonGroupOnTab.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = customExtractors });

            var customClassifyiers = ClassifyingService.Classifiers;
            CustomClassifiersRibbonGroupOnTab.SetBinding(
                ItemsControl.ItemsSourceProperty,
                new Binding { Source = customClassifyiers });

            BindToSearchElements();

            // Column view buttons
            ExceptionRibbonToggleButton.SetBinding(
                ToggleButton.IsCheckedProperty,
                new Binding { Source = Preferences, Path = new PropertyPath("ShowExceptionColumn") });
            ThreadRibbonToggleButton.SetBinding(
                ToggleButton.IsCheckedProperty,
                new Binding { Source = Preferences, Path = new PropertyPath("ShowThreadColumn") });
            SourceHostRibbonToggleButton.SetBinding(
                ToggleButton.IsCheckedProperty,
                new Binding { Source = Preferences, Path = new PropertyPath("ShowSourceColumn") });
            DebugSourceRibbonToggleButton.SetBinding(
                ToggleButton.IsCheckedProperty,
                new Binding { Source = Preferences, Path = new PropertyPath("ShowSourceInformationColumns") });
            ContextRibbonToggleButton.SetBinding(
                ToggleButton.IsCheckedProperty,
                new Binding { Source = Preferences, Path = new PropertyPath("ShowContextColumn") });
        }

        private void BindToSearchElements()
        {
            // Bind search
            HighlightToggleButton.SetBinding(ToggleButton.IsCheckedProperty, CreateBinding("Enabled", Search));
            FilterToggleButton.SetBinding(ToggleButton.IsCheckedProperty, CreateBinding("Enabled", SearchFilter));
            ExtractToggleButton.SetBinding(ToggleButton.IsCheckedProperty, CreateBinding("Enabled", SearchExtractor));

            if (Search.Enabled)
            {
                BindSearchToSearchHighlighter();
            }
            else if (SearchFilter.Enabled)
            {
                BindSearchToSearchFilter();
            }
            else if (SearchExtractor.Enabled)
            {
                BindSearchToSearchExtractor();
            }
        }

        private void GetRecentlyOpenedFiles()
        {
            if (string.IsNullOrWhiteSpace(persistingRecentFileName))
            {
                return;
            }

            var fileName = Path.ChangeExtension(persistingRecentFileName, ".json");
            var recentFileInfo = JsonHelper.DeserializeFromFile<RecentFileInfo>(fileName);

            recentFilePathList = recentFileInfo?.RecentFilePaths.ToList() ?? new List<string>();
        }
    }
}

================================================
FILE: Sentinel/Controls/PersistingSettings.cs
================================================
namespace Sentinel.Controls
{
    using System;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    using Sentinel.Interfaces;
    using Sentinel.Support;

    [DataContract]
    public class PersistingSettings
    {
        [DataMember]
        public WindowPlacementInfo WindowPlacementInfo { get; set; }

        [DataMember]
        public IUserPreferences UserPreferences { get; set; }

        internal static PersistingSettings Load(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new System.ArgumentException("Value cannot be null or whitespace.", nameof(fileName));
            }

            // Note that PersistingSettings is a new file format, so need to detect whether using
            // new serialisation or upgrading.
            if (System.IO.File.Exists(fileName))
            {
                var fileContents = System.IO.File.ReadAllText(fileName);

                // Version detect from file-header signature:
                var fileHeader = fileContents
                    .Substring(0, 52)
                    .Replace(" ", string.Empty)
                    .Replace("\r", string.Empty)
                    .Replace("\n", string.Empty);

                switch (fileHeader)
                {
                    case "{\"$type\":\"Sentinel.Controls.WindowPlacementInfo":
                        return DeserializeFromV1(fileContents);
                    case "{\"$type\":\"Sentinel.Controls.PersistingSettings,":
                        return DeserializeFromV2(fileContents);
                    default:
                        return null;
                }
            }

            return null;
        }

        internal static void Save(string fileName, WindowPlacementInfo placementInfo, IUserPreferences userPreferences)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(fileName));
            }

            var wrapper = new PersistingSettings
            {
                WindowPlacementInfo = placementInfo,
                UserPreferences = userPreferences,
            };

            try
            {
                JsonHelper.SerializeToFile(wrapper, fileName);
            }
            catch (Exception e)
            {
                Trace.TraceError($"Unable to write persistence file: {e.Message}");
            }
        }

        private static PersistingSettings DeserializeFromV1(string fileContents)
        {
            Trace.WriteLine("DeserializeFromV1");

            PersistingSettings wrapper = null;

            try
            {
                wrapper = new PersistingSettings
                {
                    WindowPlacementInfo = JsonHelper.DeserializeFromString<WindowPlacementInfo>(fileContents),
                };
            }
            catch (Exception e)
            {
                Trace.TraceError($"Deserialize error: {e.Message}");
            }

            return wrapper;
        }

        private static PersistingSettings DeserializeFromV2(string fileContents)
        {
            Trace.WriteLine("DeserializeFromV1");

            try
            {
                return JsonHelper.DeserializeFromString<PersistingSettings>(fileContents);
            }
            catch (Exception e)
            {
                Trace.TraceError($"Deserialize error: {e.Message}");
                return null;
            }
        }
    }
}

================================================
FILE: Sentinel/Controls/PreferencesControl.xaml
================================================
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:controls="clr-namespace:Sentinel.Controls"
             xmlns:highlighters="clr-namespace:Sentinel.Highlighters.Gui"
             xmlns:classificationControls="clr-namespace:Sentinel.Classification.Gui"
             xmlns:filters="clr-namespace:Sentinel.Filters.Gui"
             xmlns:extractors="clr-namespace:Sentinel.Extractors.Gui"
             xmlns:converters="clr-namespace:Sentinel.WpfExtras.Converters"
             mc:Ignorable="d"
             x:Class="Sentinel.Controls.PreferencesControl"
             x:Name="UserControl"
             Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">

    <UserControl.Resources>
        <converters:BooleanInvertingValueConverter x:Key="BooleanInverterConverter" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <TabControl SelectedIndex="{Binding SelectedTabIndex}">
            <TabItem Header="General">
                <ScrollViewer HorizontalScrollBarVisibility="Hidden"
                              VerticalScrollBarVisibility="Auto">
                    <DockPanel Margin="5">
                        <StackPanel DockPanel.Dock="Top">
                            <GroupBox Header="Column options">
                                <Grid Margin="5">
                                    <Grid.RowDefinitions>
                                        <RowDefinition />
                                        <RowDefinition />
                                        <RowDefinition />
                                        <RowDefinition />
                                        <RowDefinition />
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                        <ColumnDefinition Width="5" />
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>

                                    <TextBlock Grid.Row="0"
                                               Grid.Column="0"
                                               VerticalAlignment="Center"
                                               Text="Issue Types column :" />
                                    <ComboBox Grid.Row="0"
                                              Grid.Column="2"
                                              SelectedIndex="{Binding Preferences.SelectedTypeOption}"
                                              Width="Auto"
                                              HorizontalAlignment="Left"
                                              Margin="0,5,0,5"
                                              ItemsSource="{Binding Preferences.TypeOptions}"
                                              MinWidth="100" />
                                    <TextBlock Grid.Row="1"
                                               Grid.Column="0"
                                               VerticalAlignment="Center"
                                               Text="Date Format :" />
                                    <ComboBox Grid.Row="1"
                                              Grid.Column="2"
                                              SelectedIndex="{Binding Preferences.SelectedDateOption}"
                                              HorizontalAlignment="Left"
                                              Margin="0,5,0,5"
                                              ItemsSource="{Binding Preferences.DateFormatOptions}"
                                              MinWidth="100" />
                                    <TextBlock Grid.Row="2"
                                               Grid.Column="0"
                                               Margin="0,8"
                                               VerticalAlignment="Top"
                                               Text="Time Format :" />
                                    <StackPanel Grid.Row="2"
                                                Grid.Column="2"
                                                Orientation="Vertical">
                                        <ComboBox SelectedIndex="{Binding Preferences.SelectedTimeFormatOption}"
                                                  Margin="0,5,0,5"
                                                  HorizontalAlignment="Left"
                                                  ItemsSource="{Binding Preferences.TimeFormatOptions}"
                                                  MinWidth="100" />
                                        <CheckBox Margin="0,5,0,5"
                                                  IsChecked="{Binding Preferences.ConvertUtcTimesToLocalTimeZone}">
                                            Convert UTC times to local timezone
                                        </CheckBox>
                                    </StackPanel>
                                    <TextBlock Grid.Row="3"
                                               Grid.Column="0"
                                               Margin="0,4"
                                               VerticalAlignment="Top"
                                               Text="Message Date/Time value :" />
                                    <StackPanel Grid.Row="3"
                                                Grid.Column="2">
                                        <RadioButton Margin="0,5,0,5"
                                                     IsChecked="{Binding Preferences.UseArrivalDateTime}">
                                            Use time of message receipt by Sentinel
                                        </RadioButton>
                                        <RadioButton Margin="0,0,0,5"
                                                     IsChecked="{Binding Preferences.UseArrivalDateTime, Converter={StaticResource BooleanInverterConverter}}">
                                            Use sender's time
                                        </RadioButton>
                                    </StackPanel>
                                    <StackPanel Orientation="Vertical"
                                                Grid.Row="4"
                                                Margin="0,5,0,5"
                                                Grid.ColumnSpan="3"
                                                Grid.Column="0">
                                        <CheckBox IsChecked="{Binding Preferences.ShowExceptionColumn}"
                                                  HorizontalAlignment="Left"
                                                  MinWidth="100"
                                                  Margin="0,0,0,5"
                                                  ToolTip="Showing exceptions will become useful once it is fully implemented."
                                                  Content="Show the Exception column" />
                                        <CheckBox IsChecked="{Binding Preferences.ShowThreadColumn}"
                                                  HorizontalAlignment="Left"
                                                  MinWidth="100"
                                                  Margin="0,0,0,5"
                                                  ToolTip="Showing the originating thread may not always be useful.  The thread identifier (a number) is unique only to the original application.  This can be misleading when multiple applications are being logged, additionally, a correctly named system will yield a more useful context."
                                                  Content="Show the Thread column" />
                                        <CheckBox IsChecked="{Binding Preferences.ShowSourceColumn}"
                                                  HorizontalAlignment="Left"
                                                  MinWidth="100"
                                                  Margin="0,0,0,5"
                                                  ToolTip="Show the name of the machine from which the message was sourced"
                                                  Content="Show the message source host-name column" />
                                        <CheckBox IsChecked="{Binding Preferences.ShowSourceInformationColumns}"
                                                  HorizontalAlignment="Left"
                                                  Margin="0,0,0,5"
                                                  ToolTip="Shows/hides the columns with the source-code information (nLog only)"
                                                  Content="Show source debugging information" />
                                        <StackPanel Orientation="Horizontal"
                                                    VerticalAlignment="Center">
                                            <CheckBox IsChecked="{Binding Preferences.ShowContextColumn}"
                                                      HorizontalAlignment="Left"
                                                      VerticalAlignment="Bottom"
                                                      Margin="0,0,0,5"
                                                      ToolTip="Shows/hides the context column (nLog only)"
                                                      Content="Show the context column" />
                                            <Label Margin="20,0,0,0">Property for context:</Label>
                                            <TextBox
                                                Text="{Binding Preferences.ContextProperty, UpdateSourceTrigger=PropertyChanged}"
                                                Margin="10,0,0,0"
                                                Width="200"
                                                VerticalAlignment="Center" />
                                        </StackPanel>
                                        <CheckBox IsChecked="{Binding Preferences.UseLazyRebuild}"
                                                  HorizontalAlignment="Left"
                                                  ToolTip="Enables/disables live resorting of sortable columns"
                                                  Content="Enable live column resorting mode" />
                                    </StackPanel>
                                </Grid>
                            </GroupBox>
                            <GroupBox Header="Row options">
                                <CheckBox Margin="5"
                                          Content="Use tighter row separation on Vista / Windows7"
                                          ToolTip="Vista and Windows 7 put spacing around each row that takes up a fair amount of space, enabling this option tries to reduce the space to something like that used by Windows XP"
                                          IsChecked="{Binding Preferences.UseTighterRows}" />
                            </GroupBox>
                            <GroupBox Header="Message limits">
                                <StackPanel Orientation="Horizontal"
                                            Margin="5"
                                            VerticalAlignment="Center">
                                    <CheckBox IsChecked="{Binding Preferences.LimitMessages}"
                                              HorizontalAlignment="Left"
                                              VerticalAlignment="Bottom"
                                              Margin="0,0,0,5"
                                              Content="Limit the maximum number of messages retained" />
                                    <StackPanel IsEnabled="{Binding Preferences.LimitMessages}"
                                                Orientation="Horizontal">
                                        <Label Margin="20,0,0,0">Message count:</Label>
                                        <controls:IntegerTextBox
                                            Text="{Binding Preferences.MaximumMessageCount, UpdateSourceTrigger=PropertyChanged}"
                                            Margin="10,0,0,0"
                                            Width="100"
                                            VerticalAlignment="Center" />
                                    </StackPanel>
                                </StackPanel>
                            </GroupBox>
                            <GroupBox Header="Layout">
                                <CheckBox Margin="5"
                                          Content="Use Stacked Layout"
                                          ToolTip="Orientate the two windows as stacked rather than side-by-side."
                                          IsChecked="{Binding Preferences.UseStackedLayout}" />
                            </GroupBox>
                            <GroupBox Header="Interactions">
                                <CheckBox Margin="5"
                                          Content="Show exceptions panel on double-click"
                                          ToolTip="When a log entry has additional exception information, double-clicking will show the exception detail panel."
                                          IsChecked="{Binding Preferences.DoubleClickToShowExceptions}" />
                            </GroupBox>
                        </StackPanel>
                    </DockPanel>
                </ScrollViewer>
            </TabItem>
            <TabItem Header="Classifiers">
                <GroupBox Header="Available Classifiers"
                          Margin="5">
                    <DockPanel>
                        <StackPanel Margin="5"
                                    DockPanel.Dock="Top">
                            <TextBlock TextWrapping="WrapWithOverflow">
                                <Run Text="Classifiers change the type of log messages when enabled." />
                                <Run
                                    Text="Messages are classified as they are received and cannot be changed afterwards." />
                            </TextBlock>
                            <TextBlock TextWrapping="WrapWithOverflow"
                                       Margin="0,5,0,5"
                                       Text="The classifiers are evaluated in the order shown below and the last enabled match wins:" />
                        </StackPanel>
                        <classificationControls:ClassificationsControl />
                    </DockPanel>
                </GroupBox>
            </TabItem>
            <TabItem Header="Highlighters">
                <GroupBox Header="Available Highlighters"
                          Margin="5">
                    <DockPanel>
                        <StackPanel Margin="5"
                                    DockPanel.Dock="Top">
                            <TextBlock TextWrapping="WrapWithOverflow">
                                <Run Text="Highlighters change the appearance of matching log messages when enabled" />
                                <Run Text="so that certain messages are made to stand out from others." />
                                <Run Text="An example would be marking Error messages in a red background." />
                            </TextBlock>
                            <TextBlock TextWrapping="WrapWithOverflow"
                                       Margin="0,5,0,5"
                                       Text="The highlighters are evaluated in the order shown below and the first enabled match wins:" />
                        </StackPanel>
                        <highlighters:HighlightersControl />
                    </DockPanel>
                </GroupBox>
            </TabItem>
            <TabItem Header="Filters">
                <GroupBox Header="Available Filters"
                          Margin="5">
                    <DockPanel>
                        <StackPanel Margin="5"
                                    DockPanel.Dock="Top">
                            <TextBlock TextWrapping="WrapWithOverflow">
                                <Run Text="Filters remove matching log messages from view when enabled." />
                                <Run
                                    Text="They do not prevent the messages from being recorded, just from being displayed." />
                            </TextBlock>
                            <TextBlock TextWrapping="WrapWithOverflow"
                                       Margin="0,5,0,5"
                                       Text="The list below indicates the available filters that may be applied:" />
                        </StackPanel>
                        <filters:FiltersControl Height="Auto"
                                                VerticalAlignment="Stretch" />
                    </DockPanel>
                </GroupBox>
            </TabItem>
            <TabItem Header="Extractors">
                <GroupBox Header="Available Extractors"
                          Margin="5">
                    <DockPanel>
                        <StackPanel Margin="5"
                                    DockPanel.Dock="Top">
                            <TextBlock TextWrapping="WrapWithOverflow">
                                <Run Text="Extractors remove unmatching log messages from view when enabled." />
                                <Run
                                    Text="They do not prevent the messages from being recorded, just from being displayed." />
                            </TextBlock>
                            <TextBlock TextWrapping="WrapWithOverflow"
                                       Margin="0,5,0,5"
                                       Text="The list below indicates the available extractors that may be applied:" />
                        </StackPanel>
                        <extractors:ExtractorsControl Height="Auto"
                                                      VerticalAlignment="Stretch" />
                    </DockPanel>
                </GroupBox>
            </TabItem>
            <TabItem Header="Images">
                <GroupBox Header="Available Images"
                          Margin="5">
                    <DockPanel>
                        <StackPanel Margin="5"
                                    DockPanel.Dock="Top">
                            <TextBlock TextWrapping="WrapWithOverflow">
                                <Run Text="Images are displayed for log messages by matching types." />
                                <Run Text="They are displayed for Classifiers, Highlighters, Filters, and Extractors" />
                                <Run Text="by matching names." />
                            </TextBlock>
                            <TextBlock TextWrapping="WrapWithOverflow"
                                       Margin="0,5,0,5"
                                       Text="The list below indicates the registered images:" />
                        </StackPanel>
                        <controls:ImageTypesControl />
                    </DockPanel>
                </GroupBox>
            </TabItem>
            <TabItem Header="Commands">
                <GroupBox Header="Experimental Commands"
                          Margin="5">
                    <DockPanel>
                        <StackPanel Margin="5"
                                    DockPanel.Dock="Top">
                            <TextBlock TextWrapping="WrapWithOverflow">
                                <Run
                                    Text="When specific logging messages are sent, interpret them as commands for controlling Sentinel." />
                            </TextBlock>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="200" />
                                </Grid.ColumnDefinitions>

                                <CheckBox Content="Clear the log"
                                          VerticalAlignment="Center"
                                          IsChecked="{Binding Preferences.EnableClearCommand}" />
                                <Label Grid.Column="1">Text to match:</Label>
                                <TextBox Grid.Column="2"
                                         VerticalAlignment="Center"
                                         Text="{Binding Preferences.ClearCommandMatchText}" />
                            </Grid>
                        </StackPanel>
                    </DockPanel>
                </GroupBox>
            </TabItem>
        </TabControl>
    </Grid>
</UserControl>

================================================
FILE: Sentinel/Controls/PreferencesControl.xaml.cs
================================================
namespace Sentinel.Controls
{
    /// <summary>
    /// Interaction logic for PreferencesControl.xaml.
    /// </summary>
    public partial class PreferencesControl
    {
        public PreferencesControl()
        {
            InitializeComponent();
        }
    }
}

================================================
FILE: Sentinel/Controls/PreferencesWindow.xaml
================================================
<Window x:Class="Sentinel.Controls.PreferencesWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Controls="clr-namespace:Sentinel.Controls"
        Title="Preferences"
        Height="548.644"
        Width="662"
        ResizeMode="CanResizeWithGrip"
        ShowInTaskbar="False"
        Closed="WindowClosed"
        Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
        WindowStyle="ToolWindow"
        WindowStartupLocation="CenterOwner">
    <Controls:PreferencesControl HorizontalAlignment="Stretch"
                              VerticalAlignment="Stretch" />
</Window>


================================================
FILE: Sentinel/Controls/PreferencesWindow.xaml.cs
================================================
namespace Sentinel.Controls
{
    using System;

    using Sentinel.Interfaces;
    using Sentinel.Services;

    /// <summary>
    /// Interaction logic for PreferencesWindow.xaml.
    /// </summary>
    public partial class PreferencesWindow
    {
        public PreferencesWindow()
            : this(0)
        {
        }

        public PreferencesWindow(int selectedTabIndex)
        {
            InitializeComponent();
            Preferences = ServiceLocator.Instance.Get<IUserPreferences>();
            SelectedTabIndex = selectedTabIndex;
            DataContext = this;
        }

        // ReSharper disable once MemberCanBePrivate.Global
        public int SelectedTabIndex { get; set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public IUserPreferences Preferences { get; private set; }

        private void WindowClosed(object sender, EventArgs e)
        {
            Preferences.Show = false;
        }
    }
}

================================================
FILE: Sentinel/Controls/RecentFileInfo.cs
================================================
namespace Sentinel.Controls
{
    using System.Collections.Generic;
    using System.Runtime.Serialization;

    [DataContract]
    public class RecentFileInfo
    {
        [DataMember]
        public IEnumerable<string> RecentFilePaths { get; set; }
    }
}


================================================
FILE: Sentinel/Controls/WindowPlacementInfo.cs
================================================
namespace Sentinel.Controls
{
    using System.Runtime.Serialization;
    using System.Windows;

    [DataContract]
    public class WindowPlacementInfo
    {
        [DataMember]
        public int Top { get; set; }

        [DataMember]
        public int Left { get; set; }

        [DataMember]
        public int Width { get; set; }

        [DataMember]
        public int Height { get; set; }

        [DataMember]
        public WindowState WindowState { get; set; }
    }
}

================================================
FILE: Sentinel/EventLogMonitor/CommandLineOptions.cs
================================================
namespace Sentinel.EventLogMonitor
{
    using CommandLine;

    public class CommandLineOptions
    {
        [Option('b', "no-banner", Default = false, HelpText = "Hide the copyright banner shown on application startup")]
        public bool SuppressBanner { get; set; }
    }
}

================================================
FILE: Sentinel/EventLogMonitor/EventLogEntry.cs
================================================
namespace Sentinel.EventLogMonitor
{
    using System;
    using System.Diagnostics;
    using System.Text;

    using Sentinel.EventLogMonitor.Interfaces;
    using Sentinel.Interfaces.CodeContracts;

    internal class EventLogEntry : IEventLogEntry
    {
        public EventLogEntry(System.Diagnostics.EventLogEntry entry)
        {
            entry.ThrowIfNull(nameof(entry));
            Entry = entry;
        }

        public string MachineName => Entry.MachineName;

        public EventLogEntryType EntryType => Entry.EntryType;

        public string Message => Entry.Message;

        public DateTime EventTime => Entry.TimeGenerated;

        public string Category => Entry.Category;

        public long InstanceId => Entry.InstanceId;

        public string Source => Entry.Source;

        public string UserName => Entry.UserName;

        private System.Diagnostics.EventLogEntry Entry { get; }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.AppendLine($"Type    : {EntryType}");
            sb.AppendLine($"Created : {EventTime}");
            sb.AppendLine($"Category: {Category}");
            sb.AppendLine($"Message : {Message}");
            sb.AppendLine($"Machine : {MachineName}");
            sb.AppendLine($"Source  : {Source}");
            sb.AppendLine($"User    : {UserName}");
            sb.AppendLine($"Inst Id : {InstanceId}");

            return sb.ToString();
        }
    }
}

================================================
FILE: Sentinel/EventLogMonitor/Interfaces/IEventLogEntry.cs
================================================
namespace Sentinel.EventLogMonitor.Interfaces
{
    using System;
    using System.Diagnostics;

    using Newtonsoft.Json;

    public interface IEventLogEntry
    {
        [JsonProperty(Order = 1, Required = Required.Always)]
        EventLogEntryType EntryType { get; }

        [JsonProperty(Order = 2)]
        string Message { get; }

        [JsonProperty(Order = 3)]
        string Source { get; }

        [JsonProperty(Order = 4)]
        DateTime EventTime { get; }

        [JsonProperty(Order = 5)]
        string Category { get; }

        [JsonProperty(Order = 6, DefaultValueHandling = DefaultValueHandling.Ignore)]
        long InstanceId { get; }

        [JsonProperty(Order = 7, DefaultValueHandling = DefaultValueHandling.Ignore)]
        string MachineName { get; }

        [JsonProperty(Order = 8, DefaultValueHandling = DefaultValueHandling.Ignore)]
        string UserName { get; }
    }
}

================================================
FILE: Sentinel/Extractors/ExtractingService.cs
================================================
namespace Sentinel.Extractors
{
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Windows.Input;

    using Sentinel.Extractors.Gui;
    using Sentinel.Extractors.Interfaces;
    using Sentinel.Interfaces;
    using Sentinel.Services;

    using WpfExtras;

    [DataContract]
    public class ExtractingService<T> : ViewModelBase, IExtractingService<T>, IDefaultInitialisation
        where T : class, IExtractor
    {
        private readonly CollectionChangeHelper<T> collectionHelper = new CollectionChangeHelper<T>();

        private readonly IAddExtractorService addExtractorService = new AddExtractor();

        private readonly IEditExtractorService editExtractorService = new EditExtractor();

        private readonly IRemoveExtractorService removeExtractorService = new RemoveExtractor();

        private int selectedIndex = -1;

        public ExtractingService()
        {
            Add = new DelegateCommand(AddExtractor);
            Edit = new DelegateCommand(EditExtractor, e => selectedIndex != -1);
            Remove = new DelegateCommand(RemoveExtractor, e => selectedIndex != -1);

            Extractors = new ObservableCollection<T>();
            SearchExtractors = new ObservableCollection<T>();

            // Register self as an observer of the collection.
            collectionHelper.OnPropertyChanged += CustomExtractorPropertyChanged;

            collectionHelper.ManagerName = "ExtractingService";
            collectionHelper.NameLookup += e => e.Name;

            Extractors.CollectionChanged += collectionHelper.AttachDetach;
            SearchExtractors.CollectionChanged += collectionHelper.AttachDetach;

            var searchExtractor = ServiceLocator.Instance.Get<ISearchExtractor>();

            if (searchExtractor != null)
            {
                SearchExtractors.Add(searchExtractor as T);
            }
            else
            {
                Debug.Fail("The search extractor is null.");
            }
        }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Add { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Edit { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public ICommand Remove { get; private set; }

        // ReSharper disable once MemberCanBePrivate.Global
        public int SelectedIndex
        {
            get
            {
                return selectedIndex;
            }

            set
            {
                if (value != selectedIndex)
                {
                    selectedIndex = value;
                    OnPropertyChanged(nameof(SelectedIndex));
                }
            }
        }

        public ObservableCollection<T> Extractors { get; set; }

        public ObservableCollection<T> SearchExtractors { get; set; }

        public void Initialise()
        {
            // For adding standard extractors
        }

        public bool IsFiltered(ILogEntry entry)
        {
            return Extractors.Any(filter => filter.Enabled && filter.IsMatch(entry))
                   || SearchExtractors.Any(filter => filter.Enabled && filter.IsMatch(entry));
        }

        private void AddExtractor(object obj)
        {
            addExtractorService.Add();
        }

        private void CustomExtractorPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var extractor = sender as Extractor;
            if (extractor != null)
            {
                Trace.WriteLine(
                    $"ExtractingService saw some activity on {extractor.Name} (IsEnabled = {extractor.Enabled})");
            }

            OnPropertyChanged(string.Empty);
        }

        private void EditExtractor(object obj)
        {
            var extractor = Extractors.ElementAt(SelectedIndex);
            if (extractor != null)
            {
                editExtractorService.Edit(extractor);
            }
        }

        private void RemoveExtractor(object obj)
        {
            var extractor = Extractors.ElementAt(SelectedIndex);
            removeExtractorService.Remove(extractor);
        }
    }
}

================================================
FILE: Sentinel/Extractors/Extractor.cs
================================================
namespace Sentinel.Extractors
{
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.Serialization;
    using System.Text.RegularExpressions;

    using Sentinel.Extractors.Interfaces;
    using Sentinel.Interfaces;

    using WpfExtras;

    [DataContract]
    public class Extractor : ViewModelBase, IExtractor
    {
        /// <summary>
        /// Is the extractor enabled?  If so, it will remove anything matching from the output.
        /// </summary>
        private bool enabled;

        private string name;

        private string pattern;

        private LogEntryFields field;

        private MatchMode mode = MatchMode.Exact;

        public Extractor()
        {
            PropertyChanged += (sender, e) =>
            {
                if (e.PropertyName == "Field" || e.PropertyName == "Mode" || e.PropertyName == "Pattern")
                {
                    OnPropertyChanged(nameof(Description));
                }
            };
        }

        public Extractor(string name, LogEntryFields field, string pattern)
        {
            Name = name;
            Pattern = pattern;
            Field = field;
        }

        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the extractor is enabled.
        /// </summary>
        public bool Enabled
        {
            get
            {
                return enabled;
            }

            set
            {
                if (value != enabled)
                {
                    enabled = value;
                    OnPropertyChanged(nameof(Enabled));
                }
            }
        }

        public string Pattern
        {
            get
            {
                return pattern;
            }

            set
            {
                if (pattern != value)
                {
                    pattern = value;
                    OnPropertyChanged(nameof(Pattern));
                }
            }
        }

        public LogEntryFields Field
        {
            get
            {
                return field;
            }

            set
            {
                if (field != value)
                {
                    field = value;
                    OnPropertyChanged(nameof(Field));
                }
            }
        }

        public MatchMode Mode
        {
            get
            {
                return mode;
            }

            set
            {
                if (mode != value)
                {
                    mode = value;
                    OnPropertyChanged(nameof(Mode));
                }
            }
        }

        public string Description
        {
            get
            {
                string modeDescription = "Exact";
                switch (Mode)
                {
                    case MatchMode.RegularExpression:
                        modeDescription = "RegEx";
                        break;
                    case MatchMode.CaseSensitive:
                        modeDescription = "Substring";
                        break;
                }

                return $"{modeDescription} match of {Pattern} in the {Field} field";
            }
        }

        public bool IsMatch(ILogEntry logEntry)
        {
            Debug.Assert(logEntry != null, "LogEntry can not be null.");

            if (string.IsNullOrWhiteSpace(Pattern))
            {
                return false;
            }

            string target;

            switch (Field)
            {
                case LogEntryFields.None:
                    target = string.Empty;
                    break;
                case LogEntryFields.Type:
                    target = logEntry.Type;
                    break;
                case LogEntryFields.System:
                    target = logEntry.System;
                    break;
                case LogEntryFields.Classification:
                    target = string.Empty;
                    break;
                case LogEntryFields.Thread:
                    target = logEntry.Thread;
                    break;
                case LogEntryFields.Source:
                    target = logEntry.Source;
                    break;
                case LogEntryFields.Description:
                    target = logEntry.Description;
                    break;
                case LogEntryFields.Host:
                    target = string.Empty;
                    break;
                default:
                    target = string.Empty;
                    break;
            }

            switch (Mode)
            {
                case MatchMode.Exact:
                    return !target.Equals(Pattern);
                case MatchMode.CaseSensitive:
                    return !target.Contains(Pattern);
                case MatchMode.CaseInsensitive:
                    return !target.ToUpperInvariant().Contains(Pattern.ToUpperInvariant());
                case MatchMode.RegularExpression:
                    var regex = new Regex(Pattern);
                    return !regex.IsMatch(target);
                default:
                    return false;
            }
        }

#if DEBUG
        public override string ToString()
        {
            return Description;
        }

#endif
    }
}


================================================
FILE: Sentinel/Extractors/Gui/AddEditExtractor.cs
================================================
namespace Sentinel.Extractors.Gui
{
    using System.Windows;
    using System.Windows.Input;

    using Sentinel.Interfaces;

    using WpfExtras;

    public class AddEditExtractor : ViewModelBase
    {
        private readonly Window window;

        private string name = "Unnamed";

        private string pattern = "pattern";

        private LogEntryFields field;

        private MatchMode mode;

        public AddEditExtractor(Window window, bool editMode)
        {
            this.window = window;
            if (window != null)
            {
                window.Title = $"{(editMode ? "Edit" : "Register")} Extractor";
            }

            Accept = new DelegateCommand(AcceptDialog, Validates);
            Reject = new DelegateCommand(RejectDialog);
        }

        public ICommand Accept { get; private set; }

        public LogEntryFields Field
        {
            get
            {
                return field;
            }

            set
            {
                field = value;
                OnPropertyChanged(nameof(Field));
            }
        }

        public MatchMode Mode
        {
            get
            {
                return mode;
            }

            set
            {
                mode = value;
                OnPropertyChanged(nameof(Mode));
            }
        }

        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        public string Pattern
        {
            get
            {
                return pattern;
            }

            set
            {
                if (value != pattern)
                {
                    pattern = value;
                    OnPropertyChanged(nameof(Pattern));
                }
            }
        }

        public ICommand Reject { get; private set; }

        private void AcceptDialog(object obj)
        {
            window.DialogResult = true;
            window.Close();
        }

        private void RejectDialog(object obj)
        {
            window.DialogResult = false;
            window.Close();
        }

        private bool Validates(object obj)
        {
            return Name.Length > 0 && Pattern.Length > 0;
        }
    }
}

================================================
FILE: Sentinel/Extractors/Gui/AddEditExtractorWindow.xaml
================================================
<Window x:Class="Sentinel.Extractors.Gui.AddEditExtractorWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:SentinelInterfaces="clr-namespace:Sentinel.Interfaces"
        Title="Add / Edit Extractor"
        ResizeMode="NoResize"
        SizeToContent="WidthAndHeight"
        WindowStyle="SingleBorderWindow"
        Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
        WindowStartupLocation="CenterOwner">
    
    <Window.Resources>
        
        <ObjectDataProvider x:Key="logEntryField"
                            MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="SentinelInterfaces:LogEntryFields" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        
        <ObjectDataProvider x:Key="matchMode"
                            MethodName="GetValues"
                            ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="SentinelInterfaces:MatchMode" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        
    </Window.Resources>

    <DockPanel Height="Auto"
               Margin="5">
        <StackPanel Orientation="Horizontal"
                    DockPanel.Dock="Bottom"
                    Height="36"
                    HorizontalAlignment="Right"
                    Margin="0,10,0,0">
            <Button Content="_OK"
                    Command="{Binding Accept}"
                    Width="80"
                    Margin="0,5"
                    IsDefault="True" />
            <Button Content="_Cancel"
                    Command="{Binding Reject}"
                    Width="80"
                    Margin="5,5,0,5"
                    IsCancel="True" />
        </StackPanel>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Label Content="Extractor name : "
                   Margin="5" />
            <TextBox Grid.Column="1"
                     Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     Margin="5"
                     VerticalContentAlignment="Center" />

            <Label Content="Field to match against : "
                   Grid.Row="1"
                   Margin="5" />
            <ComboBox Grid.Column="1"
                      Grid.Row="1"
                      SelectedItem="{Binding Field, UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Source={StaticResource logEntryField}}"
                      Margin="5"
                      VerticalContentAlignment="Center" />

            <Label Content="Match method : "
                   Margin="5"
                   Grid.Row="2" />
            <ComboBox Grid.Column="1"
                      Grid.Row="2"
                      SelectedItem="{Binding Mode, UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Source={StaticResource matchMode}}"
                      Margin="5"
                      VerticalContentAlignment="Center" />

            <Label Content="Match string :"
                   Margin="5"
                   Grid.Row="3" />
            <TextBox x:Name="matchText"
                     Margin="5"
                     MinWidth="205"
                     Grid.Row="3"
                     Grid.Column="1"
                     Text="{Binding Pattern, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     VerticalContentAlignment="Center" />
        </Grid>
    </DockPanel>
</Window>

================================================
FILE: Sentinel/Extractors/Gui/AddEditExtractorWindow.xaml.cs
================================================
namespace Sentinel.Extractors.Gui
{
    using System.Windows;

    /// <summary>
    /// Interaction logic for AddEditExtractorWindow.xaml.
    /// </summary>
    public partial class AddEditExtractorWindow : Window
    {
        public AddEditExtractorWindow()
        {
            InitializeComponent();
        }
    }
}


================================================
FILE: Sentinel/Extractors/Gui/AddExtractor.cs
================================================
namespace Sentinel.Extractors.Gui
{
    using System.Windows;

    using Sentinel.Extractors.Interfaces;
    using Sentinel.Services;

    public class AddExtractor : IAddExtractorService
    {
        public void Add()
        {
            var extractorWindow = new AddEditExtractorWindow();
            using (var data = new AddEditExtractor(extractorWindow, false))
            {
                extractorWindow.DataContext = data;
                extractorWindow.Owner = Application.Current.MainWindow;

                var dialogResult = extractorWindow.ShowDialog();
                if (dialogResult == null || !(bool)dialogResult)
                {
                    return;
                }

                var extractor = Construct(data);
                if (extractor == null)
                {
                    return;
                }

                var service = ServiceLocator.Instance.Get<IExtractingService<IExtractor>>();
                service?.Extractors.Add(extractor);
            }
        }

        private static Extractor Construct(AddEditExtractor data)
        {
            return new Extractor
                       {
                           Name = data.Name,
                           Field = data.Field,
                           Mode = data.Mode,
                           Pattern = data.Pattern,
                           Enabled = true,
                       };
        }
    }
}

================================================
FILE: Sentinel/Extractors/Gui/EditExtractor.cs
================================================
namespace Sentinel.Extractors.Gui
{
    using System.Diagnostics;
    using System.Windows;

    using Sentinel.Extractors.Interfaces;

    public class EditExtractor : IEditExtractorService
    {
        public void Edit(IExtractor extractor)
        {
            Debug.Assert(extractor != null, "Extractor must be supplied to allow editing.");

            var window = new AddEditExtractorWindow();
            var data = new AddEditExtractor(window, true);
            window.DataContext = data;
            window.Owner = Application.Current.MainWindow;

            data.Name = extractor.Name;
            data.Field = extractor.Field;
            data.Pattern = extractor.Pattern;
            data.Mode = extractor.Mode;

            var dialogResult = window.ShowDialog();

            if (dialogResult != null && (bool)dialogResult)
            {
                extractor.Name = data.Name;
                extractor.Pattern = data.Pattern;
                extractor.Mode = data.Mode;
                extractor.Field = data.Field;
            }
        }
    }
}

================================================
FILE: Sentinel/Extractors/Gui/ExtractorsControl.xaml
================================================
<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Controls="clr-namespace:Sentinel.Support.Wpf"
    mc:Ignorable="d"
    x:Class="Sentinel.Extractors.Gui.ExtractorsControl"
    Name="extractorsControl"
    d:DesignWidth="756.67" d:DesignHeight="250">

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="80" />
        </Grid.ColumnDefinitions>
        <ListView ItemsSource="{Binding Extractors.Extractors}"
                  Grid.Column="0"
                  Grid.Row="0"
                  Grid.RowSpan="4"
                  SelectedIndex="{Binding Extractors.SelectedIndex}">
            <ListView.View>
                <GridView AllowsColumnReorder="False">
                    <Controls:FixedWidthColumn Header="Enabled"
                                               FixedWidth="28">
                        <Controls:FixedWidthColumn.HeaderTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="True"
                                          IsEnabled="False"
                                          ToolTipService.ShowOnDisabled="True"
                                          ToolTip="Is the extractor enabled?" />
                            </DataTemplate>
                        </Controls:FixedWidthColumn.HeaderTemplate>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Enabled}" 
                                          Margin="2,3,0,3"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </Controls:FixedWidthColumn>
                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="Field"
                                    DisplayMemberBinding="{Binding Field}" />
                    <GridViewColumn Header="Mode"
                                    DisplayMemberBinding="{Binding Mode}" />
                    <GridViewColumn Header="Description"
                                    DisplayMemberBinding="{Binding Description}" />
                </GridView>
            </ListView.View>
        </ListView>
        <Button Content="_Add"
                Grid.Row="0"
                Grid.Column="1"
                Command="{Binding Extractors.Add}"
                Margin="5,0,5,5" />
        <Button Content="_Edit"
                Command="{Binding Extractors.Edit}"
                Grid.Row="1"
                Grid.Column="1"
                Margin="5,0,5,5" />
        <Button Content="_Remove"
                Command="{Binding Extractors.Remove}"
                Grid.Row="2"
                Grid.Column="1"
                Margin="5,0,5,5" />
    </Grid>
</UserControl>

================================================
FILE: Sentinel/Extractors/Gui/ExtractorsControl.xaml.cs
================================================
namespace Sentinel.Extractors.Gui
{
    using System.Windows.Controls;

    using Sentinel.Extractors.Interfaces;
    using Sentinel.Services;

    /// <summary>
    /// Interaction logic for ExtractorsControl.xaml.
    /// </summary>
    public partial class ExtractorsControl : UserControl
    {
        public ExtractorsControl()
        {
            InitializeComponent();
            var service = ServiceLocator.Instance.Get<IExtractingService<IExtractor>>();
            if (service != null)
            {
                Extractors = service;
            }

            DataContext = this;
        }

        public IExtractingService<IExtractor> Extractors { get; private set; }
    }
}

================================================
FILE: Sentinel/Extractors/Gui/RemoveExtractor.cs
================================================
namespace Sentinel.Extractors.Gui
{
    using System.Windows;

    using Sentinel.Extractors.Interfaces;
    using Sentinel.Services;

    public class RemoveExtractor
        : IRemoveExtractorService
    {
        public void Remove(IExtractor extractor)
        {
            var service = ServiceLocator.Instance.Get<IExtractingService<IExtractor>>();

            if (service != null)
            {
                var prompt = "Are you sure you want to remove the selected extractor?\r\n\r\n" +
                             $"Extractor Name = \"{extractor.Name}\"";

                var result = MessageBox.Show(
                    prompt,
                    "Remove Extractor",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question,
                    MessageBoxResult.No);

                if (result == MessageBoxResult.Yes)
                {
                    service.Extractors.Remove(extractor);
                }
            }
        }
    }
}

================================================
FILE: Sentinel/Extractors/Interfaces/IAddExtractorService.cs
================================================
namespace Sentinel.Extractors.Interfaces
{
    public interface IAddExtractorService
    {
        void Add();
    }
}

================================================
FILE: Sentinel/Extractors/Interfaces/IEditExtractorService.cs
================================================
namespace Sentinel.Extractors.Interfaces
{
    public interface IEditExtractorService
    {
        void Edit(IExtractor extractor);
    }
}

================================================
FILE: Sentinel/Extractors/Interfaces/IExtractingService.cs
================================================
namespace Sentinel.Extractors.Interfaces
{
    using System.Collections.ObjectModel;
    using System.Runtime.Serialization;

    using Sentinel.Interfaces;

    public interface IExtractingService<T>
    {
        [DataMember]
        ObservableCollection<T> Extractors { get; set; }

        [IgnoreDataMember]
        ObservableCollection<T> SearchExtractors { get; set; }

        bool IsFiltered(ILogEntry entry);
    }
}

================================================
FILE: Sentinel/Extractors/Interfaces/IExtractor.cs
================================================
namespace Sentinel.Extractors.Interfaces
{
    using System.Runtime.Serialization;

    using Sentinel.Interfaces;

    public interface IExtractor
    {
        [DataMember]
        string Name { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether the filter is enabled.
        /// </summary>
        [DataMember]
        bool Enabled { get; set; }

        [DataMember]
        string Pattern { get; set; }

        [DataMember]
        string Description { get; }

        [DataMember]
        LogEntryFields Field { get; set; }

        [DataMember]
        MatchMode Mode { get; set; }

        bool IsMatch(ILogEntry entry);
    }
}

================================================
FILE: Sentinel/Extractors/Interfaces/IRemoveExtractorService.cs
================================================
namespace Sentinel.Extractors.Interfaces
{
    public interface IRemoveExtractorService
    {
        void Remove(IExtractor extractor);
    }
}

================================================
FILE: Sentinel/Extractors/Interfaces/ISearchExtractor.cs
================================================
namespace Sentinel.Extractors.Interfaces
{
    public interface ISearchExtractor : IExtractor
    {
    }
}

================================================
FILE: Sentinel/Extractors/SearchExtractor.cs
================================================
namespace Sentinel.Extractors
{
    using System.Runtime.Serialization;

    using Sentinel.Extractors.Interfaces;
    using Sentinel.Interfaces;

    [DataContract]
    public class SearchExtractor
        : Extractor, IDefaultInitialisation, ISearchExtractor
    {
        public void Initialise()
        {
            Name = "SearchExtractor";
            Field = LogEntryFields.System;
            Pattern = string.Empty;
        }
    }
}

================================================
FILE: Sentinel/FileMonitor/CustomMessageDecoderPage.xaml
================================================
<UserControl x:Class="Sentinel.FileMonitor.CustomMessageDecoderPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Loaded="OnLoaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <TextBlock Margin="3"
                   Grid.Column="0"
                   Grid.ColumnSpan="2"
                   TextWrapping="WrapWithOverflow">
            <Run>Define a regular expression, using named captures, to decompose the log message into its appropriate fields.</Run>
            <LineBreak />
            <LineBreak />
            <Run>An example pattern would therefore include something like:</Run>
            <LineBreak />
            <LineBreak />
            <Run FontWeight="Bold"
                 FontFamily="Courier New"
                 Text="(?&lt;DateTime&gt;[^|]+)" />
            <LineBreak />
            <LineBreak />
            <Run>Common field names are Description, Type and DateTime and at least one of these must be matched.</Run>
        </TextBlock>
        <TextBlock Grid.Column="0"
                   Grid.Row="1"
                   Margin="3,10,3,3"
                   Text="Pattern : " />
        <TextBox Grid.Column="1"
                 AcceptsReturn="True"
                 Grid.Row="1"
                 Margin="3,10,3,3"
                 Text="{Binding CustomFormat, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnDataErrors=True}"
                 VerticalAlignment="Stretch" />
        <TextBlock Grid.Column="0"
                   Grid.Row="2"
                   Grid.ColumnSpan="2"
                   TextWrapping="WrapWithOverflow"
                   FontWeight="Bold"
                   Foreground="Red"
                   Text="{Binding Error}"
                   TextAlignment="Center" />
    </Grid>
</UserControl>


================================================
FILE: Sentinel/FileMonitor/CustomMessageDecoderPage.xaml.cs
================================================
namespace Sentinel.FileMonitor
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Controls;

    using WpfExtras;

    /// <summary>
    /// Interaction logic for CustomMessageDecoderPage.xaml.
    /// </summary>
    public partial class CustomMessageDecoderPage : IWizardPage, IDataErrorInfo
    {
        private readonly ObservableCollection<IWizardPage> children = new ObservableCollection<IWizardPage>();

        private readonly ReadOnlyObservableCollection<IWizardPage> readonlyChildren;

        private string customFormat;

        private string error;

        private bool isValid;

        public CustomMessageDecoderPage()
        {
            InitializeComponent();
Download .txt
gitextract_gjrp28h9/

├── .gitattributes
├── .github/
│   └── dependabot.yml
├── .gitignore
├── CONTRIBUTING.md
├── CustomDictionary.xml
├── GitVersion.yml
├── LICENSE.md
├── README.md
├── Sentinel/
│   ├── .vscode/
│   │   ├── launch.json
│   │   └── tasks.json
│   ├── Classification/
│   │   ├── Classifier.cs
│   │   ├── ClassifyingService.cs
│   │   ├── Gui/
│   │   │   ├── AddClassifier.cs
│   │   │   ├── AddEditClassifier.cs
│   │   │   ├── AddEditClassifierWindow.xaml
│   │   │   ├── AddEditClassifierWindow.xaml.cs
│   │   │   ├── ClassificationsControl.xaml
│   │   │   ├── ClassificationsControl.xaml.cs
│   │   │   ├── EditClassifier.cs
│   │   │   └── RemoveClassifier.cs
│   │   └── Interfaces/
│   │       ├── IAddClassifyingService.cs
│   │       ├── IClassifier.cs
│   │       ├── IClassifyingService.cs
│   │       ├── IEditClassifyingService.cs
│   │       └── IRemoveClassifyingService.cs
│   ├── Controls/
│   │   ├── AboutWindow.xaml
│   │   ├── AboutWindow.xaml.cs
│   │   ├── ImageTypesControl.xaml
│   │   ├── ImageTypesControl.xaml.cs
│   │   ├── IntegerTextBox.cs
│   │   ├── LogActivityControl.xaml
│   │   ├── LogActivityControl.xaml.cs
│   │   ├── MainWindow.xaml
│   │   ├── MainWindow.xaml.cs
│   │   ├── PersistingSettings.cs
│   │   ├── PreferencesControl.xaml
│   │   ├── PreferencesControl.xaml.cs
│   │   ├── PreferencesWindow.xaml
│   │   ├── PreferencesWindow.xaml.cs
│   │   ├── RecentFileInfo.cs
│   │   └── WindowPlacementInfo.cs
│   ├── EventLogMonitor/
│   │   ├── CommandLineOptions.cs
│   │   ├── EventLogEntry.cs
│   │   └── Interfaces/
│   │       └── IEventLogEntry.cs
│   ├── Extractors/
│   │   ├── ExtractingService.cs
│   │   ├── Extractor.cs
│   │   ├── Gui/
│   │   │   ├── AddEditExtractor.cs
│   │   │   ├── AddEditExtractorWindow.xaml
│   │   │   ├── AddEditExtractorWindow.xaml.cs
│   │   │   ├── AddExtractor.cs
│   │   │   ├── EditExtractor.cs
│   │   │   ├── ExtractorsControl.xaml
│   │   │   ├── ExtractorsControl.xaml.cs
│   │   │   └── RemoveExtractor.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddExtractorService.cs
│   │   │   ├── IEditExtractorService.cs
│   │   │   ├── IExtractingService.cs
│   │   │   ├── IExtractor.cs
│   │   │   ├── IRemoveExtractorService.cs
│   │   │   └── ISearchExtractor.cs
│   │   └── SearchExtractor.cs
│   ├── FileMonitor/
│   │   ├── CustomMessageDecoderPage.xaml
│   │   ├── CustomMessageDecoderPage.xaml.cs
│   │   ├── FileMonitorProviderPage.xaml
│   │   ├── FileMonitorProviderPage.xaml.cs
│   │   ├── FileMonitoringProvider.cs
│   │   ├── FileMonitoringProviderSettings.cs
│   │   ├── IFileMonitoringProviderSettings.cs
│   │   ├── LogEntry.cs
│   │   ├── MessageFormatPage.xaml
│   │   ├── MessageFormatPage.xaml.cs
│   │   └── ProviderRegistrationInformation.cs
│   ├── Filters/
│   │   ├── Filter.cs
│   │   ├── FilteringService.cs
│   │   ├── Gui/
│   │   │   ├── AddEditFilter.cs
│   │   │   ├── AddEditFilterWindow.xaml
│   │   │   ├── AddEditFilterWindow.xaml.cs
│   │   │   ├── AddFilter.cs
│   │   │   ├── EditFilter.cs
│   │   │   ├── FiltersControl.xaml
│   │   │   ├── FiltersControl.xaml.cs
│   │   │   └── RemoveFilter.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddFilterService.cs
│   │   │   ├── IEditFilterService.cs
│   │   │   ├── IFilter.cs
│   │   │   ├── IFilteringService.cs
│   │   │   ├── IRemoveFilterService.cs
│   │   │   ├── ISearchFilter.cs
│   │   │   └── IStandardDebuggingFilter.cs
│   │   ├── SearchFilter.cs
│   │   └── StandardFilter.cs
│   ├── Highlighters/
│   │   ├── Gui/
│   │   │   ├── AddEditHighlighter.cs
│   │   │   ├── AddEditHighlighterWindow.xaml
│   │   │   ├── AddEditHighlighterWindow.xaml.cs
│   │   │   ├── AddNewHighlighterService.cs
│   │   │   ├── EditHighlighterService.cs
│   │   │   ├── HighlightersControl.xaml
│   │   │   ├── HighlightersControl.xaml.cs
│   │   │   └── RemoveHighlighterService.cs
│   │   ├── Highlighter.cs
│   │   ├── HighlighterConverter.cs
│   │   ├── HighlighterStyle.cs
│   │   ├── HighlightingSelector.cs
│   │   ├── HighlightingService.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddHighlighterService.cs
│   │   │   ├── IEditHighlighterService.cs
│   │   │   ├── IHighlighter.cs
│   │   │   ├── IHighlightingService.cs
│   │   │   ├── IRemoveHighlighterService.cs
│   │   │   ├── ISearchHighlighter.cs
│   │   │   └── IStandardDebuggingHighlighter.cs
│   │   ├── SearchHighlighter.cs
│   │   └── StandardHighlighter.cs
│   ├── Images/
│   │   ├── AddEditTypeImageViewModel.cs
│   │   ├── AddTypeImageService.cs
│   │   ├── Controls/
│   │   │   ├── AddImageWindow.xaml
│   │   │   └── AddImageWindow.xaml.cs
│   │   ├── EditTypeImageMapping.cs
│   │   ├── ImageQuality.cs
│   │   ├── ImageTypeRecord.cs
│   │   ├── Interfaces/
│   │   │   ├── IAddTypeImage.cs
│   │   │   ├── IEditTypeImage.cs
│   │   │   ├── IRemoveTypeImage.cs
│   │   │   ├── ITypeImageService.cs
│   │   │   └── ImageOptions.cs
│   │   ├── RemoveTypeImageMapping.cs
│   │   └── TypeToImageService.cs
│   ├── Interfaces/
│   │   ├── CaseInsensitiveComparer.cs
│   │   ├── CodeContracts/
│   │   │   ├── ThrowIfNull.cs
│   │   │   ├── ThrowIfNullOrWhitespace.cs
│   │   │   └── ValidatedNotNullAttribute.cs
│   │   ├── CollectionChangeHelper.cs
│   │   ├── EnumerableExtensions.cs
│   │   ├── IDefaultInitialisation.cs
│   │   ├── IHighlighterStyle.cs
│   │   ├── ILogEntry.cs
│   │   ├── ILogger.cs
│   │   ├── IUserPreferences.cs
│   │   ├── LinqHelpers.cs
│   │   ├── LogEntryFields.cs
│   │   ├── MatchMode.cs
│   │   └── Providers/
│   │       ├── ILogProvider.cs
│   │       ├── INetworkProvider.cs
│   │       ├── IProviderInfo.cs
│   │       ├── IProviderRegistrationRecord.cs
│   │       └── IProviderSettings.cs
│   ├── Log4Net/
│   │   ├── ConfigurationPage.xaml
│   │   ├── ConfigurationPage.xaml.cs
│   │   ├── IUdpAppenderListenerSettings.cs
│   │   ├── Log4NetProvider.cs
│   │   ├── LogEntry.cs
│   │   ├── ProviderRegistrationInformation.cs
│   │   ├── UdpAppenderSettings.cs
│   │   └── XElementHelpers.cs
│   ├── Logger/
│   │   ├── ILogViewerDetails.cs
│   │   ├── IUdpLogViewer.cs
│   │   └── LogWriter.cs
│   ├── Logs/
│   │   ├── Gui/
│   │   │   ├── AddNewLoggerWelcomePage.xaml
│   │   │   ├── AddNewLoggerWelcomePage.xaml.cs
│   │   │   ├── NewLoggerSettings.cs
│   │   │   ├── NewLoggerSummaryPage.xaml
│   │   │   ├── NewLoggerSummaryPage.xaml.cs
│   │   │   ├── NewLoggerWizard.cs
│   │   │   ├── ProvidersPage.xaml
│   │   │   ├── ProvidersPage.xaml.cs
│   │   │   ├── SetLoggerNamePage.xaml
│   │   │   ├── SetLoggerNamePage.xaml.cs
│   │   │   ├── ViewSelectionPage.xaml
│   │   │   └── ViewSelectionPage.xaml.cs
│   │   ├── Interfaces/
│   │   │   ├── ILogFileExporter.cs
│   │   │   └── ILogManager.cs
│   │   ├── Log.cs
│   │   ├── LogFileExporter.cs
│   │   └── LogManager.cs
│   ├── MSBuild/
│   │   ├── ConfigurationPage.xaml
│   │   ├── ConfigurationPage.xaml.cs
│   │   ├── IMSBuildListenerSettings.cs
│   │   ├── LogEntry.cs
│   │   ├── MSBuildListenerSettings.cs
│   │   ├── MSBuildProvider.cs
│   │   ├── ProviderInfo.cs
│   │   └── ProviderRegistrationInformation.cs
│   ├── MainApplication.xaml
│   ├── MainApplication.xaml.cs
│   ├── NLog/
│   │   ├── INLogAppenderSettings.cs
│   │   ├── LogEntry.cs
│   │   ├── NLogViewerProvider.cs
│   │   ├── NetworkClientWrapper.cs
│   │   ├── NetworkConfigurationPage.xaml
│   │   ├── NetworkConfigurationPage.xaml.cs
│   │   ├── NetworkProtocol.cs
│   │   ├── NetworkSettings.cs
│   │   ├── ProviderInfo.cs
│   │   ├── ProviderRegistrationInformation.cs
│   │   └── ProviderSettings.cs
│   ├── Preferences/
│   │   └── UserPreferences.cs
│   ├── Properties/
│   │   ├── AssemblyInfo.cs
│   │   ├── Resources.Designer.cs
│   │   ├── Resources.resx
│   │   ├── Settings.Designer.cs
│   │   ├── Settings.settings
│   │   └── app.manifest
│   ├── Providers/
│   │   ├── Interfaces/
│   │   │   ├── INewProviderWizard.cs
│   │   │   ├── IProviderManager.cs
│   │   │   └── PendingProviderRecord.cs
│   │   ├── NewProviderWizard.cs
│   │   ├── ProviderInfo.cs
│   │   ├── ProviderManager.cs
│   │   ├── ProviderRegistrationRecord.cs
│   │   ├── ProviderSettings.cs
│   │   ├── SelectProviderPage.xaml
│   │   └── SelectProviderPage.xaml.cs
│   ├── Sentinel.csproj
│   ├── Services/
│   │   ├── AttributeHelper.cs
│   │   ├── DictionaryHelper.cs
│   │   ├── Interfaces/
│   │   │   └── ISessionManager.cs
│   │   ├── ServiceLocator.cs
│   │   └── SessionManager.cs
│   ├── StartUp/
│   │   ├── IOptions.cs
│   │   ├── Log4NetOptions.cs
│   │   └── NLogOptions.cs
│   ├── Support/
│   │   ├── Converters/
│   │   │   ├── BooleanToWidthConverter.cs
│   │   │   ├── CollapseIfNullConverter.cs
│   │   │   ├── DatePreferenceConverter.cs
│   │   │   ├── ImageLibraryConverter.cs
│   │   │   ├── LongPathToShortPathConverter.cs
│   │   │   ├── MessageHasExceptionMetadataConverter.cs
│   │   │   ├── MetaDataConverter.cs
│   │   │   ├── MetaDataParameterConverter.cs
│   │   │   ├── TimePreferenceConverter.cs
│   │   │   ├── TimeSinceDateTimeConverter.cs
│   │   │   ├── TypeToImageConverter.cs
│   │   │   ├── TypeToLargeImageConverter.cs
│   │   │   ├── TypeToMediumImageConverter.cs
│   │   │   └── TypeToSmallImageConverter.cs
│   │   ├── GridViewSort.cs
│   │   ├── JsonHelper.cs
│   │   ├── ScrollingHelper.cs
│   │   └── Wpf/
│   │       ├── DataBoundToolbar.cs
│   │       ├── FixedWidthColumn.cs
│   │       ├── ObservableDictionary.cs
│   │       └── ThemeInfo.cs
│   ├── Views/
│   │   ├── Gui/
│   │   │   ├── LogMessages.cs
│   │   │   ├── LogMessagesControl.xaml
│   │   │   ├── LogMessagesControl.xaml.cs
│   │   │   ├── LogViewerToolbarButton.cs
│   │   │   ├── MultipleViewFrame.xaml
│   │   │   ├── MultipleViewFrame.xaml.cs
│   │   │   └── ViewInformation.cs
│   │   ├── Heartbeat/
│   │   │   ├── HeartbeatControl.xaml
│   │   │   ├── HeartbeatControl.xaml.cs
│   │   │   ├── MessageHeatbeat.cs
│   │   │   └── ViewInformation.cs
│   │   ├── Interfaces/
│   │   │   ├── ILogViewer.cs
│   │   │   ├── ILogViewerToolbarButton.cs
│   │   │   ├── IViewInformation.cs
│   │   │   ├── IViewManager.cs
│   │   │   └── IWindowFrame.cs
│   │   └── ViewManager.cs
│   └── WpfExtras/
│       ├── Converters/
│       │   ├── BooleanInvertingValueConverter.cs
│       │   ├── BooleanToDisabledConverter.cs
│       │   ├── CollapseIfFalseConverter.cs
│       │   ├── CollapseIfZeroConverter.cs
│       │   ├── ColourConverter.cs
│       │   ├── VisibilityToCollapsedConverter.cs
│       │   └── VisibilityToHiddenConverter.cs
│       ├── DelegateCommand.cs
│       ├── EstablishPossibleNavigation.cs
│       ├── IWizardPage.cs
│       ├── PageChange.cs
│       ├── PageNavigationTreeEntry.cs
│       ├── ViewModelBase.cs
│       ├── Wizard.xaml
│       └── Wizard.xaml.cs
├── Sentinel.sln
├── Sentinel.sln.DotSettings
├── Settings.StyleCop
├── SharedAssemblyInfo.cs
├── StyleCop/
│   └── StyleCopRules.ruleset
└── docs/
    └── Home.md
Download .txt
SYMBOL INDEX (873 symbols across 227 files)

FILE: Sentinel/Classification/Classifier.cs
  class Classifier (line 12) | [DataContract]
    method Classifier (line 29) | public Classifier()
    method Classifier (line 45) | public Classifier(string name, bool enabled, LogEntryFields field, Mat...
    method Classify (line 193) | public ILogEntry Classify(ILogEntry logEntry)
    method IsMatch (line 206) | public bool IsMatch(ILogEntry logEntry)

FILE: Sentinel/Classification/ClassifyingService.cs
  class ClassifyingService (line 22) | [DataContract]
    method ClassifyingService (line 39) | public ClassifyingService()
    method Initialise (line 116) | public void Initialise()
    method Classify (line 123) | public ILogEntry Classify(ILogEntry entry)
    method AddClassifier (line 138) | private void AddClassifier(object obj)
    method EditClassifier (line 153) | private void EditClassifier(object obj)
    method MoveItemDown (line 172) | private void MoveItemDown(object obj)
    method MoveItemUp (line 206) | private void MoveItemUp(object obj)
    method RemoveClassifier (line 233) | private void RemoveClassifier(object obj)
    method CustomClassifierPropertyChanged (line 239) | private void CustomClassifierPropertyChanged(object sender, PropertyCh...

FILE: Sentinel/Classification/Gui/AddClassifier.cs
  class AddClassifier (line 8) | public class AddClassifier : IAddClassifyingService
    method Add (line 10) | public void Add()
    method Construct (line 31) | private static Classifier Construct(AddEditClassifier data)

FILE: Sentinel/Classification/Gui/AddEditClassifier.cs
  class AddEditClassifier (line 10) | public class AddEditClassifier : ViewModelBase
    method AddEditClassifier (line 24) | public AddEditClassifier(Window window, bool editMode)
    method AcceptDialog (line 121) | private void AcceptDialog(object obj)
    method RejectDialog (line 127) | private void RejectDialog(object obj)
    method Validates (line 133) | private bool Validates(object obj)

FILE: Sentinel/Classification/Gui/AddEditClassifierWindow.xaml.cs
  class AddEditClassifierWindow (line 6) | public partial class AddEditClassifierWindow
    method AddEditClassifierWindow (line 8) | public AddEditClassifierWindow()

FILE: Sentinel/Classification/Gui/ClassificationsControl.xaml.cs
  class ClassificationsControl (line 11) | public partial class ClassificationsControl : UserControl
    method ClassificationsControl (line 13) | public ClassificationsControl()

FILE: Sentinel/Classification/Gui/EditClassifier.cs
  class EditClassifier (line 8) | public class EditClassifier : IEditClassifyingService
    method Edit (line 10) | public void Edit(IClassifier classifier)

FILE: Sentinel/Classification/Gui/RemoveClassifier.cs
  class RemoveClassifier (line 8) | public class RemoveClassifier : IRemoveClassifyingService
    method Remove (line 10) | public void Remove(IClassifier classifier)

FILE: Sentinel/Classification/Interfaces/IAddClassifyingService.cs
  type IAddClassifyingService (line 3) | public interface IAddClassifyingService
    method Add (line 5) | void Add();

FILE: Sentinel/Classification/Interfaces/IClassifier.cs
  type IClassifier (line 7) | public interface IClassifier
    method IsMatch (line 30) | bool IsMatch(ILogEntry entry);
    method Classify (line 32) | ILogEntry Classify(ILogEntry entry);

FILE: Sentinel/Classification/Interfaces/IClassifyingService.cs
  type IClassifyingService (line 9) | public interface IClassifyingService<T>
    method Classify (line 26) | ILogEntry Classify(ILogEntry entry);

FILE: Sentinel/Classification/Interfaces/IEditClassifyingService.cs
  type IEditClassifyingService (line 3) | public interface IEditClassifyingService
    method Edit (line 5) | void Edit(IClassifier classifier);

FILE: Sentinel/Classification/Interfaces/IRemoveClassifyingService.cs
  type IRemoveClassifyingService (line 3) | public interface IRemoveClassifyingService
    method Remove (line 5) | void Remove(IClassifier classifier);

FILE: Sentinel/Controls/AboutWindow.xaml.cs
  class AboutWindow (line 11) | public partial class AboutWindow
    method AboutWindow (line 13) | public AboutWindow(Window parent)

FILE: Sentinel/Controls/ImageTypesControl.xaml.cs
  class ImageTypesControl (line 11) | public partial class ImageTypesControl : UserControl
    method ImageTypesControl (line 13) | public ImageTypesControl()

FILE: Sentinel/Controls/IntegerTextBox.cs
  class IntegerTextBox (line 7) | public class IntegerTextBox : TextBox
    method OnPreviewTextInput (line 9) | protected override void OnPreviewTextInput(TextCompositionEventArgs e)

FILE: Sentinel/Controls/LogActivityControl.xaml.cs
  class LogActivityControl (line 9) | public partial class LogActivityControl
    method LogActivityControl (line 11) | public LogActivityControl()

FILE: Sentinel/Controls/MainWindow.xaml.cs
  class MainWindow (line 42) | public partial class MainWindow
    method MainWindow (line 56) | public MainWindow()
    method ValidateScreenPosition (line 139) | private static WindowPlacementInfo ValidateScreenPosition(WindowPlacem...
    method ShowPreferencesAction (line 164) | private void ShowPreferencesAction(object obj)
    method ExportLogsAction (line 170) | private void ExportLogsAction(object obj)
    method SaveSessionAction (line 216) | private void SaveSessionAction(object obj)
    method AddToRecentFiles (line 236) | private void AddToRecentFiles(string fileName)
    method NewSessionAction (line 254) | private void NewSessionAction(object obj)
    method LoadSessionAction (line 293) | private void LoadSessionAction(object obj)
    method AddNewListenerAction (line 376) | private void AddNewListenerAction(object obj)
    method OnLoaded (line 400) | private void OnLoaded(object sender, RoutedEventArgs e)
    method ProcessCommandLine (line 446) | private void ProcessCommandLine(IEnumerable<string> commandLine)
    method CreateDefaultLog4NetListener (line 513) | private void CreateDefaultLog4NetListener(Log4NetOptions log4NetOption...
    method CreateDefaultNLogListener (line 537) | private void CreateDefaultNLogListener(NLogOptions verbOptions, ISessi...
    method RestoreWindowPosition (line 560) | private void RestoreWindowPosition(WindowPlacementInfo wp)
    method PreferencesChanged (line 587) | private void PreferencesChanged(object sender, PropertyChangedEventArg...
    method ViewManagerChanged (line 607) | private void ViewManagerChanged(object sender, NotifyCollectionChanged...
    method OnClosed (line 615) | private void OnClosed(object sender, CancelEventArgs e)
    method RetainOnlyStandardFilters (line 634) | private void RetainOnlyStandardFilters(object sender, FilterEventArgs e)
    method ExcludeStandardFilters (line 641) | private void ExcludeStandardFilters(object sender, FilterEventArgs e)
    method RetainOnlyStandardHighlighters (line 648) | private void RetainOnlyStandardHighlighters(object sender, FilterEvent...
    method ExcludeStandardHighlighters (line 655) | private void ExcludeStandardHighlighters(object sender, FilterEventArg...
    method SearchToggleButtonChecked (line 662) | private void SearchToggleButtonChecked(object sender, RoutedEventArgs e)
    method BindSearchToSearchExtractor (line 683) | private void BindSearchToSearchExtractor()
    method CreateBinding (line 693) | private Binding CreateBinding(string path, object source)
    method BindSearchToSearchFilter (line 703) | private void BindSearchToSearchFilter()
    method BindSearchToSearchHighlighter (line 712) | private void BindSearchToSearchHighlighter()
    method RemoveBindingReferences (line 721) | private void RemoveBindingReferences()
    method BindViewToViewModel (line 732) | private void BindViewToViewModel()
    method BindToSearchElements (line 854) | private void BindToSearchElements()
    method GetRecentlyOpenedFiles (line 875) | private void GetRecentlyOpenedFiles()

FILE: Sentinel/Controls/PersistingSettings.cs
  class PersistingSettings (line 9) | [DataContract]
    method Load (line 18) | internal static PersistingSettings Load(string fileName)
    method Save (line 52) | internal static void Save(string fileName, WindowPlacementInfo placeme...
    method DeserializeFromV1 (line 75) | private static PersistingSettings DeserializeFromV1(string fileContents)
    method DeserializeFromV2 (line 96) | private static PersistingSettings DeserializeFromV2(string fileContents)

FILE: Sentinel/Controls/PreferencesControl.xaml.cs
  class PreferencesControl (line 6) | public partial class PreferencesControl
    method PreferencesControl (line 8) | public PreferencesControl()

FILE: Sentinel/Controls/PreferencesWindow.xaml.cs
  class PreferencesWindow (line 11) | public partial class PreferencesWindow
    method PreferencesWindow (line 13) | public PreferencesWindow()
    method PreferencesWindow (line 18) | public PreferencesWindow(int selectedTabIndex)
    method WindowClosed (line 32) | private void WindowClosed(object sender, EventArgs e)

FILE: Sentinel/Controls/RecentFileInfo.cs
  class RecentFileInfo (line 6) | [DataContract]

FILE: Sentinel/Controls/WindowPlacementInfo.cs
  class WindowPlacementInfo (line 6) | [DataContract]

FILE: Sentinel/EventLogMonitor/CommandLineOptions.cs
  class CommandLineOptions (line 5) | public class CommandLineOptions

FILE: Sentinel/EventLogMonitor/EventLogEntry.cs
  class EventLogEntry (line 10) | internal class EventLogEntry : IEventLogEntry
    method EventLogEntry (line 12) | public EventLogEntry(System.Diagnostics.EventLogEntry entry)
    method ToString (line 36) | public override string ToString()

FILE: Sentinel/EventLogMonitor/Interfaces/IEventLogEntry.cs
  type IEventLogEntry (line 8) | public interface IEventLogEntry

FILE: Sentinel/Extractors/ExtractingService.cs
  class ExtractingService (line 17) | [DataContract]
    method ExtractingService (line 31) | public ExtractingService()
    method Initialise (line 92) | public void Initialise()
    method IsFiltered (line 97) | public bool IsFiltered(ILogEntry entry)
    method AddExtractor (line 103) | private void AddExtractor(object obj)
    method CustomExtractorPropertyChanged (line 108) | private void CustomExtractorPropertyChanged(object sender, PropertyCha...
    method EditExtractor (line 120) | private void EditExtractor(object obj)
    method RemoveExtractor (line 129) | private void RemoveExtractor(object obj)

FILE: Sentinel/Extractors/Extractor.cs
  class Extractor (line 13) | [DataContract]
    method Extractor (line 29) | public Extractor()
    method Extractor (line 40) | public Extractor(string name, LogEntryFields field, string pattern)
    method IsMatch (line 154) | public bool IsMatch(ILogEntry logEntry)
    method ToString (line 213) | public override string ToString()

FILE: Sentinel/Extractors/Gui/AddEditExtractor.cs
  class AddEditExtractor (line 10) | public class AddEditExtractor : ViewModelBase
    method AddEditExtractor (line 22) | public AddEditExtractor(Window window, bool editMode)
    method AcceptDialog (line 100) | private void AcceptDialog(object obj)
    method RejectDialog (line 106) | private void RejectDialog(object obj)
    method Validates (line 112) | private bool Validates(object obj)

FILE: Sentinel/Extractors/Gui/AddEditExtractorWindow.xaml.cs
  class AddEditExtractorWindow (line 8) | public partial class AddEditExtractorWindow : Window
    method AddEditExtractorWindow (line 10) | public AddEditExtractorWindow()

FILE: Sentinel/Extractors/Gui/AddExtractor.cs
  class AddExtractor (line 8) | public class AddExtractor : IAddExtractorService
    method Add (line 10) | public void Add()
    method Construct (line 35) | private static Extractor Construct(AddEditExtractor data)

FILE: Sentinel/Extractors/Gui/EditExtractor.cs
  class EditExtractor (line 8) | public class EditExtractor : IEditExtractorService
    method Edit (line 10) | public void Edit(IExtractor extractor)

FILE: Sentinel/Extractors/Gui/ExtractorsControl.xaml.cs
  class ExtractorsControl (line 11) | public partial class ExtractorsControl : UserControl
    method ExtractorsControl (line 13) | public ExtractorsControl()

FILE: Sentinel/Extractors/Gui/RemoveExtractor.cs
  class RemoveExtractor (line 8) | public class RemoveExtractor
    method Remove (line 11) | public void Remove(IExtractor extractor)

FILE: Sentinel/Extractors/Interfaces/IAddExtractorService.cs
  type IAddExtractorService (line 3) | public interface IAddExtractorService
    method Add (line 5) | void Add();

FILE: Sentinel/Extractors/Interfaces/IEditExtractorService.cs
  type IEditExtractorService (line 3) | public interface IEditExtractorService
    method Edit (line 5) | void Edit(IExtractor extractor);

FILE: Sentinel/Extractors/Interfaces/IExtractingService.cs
  type IExtractingService (line 8) | public interface IExtractingService<T>
    method IsFiltered (line 16) | bool IsFiltered(ILogEntry entry);

FILE: Sentinel/Extractors/Interfaces/IExtractor.cs
  type IExtractor (line 7) | public interface IExtractor
    method IsMatch (line 30) | bool IsMatch(ILogEntry entry);

FILE: Sentinel/Extractors/Interfaces/IRemoveExtractorService.cs
  type IRemoveExtractorService (line 3) | public interface IRemoveExtractorService
    method Remove (line 5) | void Remove(IExtractor extractor);

FILE: Sentinel/Extractors/Interfaces/ISearchExtractor.cs
  type ISearchExtractor (line 3) | public interface ISearchExtractor : IExtractor

FILE: Sentinel/Extractors/SearchExtractor.cs
  class SearchExtractor (line 8) | [DataContract]
    method Initialise (line 12) | public void Initialise()

FILE: Sentinel/FileMonitor/CustomMessageDecoderPage.xaml.cs
  class CustomMessageDecoderPage (line 15) | public partial class CustomMessageDecoderPage : IWizardPage, IDataErrorInfo
    method CustomMessageDecoderPage (line 27) | public CustomMessageDecoderPage()
    method Save (line 140) | public object Save(object saveData)
    method AddChild (line 152) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 158) | public void RemoveChild(IWizardPage item)
    method OnPropertyChanged (line 164) | protected virtual void OnPropertyChanged(string propertyName)
    method ContainsKeyFields (line 174) | private static bool ContainsKeyFields(string pattern)
    method PropertyChangedHandler (line 186) | private void PropertyChangedHandler(object sender, PropertyChangedEven...
    method OnLoaded (line 194) | private void OnLoaded(object sender, RoutedEventArgs e)

FILE: Sentinel/FileMonitor/FileMonitorProviderPage.xaml.cs
  class FileMonitorProviderPage (line 22) | public partial class FileMonitorProviderPage : IWizardPage, IDataErrorInfo
    method FileMonitorProviderPage (line 38) | public FileMonitorProviderPage()
    method Save (line 172) | public object Save(object saveData)
    method AddChild (line 198) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 204) | public void RemoveChild(IWizardPage item)
    method OnPropertyChanged (line 210) | protected virtual void OnPropertyChanged(string propertyName)
    method BrowseForFile (line 220) | private void BrowseForFile(object obj)
    method OnLoaded (line 239) | private void OnLoaded(object sender, RoutedEventArgs e)
    method PropertyChangedHandler (line 244) | private void PropertyChangedHandler(object sender, PropertyChangedEven...
    method CheckSuppliedFilenameIsValid (line 265) | private bool CheckSuppliedFilenameIsValid(string fileNameToValidate, o...

FILE: Sentinel/FileMonitor/FileMonitoringProvider.cs
  class FileMonitoringProvider (line 20) | public class FileMonitoringProvider : ILogProvider, IDisposable
    method FileMonitoringProvider (line 38) | [System.Diagnostics.CodeAnalysis.SuppressMessage(
    method Dispose (line 93) | public void Dispose()
    method Start (line 99) | public void Start()
    method Close (line 113) | public void Close()
    method Pause (line 119) | public void Pause()
    method Dispose (line 128) | protected virtual void Dispose(bool disposing)
    method PurgeWorkerDoWork (line 136) | private void PurgeWorkerDoWork(object sender, DoWorkEventArgs e)
    method PredetermineGroupNames (line 154) | private void PredetermineGroupNames(string messageDecoder)
    method DoWork (line 178) | private void DoWork(object sender, DoWorkEventArgs e)
    method DecodeAndQueueMessage (line 254) | private void DecodeAndQueueMessage(string message)
    method DoWorkComplete (line 313) | private void DoWorkComplete(object sender, RunWorkerCompletedEventArgs e)
    class ProviderInfo (line 318) | private class ProviderInfo : IProviderInfo

FILE: Sentinel/FileMonitor/FileMonitoringProviderSettings.cs
  class FileMonitoringProviderSettings (line 7) | public class FileMonitoringProviderSettings : IFileMonitoringProviderSet...
    method FileMonitoringProviderSettings (line 9) | public FileMonitoringProviderSettings(
    method Update (line 41) | public void Update(string fileName, int refreshPeriod, bool loadExisti...

FILE: Sentinel/FileMonitor/IFileMonitoringProviderSettings.cs
  type IFileMonitoringProviderSettings (line 5) | public interface IFileMonitoringProviderSettings : IProviderSettings
    method Update (line 15) | void Update(string fileName, int refresh, bool loadExisting);

FILE: Sentinel/FileMonitor/LogEntry.cs
  class LogEntry (line 8) | internal class LogEntry : ILogEntry

FILE: Sentinel/FileMonitor/MessageFormatPage.xaml.cs
  class MessageFormatPage (line 16) | public partial class MessageFormatPage : IWizardPage
    method MessageFormatPage (line 28) | public MessageFormatPage()
    method AddChild (line 87) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 93) | public void RemoveChild(IWizardPage item)
    method Save (line 99) | public object Save(object saveData)
    method OnPropertyChanged (line 115) | protected virtual void OnPropertyChanged(string propertyName)
    method GetDecoder (line 122) | private string GetDecoder()
    method PropertyChangedHandler (line 133) | private void PropertyChangedHandler(object sender, PropertyChangedEven...
    method OnLoaded (line 164) | private void OnLoaded(object sender, RoutedEventArgs e)

FILE: Sentinel/FileMonitor/ProviderRegistrationInformation.cs
  class ProviderRegistrationInformation (line 7) | public class ProviderRegistrationInformation : IProviderRegistrationRecord
    method ProviderRegistrationInformation (line 9) | public ProviderRegistrationInformation(IProviderInfo providerInfo)

FILE: Sentinel/Filters/Filter.cs
  class Filter (line 12) | [DataContract]
    method Filter (line 30) | public Filter()
    method Filter (line 46) | public Filter(string name, LogEntryFields field, string pattern)
    method IsMatch (line 177) | public bool IsMatch(ILogEntry logEntry)
    method ToString (line 235) | public override string ToString()

FILE: Sentinel/Filters/FilteringService.cs
  class FilteringService (line 17) | [DataContract]
    method FilteringService (line 31) | public FilteringService()
    method Initialise (line 88) | public void Initialise()
    method IsFiltered (line 99) | public bool IsFiltered(ILogEntry entry)
    method AddFilter (line 105) | private void AddFilter(object obj)
    method CustomFilterPropertyChanged (line 110) | private void CustomFilterPropertyChanged(object sender, PropertyChange...
    method EditFilter (line 122) | private void EditFilter(object obj)
    method RemoveFilter (line 131) | private void RemoveFilter(object obj)

FILE: Sentinel/Filters/Gui/AddEditFilter.cs
  class AddEditFilter (line 10) | public class AddEditFilter : ViewModelBase
    method AddEditFilter (line 22) | public AddEditFilter(Window window, bool editMode)
    method AcceptDialog (line 100) | private void AcceptDialog(object obj)
    method RejectDialog (line 106) | private void RejectDialog(object obj)
    method Validates (line 112) | private bool Validates(object obj)

FILE: Sentinel/Filters/Gui/AddEditFilterWindow.xaml.cs
  class AddEditFilterWindow (line 8) | public partial class AddEditFilterWindow : Window
    method AddEditFilterWindow (line 10) | public AddEditFilterWindow()

FILE: Sentinel/Filters/Gui/AddFilter.cs
  class AddFilter (line 8) | public class AddFilter : IAddFilterService
    method Add (line 10) | public void Add()
    method Construct (line 30) | private static Filter Construct(AddEditFilter data)

FILE: Sentinel/Filters/Gui/EditFilter.cs
  class EditFilter (line 8) | public class EditFilter : IEditFilterService
    method Edit (line 10) | public void Edit(IFilter filter)

FILE: Sentinel/Filters/Gui/FiltersControl.xaml.cs
  class FiltersControl (line 11) | public partial class FiltersControl : UserControl
    method FiltersControl (line 13) | public FiltersControl()

FILE: Sentinel/Filters/Gui/RemoveFilter.cs
  class RemoveFilter (line 8) | public class RemoveFilter : IRemoveFilterService
    method Remove (line 10) | public void Remove(IFilter filter)

FILE: Sentinel/Filters/Interfaces/IAddFilterService.cs
  type IAddFilterService (line 3) | public interface IAddFilterService
    method Add (line 5) | void Add();

FILE: Sentinel/Filters/Interfaces/IEditFilterService.cs
  type IEditFilterService (line 3) | public interface IEditFilterService
    method Edit (line 5) | void Edit(IFilter filter);

FILE: Sentinel/Filters/Interfaces/IFilter.cs
  type IFilter (line 7) | public interface IFilter
    method IsMatch (line 30) | bool IsMatch(ILogEntry entry);

FILE: Sentinel/Filters/Interfaces/IFilteringService.cs
  type IFilteringService (line 8) | public interface IFilteringService<T>
    method IsFiltered (line 15) | bool IsFiltered(ILogEntry entry);

FILE: Sentinel/Filters/Interfaces/IRemoveFilterService.cs
  type IRemoveFilterService (line 3) | public interface IRemoveFilterService
    method Remove (line 5) | void Remove(IFilter filter);

FILE: Sentinel/Filters/Interfaces/ISearchFilter.cs
  type ISearchFilter (line 3) | public interface ISearchFilter : IFilter

FILE: Sentinel/Filters/Interfaces/IStandardDebuggingFilter.cs
  type IStandardDebuggingFilter (line 3) | public interface IStandardDebuggingFilter : IFilter

FILE: Sentinel/Filters/SearchFilter.cs
  class SearchFilter (line 8) | [DataContract]
    method Initialise (line 11) | public void Initialise()

FILE: Sentinel/Filters/StandardFilter.cs
  class StandardFilter (line 6) | public class StandardFilter : Filter, IStandardDebuggingFilter
    method StandardFilter (line 8) | public StandardFilter(string name, LogEntryFields field, string pattern)

FILE: Sentinel/Highlighters/Gui/AddEditHighlighter.cs
  class AddEditHighlighter (line 15) | public class AddEditHighlighter : ViewModelBase
    method AddEditHighlighter (line 39) | public AddEditHighlighter(Window window, bool editMode)
    method GetColours (line 244) | private static Dictionary<string, Color> GetColours()
    method AcceptDialog (line 259) | private void AcceptDialog(object obj)
    method CloseColourCheck (line 265) | private void CloseColourCheck(object sender, PropertyChangedEventArgs e)
    method RejectDialog (line 278) | private void RejectDialog(object obj)
    method Validates (line 284) | private bool Validates(object obj)

FILE: Sentinel/Highlighters/Gui/AddEditHighlighterWindow.xaml.cs
  class AddEditHighlighterWindow (line 8) | public partial class AddEditHighlighterWindow : Window
    method AddEditHighlighterWindow (line 10) | public AddEditHighlighterWindow()

FILE: Sentinel/Highlighters/Gui/AddNewHighlighterService.cs
  class AddNewHighlighterService (line 9) | public class AddNewHighlighterService : IAddHighlighterService
    method Add (line 11) | public void Add()
    method Construct (line 31) | public Highlighter Construct(AddEditHighlighter data)

FILE: Sentinel/Highlighters/Gui/EditHighlighterService.cs
  class EditHighlighterService (line 10) | public class EditHighlighterService : IEditHighlighterService
    method Edit (line 12) | public void Edit(IHighlighter highlighter)

FILE: Sentinel/Highlighters/Gui/HighlightersControl.xaml.cs
  class HighlightersControl (line 11) | public partial class HighlightersControl : UserControl
    method HighlightersControl (line 13) | public HighlightersControl()

FILE: Sentinel/Highlighters/Gui/RemoveHighlighterService.cs
  class RemoveHighlighterService (line 8) | public class RemoveHighlighterService : IRemoveHighlighterService
    method Remove (line 10) | public void Remove(IHighlighter highlighter)

FILE: Sentinel/Highlighters/Highlighter.cs
  class Highlighter (line 12) | [DataContract]
    method Highlighter (line 29) | public Highlighter()
    method Highlighter (line 48) | protected Highlighter(string name, bool enabled, LogEntryFields field,...
    method IsMatch (line 196) | public bool IsMatch(ILogEntry logEntry)

FILE: Sentinel/Highlighters/HighlighterConverter.cs
  class HighlighterConverter (line 10) | public class HighlighterConverter : IValueConverter
    method HighlighterConverter (line 14) | public HighlighterConverter(IHighlighter highlighter)
    method Convert (line 21) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 40) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Highlighters/HighlighterStyle.cs
  class HighlighterStyle (line 12) | [DataContract]

FILE: Sentinel/Highlighters/HighlightingSelector.cs
  class HighlightingSelector (line 24) | public class HighlightingSelector : StyleSelector
    method HighlightingSelector (line 32) | public HighlightingSelector(Action<object, MouseButtonEventArgs> messa...
    method SelectStyle (line 156) | public override Style SelectStyle(object item, DependencyObject contai...
    method SetStyleSpacing (line 182) | private static void SetStyleSpacing(Style style)
    method RegisterDoubleClickEvent (line 196) | private void RegisterDoubleClickEvent(Style style, Action<object, Mous...

FILE: Sentinel/Highlighters/HighlightingService.cs
  class HighlightingService (line 17) | [DataContract]
    method HighlightingService (line 28) | public HighlightingService()
    method IsHighlighted (line 87) | public IHighlighterStyle IsHighlighted(ILogEntry logEntry)
    method Initialise (line 92) | public void Initialise()
    method AddHighlighter (line 146) | private void AddHighlighter(object obj)
    method CustomHighlighterPropertyChanged (line 152) | private void CustomHighlighterPropertyChanged(object sender, PropertyC...
    method EditHighlighter (line 164) | private void EditHighlighter(object obj)
    method MoveItemDown (line 174) | private void MoveItemDown(object obj)
    method MoveItemUp (line 202) | private void MoveItemUp(object obj)
    method RemoveHighlighter (line 226) | private void RemoveHighlighter(object obj)

FILE: Sentinel/Highlighters/Interfaces/IAddHighlighterService.cs
  type IAddHighlighterService (line 3) | public interface IAddHighlighterService
    method Add (line 5) | void Add();

FILE: Sentinel/Highlighters/Interfaces/IEditHighlighterService.cs
  type IEditHighlighterService (line 3) | public interface IEditHighlighterService
    method Edit (line 5) | void Edit(IHighlighter highlighter);

FILE: Sentinel/Highlighters/Interfaces/IHighlighter.cs
  type IHighlighter (line 7) | public interface IHighlighter
    method IsMatch (line 30) | bool IsMatch(ILogEntry logEntry);

FILE: Sentinel/Highlighters/Interfaces/IHighlightingService.cs
  type IHighlightingService (line 8) | public interface IHighlightingService<T>
    method IsHighlighted (line 25) | IHighlighterStyle IsHighlighted(ILogEntry entry);

FILE: Sentinel/Highlighters/Interfaces/IRemoveHighlighterService.cs
  type IRemoveHighlighterService (line 3) | public interface IRemoveHighlighterService
    method Remove (line 5) | void Remove(IHighlighter highlighter);

FILE: Sentinel/Highlighters/Interfaces/ISearchHighlighter.cs
  type ISearchHighlighter (line 7) | public interface ISearchHighlighter

FILE: Sentinel/Highlighters/Interfaces/IStandardDebuggingHighlighter.cs
  type IStandardDebuggingHighlighter (line 3) | public interface IStandardDebuggingHighlighter : IHighlighter

FILE: Sentinel/Highlighters/SearchHighlighter.cs
  class SearchHighlighter (line 13) | [DataContract]
    method Initialise (line 85) | public void Initialise()

FILE: Sentinel/Highlighters/StandardHighlighter.cs
  class StandardHighlighter (line 6) | public class StandardHighlighter : Highlighter, IStandardDebuggingHighli...
    method StandardHighlighter (line 8) | public StandardHighlighter(string name, bool enabled, LogEntryFields f...

FILE: Sentinel/Images/AddEditTypeImageViewModel.cs
  class AddEditTypeImageViewModel (line 14) | public class AddEditTypeImageViewModel
    method AddEditTypeImageViewModel (line 81) | public AddEditTypeImageViewModel(Window window, ITypeImageService imag...
    type ImageError (line 115) | private enum ImageError
    type TypeError (line 146) | private enum TypeError
    method BrowseForImageFiles (line 348) | private void BrowseForImageFiles(object obj)
    method LoadImageFromFileName (line 374) | private void LoadImageFromFileName(string fileName)
    method CloseDialog (line 412) | private void CloseDialog(bool dialogResult)
    method UpdateErrorMessage (line 418) | private void UpdateErrorMessage(bool imageChangedMostRecently)

FILE: Sentinel/Images/AddTypeImageService.cs
  class AddTypeImageService (line 12) | public class AddTypeImageService : ViewModelBase, IAddTypeImage
    method Add (line 16) | public void Add()

FILE: Sentinel/Images/Controls/AddImageWindow.xaml.cs
  class AddImageWindow (line 8) | public partial class AddImageWindow : Window
    method AddImageWindow (line 10) | public AddImageWindow()

FILE: Sentinel/Images/EditTypeImageMapping.cs
  class EditTypeImageMapping (line 10) | public class EditTypeImageMapping : IEditTypeImage
    method Edit (line 12) | public void Edit(ImageTypeRecord imageTypeRecord)

FILE: Sentinel/Images/ImageQuality.cs
  type ImageQuality (line 3) | public enum ImageQuality

FILE: Sentinel/Images/ImageTypeRecord.cs
  class ImageTypeRecord (line 5) | public class ImageTypeRecord : ViewModelBase
    method ImageTypeRecord (line 13) | public ImageTypeRecord(string name, ImageQuality quality, string image)

FILE: Sentinel/Images/Interfaces/IAddTypeImage.cs
  type IAddTypeImage (line 3) | public interface IAddTypeImage
    method Add (line 5) | void Add();

FILE: Sentinel/Images/Interfaces/IEditTypeImage.cs
  type IEditTypeImage (line 3) | public interface IEditTypeImage
    method Edit (line 5) | void Edit(ImageTypeRecord imageTypeRecord);

FILE: Sentinel/Images/Interfaces/IRemoveTypeImage.cs
  type IRemoveTypeImage (line 3) | public interface IRemoveTypeImage
    method Remove (line 5) | void Remove(ImageTypeRecord imageTypeRecord);

FILE: Sentinel/Images/Interfaces/ITypeImageService.cs
  type ITypeImageService (line 7) | public interface ITypeImageService
    method Register (line 20) | void Register(string type, ImageQuality quality, string image);
    method Get (line 22) | ImageTypeRecord Get(string type, ImageOptions options);

FILE: Sentinel/Images/Interfaces/ImageOptions.cs
  class ImageOptions (line 3) | public class ImageOptions

FILE: Sentinel/Images/RemoveTypeImageMapping.cs
  class RemoveTypeImageMapping (line 8) | public class RemoveTypeImageMapping : IRemoveTypeImage
    method Remove (line 10) | public void Remove(ImageTypeRecord typeImageRecord)

FILE: Sentinel/Images/TypeToImageService.cs
  class TypeToImageService (line 15) | [DataContract]
    method TypeToImageService (line 20) | public TypeToImageService()
    method Register (line 65) | public void Register(string type, ImageQuality quality, string image)
    method Get (line 94) | public ImageTypeRecord Get(
    method Initialise (line 141) | public void Initialise()
    method AddMapping (line 174) | private void AddMapping(object obj)
    method EditMapping (line 179) | private void EditMapping(object obj)
    method RemoveMapping (line 188) | private void RemoveMapping(object obj)

FILE: Sentinel/Interfaces/CaseInsensitiveComparer.cs
  class CaseInsensitiveComparer (line 6) | public class CaseInsensitiveComparer<T> : IEqualityComparer<T>
    method Equals (line 8) | public bool Equals(T x, T y)
    method GetHashCode (line 20) | public int GetHashCode(T obj)

FILE: Sentinel/Interfaces/CodeContracts/ThrowIfNull.cs
  class CodeContractExtensions (line 8) | public static partial class CodeContractExtensions
    method ThrowIfNull (line 10) | [ContractAbbreviator]

FILE: Sentinel/Interfaces/CodeContracts/ThrowIfNullOrWhitespace.cs
  class CodeContractExtensions (line 8) | public static partial class CodeContractExtensions
    method ThrowIfNullOrWhiteSpace (line 10) | [ContractAbbreviator]

FILE: Sentinel/Interfaces/CodeContracts/ValidatedNotNullAttribute.cs
  class ValidatedNotNullAttribute (line 5) | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]

FILE: Sentinel/Interfaces/CollectionChangeHelper.cs
  class CollectionChangeHelper (line 10) | public class CollectionChangeHelper<T>
    method AttachDetach (line 18) | public void AttachDetach(object sender, NotifyCollectionChangedEventAr...

FILE: Sentinel/Interfaces/EnumerableExtensions.cs
  class EnumerableExtensions (line 6) | public static class EnumerableExtensions
    method IndexOf (line 8) | public static int IndexOf<T>(this IEnumerable<T> list, T value)
    method IndexOf (line 13) | public static int IndexOf<T>(this IEnumerable<T> list, T value, IEqual...

FILE: Sentinel/Interfaces/IDefaultInitialisation.cs
  type IDefaultInitialisation (line 3) | public interface IDefaultInitialisation
    method Initialise (line 5) | void Initialise();

FILE: Sentinel/Interfaces/IHighlighterStyle.cs
  type IHighlighterStyle (line 5) | public interface IHighlighterStyle

FILE: Sentinel/Interfaces/ILogEntry.cs
  type ILogEntry (line 6) | public interface ILogEntry

FILE: Sentinel/Interfaces/ILogger.cs
  type ILogger (line 9) | public interface ILogger : INotifyPropertyChanged
    method Clear (line 34) | void Clear();
    method AddBatch (line 40) | void AddBatch(Queue<ILogEntry> entries);
    method LimitMessageCount (line 49) | void LimitMessageCount(int maximumMessages);

FILE: Sentinel/Interfaces/IUserPreferences.cs
  type IUserPreferences (line 6) | public interface IUserPreferences

FILE: Sentinel/Interfaces/LinqHelpers.cs
  class LinqHelpers (line 5) | public static class LinqHelpers
    method Swap (line 7) | public static IList<T> Swap<T>(this IList<T> list, int index1, int ind...

FILE: Sentinel/Interfaces/LogEntryFields.cs
  type LogEntryFields (line 16) | [Flags]

FILE: Sentinel/Interfaces/MatchMode.cs
  type MatchMode (line 11) | [DataContract]

FILE: Sentinel/Interfaces/Providers/ILogProvider.cs
  type ILogProvider (line 3) | public interface ILogProvider
    method Start (line 15) | void Start();
    method Pause (line 17) | void Pause();
    method Close (line 19) | void Close();

FILE: Sentinel/Interfaces/Providers/INetworkProvider.cs
  type INetworkProvider (line 5) | public interface INetworkProvider : ILogProvider

FILE: Sentinel/Interfaces/Providers/IProviderInfo.cs
  type IProviderInfo (line 6) | public interface IProviderInfo

FILE: Sentinel/Interfaces/Providers/IProviderRegistrationRecord.cs
  type IProviderRegistrationRecord (line 5) | public interface IProviderRegistrationRecord

FILE: Sentinel/Interfaces/Providers/IProviderSettings.cs
  type IProviderSettings (line 5) | public interface IProviderSettings

FILE: Sentinel/Log4Net/ConfigurationPage.xaml.cs
  class ConfigurationPage (line 14) | public partial class ConfigurationPage : UserControl, IWizardPage
    method ConfigurationPage (line 24) | public ConfigurationPage()
    method AddChild (line 105) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 111) | public void RemoveChild(IWizardPage item)
    method Save (line 117) | public object Save(object saveData)
    method OnPropertyChanged (line 128) | protected void OnPropertyChanged(string propertyName)
    method SelectProviderPagePropertyChanged (line 138) | private void SelectProviderPagePropertyChanged(object sender, Property...

FILE: Sentinel/Log4Net/IUdpAppenderListenerSettings.cs
  type IUdpAppenderListenerSettings (line 5) | public interface IUdpAppenderListenerSettings : IProviderSettings

FILE: Sentinel/Log4Net/Log4NetProvider.cs
  class Log4NetProvider (line 17) | public class Log4NetProvider : INetworkProvider
    method Log4NetProvider (line 42) | public Log4NetProvider(IProviderSettings settings)
    method Start (line 65) | public void Start()
    method Pause (line 83) | public void Pause()
    method Close (line 93) | public void Close()
    method SocketListener (line 103) | private void SocketListener()
    method MessagePump (line 161) | private void MessagePump()
    method DeserializeMessage (line 213) | private ILogEntry DeserializeMessage(string message)
    method AddExceptionIfFound (line 346) | private void AddExceptionIfFound(XElement entryEvent, Dictionary<strin...
    method IsValidMessage (line 359) | private bool IsValidMessage(string message)
    class ProviderInfo (line 369) | internal class ProviderInfo : IProviderInfo

FILE: Sentinel/Log4Net/LogEntry.cs
  class LogEntry (line 8) | internal class LogEntry : ILogEntry
    method LogEntry (line 10) | public LogEntry()

FILE: Sentinel/Log4Net/ProviderRegistrationInformation.cs
  class ProviderRegistrationInformation (line 7) | public class ProviderRegistrationInformation : IProviderRegistrationRecord
    method ProviderRegistrationInformation (line 9) | public ProviderRegistrationInformation(IProviderInfo providerInfo)

FILE: Sentinel/Log4Net/UdpAppenderSettings.cs
  class UdpAppenderSettings (line 5) | public class UdpAppenderSettings : IUdpAppenderListenerSettings
    method UdpAppenderSettings (line 7) | public UdpAppenderSettings()
    method UdpAppenderSettings (line 13) | public UdpAppenderSettings(IProviderSettings providerInfo)

FILE: Sentinel/Log4Net/XElementHelpers.cs
  class XElementHelpers (line 11) | public static class XElementHelpers
    method GetAttribute (line 15) | public static string GetAttribute(this XElement element, string attrib...
    method GetAttributeDateTime (line 28) | public static DateTime GetAttributeDateTime(this XElement element, str...

FILE: Sentinel/Logger/ILogViewerDetails.cs
  type ILogViewerDetails (line 3) | public interface ILogViewerDetails

FILE: Sentinel/Logger/IUdpLogViewer.cs
  type IUdpLogViewer (line 5) | public interface IUdpLogViewer : ILogViewer

FILE: Sentinel/Logger/LogWriter.cs
  class LogWriter (line 13) | public class LogWriter
    method Write (line 19) | public void Write(IEnumerable<ILogEntry> entries)

FILE: Sentinel/Logs/Gui/AddNewLoggerWelcomePage.xaml.cs
  class AddNewLoggerWelcomePage (line 12) | public partial class AddNewLoggerWelcomePage : IWizardPage
    method AddNewLoggerWelcomePage (line 20) | public AddNewLoggerWelcomePage()
    method AddChild (line 73) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 79) | public void RemoveChild(IWizardPage item)
    method Save (line 85) | public object Save(object saveData)
    method OnPropertyChanged (line 94) | private void OnPropertyChanged(string propertyName)

FILE: Sentinel/Logs/Gui/NewLoggerSettings.cs
  class NewLoggerSettings (line 14) | public class NewLoggerSettings : ViewModelBase
    method NewLoggerSettings (line 22) | public NewLoggerSettings()
    method LookupViewInformation (line 162) | private static string LookupViewInformation(string identifier)
    method ViewsCollectionChanged (line 169) | private void ViewsCollectionChanged(object sender, NotifyCollectionCha...
    class InternalSettings (line 179) | private class InternalSettings

FILE: Sentinel/Logs/Gui/NewLoggerSummaryPage.xaml.cs
  class NewLoggerSummaryPage (line 12) | public partial class NewLoggerSummaryPage : IWizardPage
    method NewLoggerSummaryPage (line 16) | public NewLoggerSummaryPage()
    method AddChild (line 37) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 42) | public void RemoveChild(IWizardPage item)
    method Save (line 47) | public object Save(object saveData)
    method OnPropertyChanged (line 52) | protected void OnPropertyChanged(string propertyName)

FILE: Sentinel/Logs/Gui/NewLoggerWizard.cs
  class NewLoggerWizard (line 8) | public class NewLoggerWizard
    method NewLoggerWizard (line 10) | public NewLoggerWizard()
    method Display (line 17) | public bool Display(Window parent)

FILE: Sentinel/Logs/Gui/ProvidersPage.xaml.cs
  class ProvidersPage (line 22) | public partial class ProvidersPage : IWizardPage, IDataErrorInfo
    method ProvidersPage (line 32) | public ProvidersPage()
    method AddChild (line 133) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 138) | public void RemoveChild(IWizardPage item)
    method Save (line 143) | public object Save(object saveData)
    method OnPropertyChanged (line 161) | protected void OnPropertyChanged(string propertyName)
    method AddNewProvider (line 171) | private void AddNewProvider(object obj)
    method RemoveSelectedProvider (line 194) | private void RemoveSelectedProvider(object obj)
    method ValidateProviders (line 208) | private string ValidateProviders()
    method PageLoaded (line 264) | private void PageLoaded(object sender, RoutedEventArgs e)
    method ProvidersCollectionChanged (line 269) | private void ProvidersCollectionChanged(object sender, NotifyCollectio...

FILE: Sentinel/Logs/Gui/SetLoggerNamePage.xaml.cs
  class SetLoggerNamePage (line 15) | public partial class SetLoggerNamePage : IWizardPage, IDataErrorInfo
    method SetLoggerNamePage (line 25) | public SetLoggerNamePage()
    method Save (line 113) | public object Save(object saveData)
    method AddChild (line 127) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 133) | public void RemoveChild(IWizardPage item)
    method OnPropertyChanged (line 139) | protected void OnPropertyChanged(string propertyName)
    method PropertyChangedHandler (line 149) | private void PropertyChangedHandler(object sender, PropertyChangedEven...
    method PageLoaded (line 158) | private void PageLoaded(object sender, System.Windows.RoutedEventArgs e)

FILE: Sentinel/Logs/Gui/ViewSelectionPage.xaml.cs
  class ViewSelectionPage (line 18) | public partial class ViewSelectionPage : IWizardPage
    method ViewSelectionPage (line 38) | public ViewSelectionPage()
    method AddChild (line 209) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 215) | public void RemoveChild(IWizardPage item)
    method Save (line 221) | public object Save(object saveData)
    method OnPropertyChanged (line 241) | protected void OnPropertyChanged(string propertyName)
    method PropertyChangedHandler (line 251) | private void PropertyChangedHandler(object sender, PropertyChangedEven...

FILE: Sentinel/Logs/Interfaces/ILogFileExporter.cs
  type ILogFileExporter (line 5) | public interface ILogFileExporter
    method SaveLogViewerToFile (line 7) | void SaveLogViewerToFile(IWindowFrame windowFrame, string filePath);

FILE: Sentinel/Logs/Interfaces/ILogManager.cs
  type ILogManager (line 7) | public interface ILogManager : IEnumerable<ILogger>
    method Add (line 9) | ILogger Add(string logName);
    method Get (line 11) | ILogger Get(string name);
    method Remove (line 13) | void Remove(string name);

FILE: Sentinel/Logs/Log.cs
  class Log (line 15) | public class Log : ViewModelBase, ILogger
    method Log (line 29) | public Log()
    method Clear (line 73) | public void Clear()
    method AddBatch (line 90) | public void AddBatch(Queue<ILogEntry> incomingEntries)
    method LimitMessageCount (line 116) | public void LimitMessageCount(int maximumMessages)
    method OnPropertyChanged (line 130) | private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)

FILE: Sentinel/Logs/LogFileExporter.cs
  class LogFileExporter (line 9) | public class LogFileExporter : ILogFileExporter
    method LogFileExporter (line 11) | public LogFileExporter()
    method SaveLogViewerToFile (line 15) | public void SaveLogViewerToFile(IWindowFrame windowFrame, string fileP...
    method AddText (line 38) | private static void AddText(FileStream fs, string value)

FILE: Sentinel/Logs/LogManager.cs
  class LogManager (line 14) | public class LogManager : ViewModelBase, ILogManager
    method Add (line 18) | public ILogger Add(string logName)
    method Get (line 34) | public ILogger Get(string name)
    method Remove (line 39) | public void Remove(string name)
    method GetEnumerator (line 55) | public IEnumerator<ILogger> GetEnumerator()
    method GetEnumerator (line 68) | IEnumerator IEnumerable.GetEnumerator()

FILE: Sentinel/MSBuild/ConfigurationPage.xaml.cs
  class ConfigurationPage (line 15) | public partial class ConfigurationPage : IWizardPage
    method ConfigurationPage (line 23) | public ConfigurationPage()
    method AddChild (line 76) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 82) | public void RemoveChild(IWizardPage item)
    method Save (line 88) | public object Save(object saveData)
    method OnPropertyChanged (line 98) | protected void OnPropertyChanged(string propertyName)
    method OnLoaded (line 108) | private void OnLoaded(object sender, System.Windows.RoutedEventArgs e)
    method SelectProviderPagePropertyChanged (line 112) | private void SelectProviderPagePropertyChanged(object sender, Property...

FILE: Sentinel/MSBuild/IMSBuildListenerSettings.cs
  type IMsBuildListenerSettings (line 5) | public interface IMsBuildListenerSettings : IProviderSettings

FILE: Sentinel/MSBuild/LogEntry.cs
  class LogEntry (line 11) | internal class LogEntry : ILogEntry
    method LogEntry (line 13) | public LogEntry()
    method LogEntry (line 17) | public LogEntry(string msbuildEventType, JObject content)

FILE: Sentinel/MSBuild/MSBuildListenerSettings.cs
  class MsBuildListenerSettings (line 5) | public class MsBuildListenerSettings : IMsBuildListenerSettings
    method MsBuildListenerSettings (line 7) | public MsBuildListenerSettings(IProviderSettings providerSettings)

FILE: Sentinel/MSBuild/MSBuildProvider.cs
  class MsBuildProvider (line 18) | public class MsBuildProvider : INetworkProvider
    method MsBuildProvider (line 33) | public MsBuildProvider(IProviderSettings settings)
    method Start (line 57) | public void Start()
    method Pause (line 75) | public void Pause()
    method Close (line 85) | public void Close()
    method SocketListener (line 95) | private void SocketListener()
    method MessagePump (line 145) | private void MessagePump()
    method DeserializeMessage (line 197) | private ILogEntry DeserializeMessage(string message)
    method IsValidMessage (line 239) | private bool IsValidMessage(string message)

FILE: Sentinel/MSBuild/ProviderInfo.cs
  class ProviderInfo (line 7) | public class ProviderInfo : IProviderInfo

FILE: Sentinel/MSBuild/ProviderRegistrationInformation.cs
  class ProviderRegistrationInformation (line 7) | public class ProviderRegistrationInformation : IProviderRegistrationRecord
    method ProviderRegistrationInformation (line 9) | public ProviderRegistrationInformation(IProviderInfo providerInfo)

FILE: Sentinel/MainApplication.xaml.cs
  class MainApplication (line 12) | public partial class MainApplication : Application
    method MainApplication (line 17) | public MainApplication()

FILE: Sentinel/NLog/INLogAppenderSettings.cs
  type INLogAppenderSettings (line 7) | public interface INLogAppenderSettings : IProviderSettings

FILE: Sentinel/NLog/LogEntry.cs
  class LogEntry (line 8) | public class LogEntry : ILogEntry
    method LogEntry (line 10) | public LogEntry()

FILE: Sentinel/NLog/NLogViewerProvider.cs
  class NLogViewerProvider (line 17) | public class NLogViewerProvider : INetworkProvider
    method NLogViewerProvider (line 44) | public NLogViewerProvider(IProviderSettings settings)
    method Start (line 67) | public void Start()
    method Pause (line 87) | public void Pause()
    method Close (line 97) | public void Close()
    method SocketListener (line 107) | private void SocketListener()
    method MessagePump (line 170) | private void MessagePump()
    method IsValidEntry (line 221) | private bool IsValidEntry(string logEntry)
    method DecodeEntry (line 226) | private LogEntry DecodeEntry(string m)

FILE: Sentinel/NLog/NetworkClientWrapper.cs
  class NetworkClientWrapper (line 9) | public class NetworkClientWrapper : IDisposable
    method NetworkClientWrapper (line 19) | public NetworkClientWrapper(NetworkProtocol protocol, IPEndPoint endPo...
    method Receive (line 36) | public byte[] Receive(ref IPEndPoint remoteEndPoint, int receiveTimeout)
    method Dispose (line 73) | public void Dispose()
  class TcpClientExtensions (line 83) | internal static class TcpClientExtensions
    method SetReceiveTimeout (line 85) | public static TcpClient SetReceiveTimeout(this TcpClient tcpClient, in...

FILE: Sentinel/NLog/NetworkConfigurationPage.xaml.cs
  class NetworkConfigurationPage (line 11) | public partial class NetworkConfigurationPage : UserControl, IWizardPage
    method NetworkConfigurationPage (line 21) | public NetworkConfigurationPage()
    method AddChild (line 88) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 94) | public void RemoveChild(IWizardPage item)
    method Save (line 100) | public object Save(object saveData)
    method OnPropertyChanged (line 120) | protected void OnPropertyChanged(string propertyName)
    method OnLoaded (line 130) | private void OnLoaded(object sender, System.Windows.RoutedEventArgs e)
    method SelectProviderPage_PropertyChanged (line 137) | private void SelectProviderPage_PropertyChanged(object sender, Propert...

FILE: Sentinel/NLog/NetworkProtocol.cs
  type NetworkProtocol (line 3) | public enum NetworkProtocol

FILE: Sentinel/NLog/NetworkSettings.cs
  class NetworkSettings (line 5) | [DataContract]
    method NetworkSettings (line 8) | public NetworkSettings()

FILE: Sentinel/NLog/ProviderInfo.cs
  class ProviderInfo (line 7) | internal class ProviderInfo : IProviderInfo

FILE: Sentinel/NLog/ProviderRegistrationInformation.cs
  class ProviderRegistrationInformation (line 7) | public class ProviderRegistrationInformation : IProviderRegistrationRecord
    method ProviderRegistrationInformation (line 9) | public ProviderRegistrationInformation(IProviderInfo providerInfo)

FILE: Sentinel/NLog/ProviderSettings.cs
  class ProviderSettings (line 7) | [DataContract]

FILE: Sentinel/Preferences/UserPreferences.cs
  class UserPreferences (line 16) | [DataContract]
    method UserPreferences (line 61) | public UserPreferences()

FILE: Sentinel/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: Sentinel/Properties/Settings.Designer.cs
  class Settings (line 14) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

FILE: Sentinel/Providers/Interfaces/INewProviderWizard.cs
  type INewProviderWizard (line 7) | public interface INewProviderWizard
    method Display (line 13) | bool Display(Window parent);

FILE: Sentinel/Providers/Interfaces/IProviderManager.cs
  type IProviderManager (line 8) | public interface IProviderManager : IEnumerable<Guid>
    method Register (line 14) | void Register(IProviderRegistrationRecord record);
    method Create (line 16) | ILogProvider Create(Guid providerGuid, IProviderSettings settings);
    method Get (line 18) | ILogProvider Get(string name);
    method Remove (line 20) | void Remove(string name);
    method GetInformation (line 22) | IProviderInfo GetInformation(Guid providerGuid);
    method GetConfiguration (line 24) | T GetConfiguration<T>(Guid providerGuid);

FILE: Sentinel/Providers/Interfaces/PendingProviderRecord.cs
  class PendingProviderRecord (line 5) | public class PendingProviderRecord

FILE: Sentinel/Providers/NewProviderWizard.cs
  class NewProviderWizard (line 11) | public class NewProviderWizard : INewProviderWizard
    method Display (line 17) | public bool Display(Window parent)

FILE: Sentinel/Providers/ProviderInfo.cs
  class ProviderInfo (line 7) | public class ProviderInfo : IProviderInfo
    method ProviderInfo (line 9) | public ProviderInfo(Guid uniqueId, string name, string description)

FILE: Sentinel/Providers/ProviderManager.cs
  class ProviderManager (line 18) | public class ProviderManager : IProviderManager
    method ProviderManager (line 25) | public ProviderManager()
    method Register (line 40) | public void Register(IProviderRegistrationRecord record)
    method Create (line 45) | public ILogProvider Create(Guid providerGuid, IProviderSettings settings)
    method Get (line 87) | public ILogProvider Get(string name)
    method Remove (line 98) | public void Remove(string name)
    method GetInformation (line 103) | public IProviderInfo GetInformation(Guid providerGuid)
    method GetConfiguration (line 124) | public T GetConfiguration<T>(Guid providerGuid)
    method GetEnumerator (line 152) | public IEnumerator<Guid> GetEnumerator()
    method GetEnumerator (line 157) | IEnumerator IEnumerable.GetEnumerator()

FILE: Sentinel/Providers/ProviderRegistrationRecord.cs
  class ProviderRegistrationRecord (line 7) | public class ProviderRegistrationRecord : IProviderRegistrationRecord

FILE: Sentinel/Providers/ProviderSettings.cs
  class ProviderSettings (line 5) | public class ProviderSettings : IProviderSettings

FILE: Sentinel/Providers/SelectProviderPage.xaml.cs
  class SelectProviderPage (line 21) | public partial class SelectProviderPage : IWizardPage
    method SelectProviderPage (line 48) | public SelectProviderPage()
    method AddChild (line 169) | public void AddChild(IWizardPage newItem)
    method RemoveChild (line 174) | public void RemoveChild(IWizardPage item)
    method Save (line 179) | public object Save(object saveData)
    method OnPropertyChanged (line 192) | protected void OnPropertyChanged(string propertyName)
    method SetChildPages (line 202) | private void SetChildPages(int index)
    method PropertyChangedHandler (line 234) | private void PropertyChangedHandler(object sender, PropertyChangedEven...
    method PageLoaded (line 244) | private void PageLoaded(object sender, RoutedEventArgs e)

FILE: Sentinel/Services/AttributeHelper.cs
  class AttributeHelper (line 9) | public static class AttributeHelper
    method HasAttribute (line 11) | public static bool HasAttribute<T>(this Type type)
    method HasAttribute (line 20) | public static bool HasAttribute<T>(this object source)

FILE: Sentinel/Services/DictionaryHelper.cs
  class DictionaryHelper (line 9) | public static class DictionaryHelper
    method Get (line 20) | public static TValue Get<TKey, TValue>(this Dictionary<TKey, TValue> d...

FILE: Sentinel/Services/Interfaces/ISessionManager.cs
  type ISessionManager (line 12) | public interface ISessionManager
    method LoadNewSession (line 35) | void LoadNewSession(Window parent);
    method LoadProviders (line 41) | void LoadProviders(IEnumerable<PendingProviderRecord> providers);
    method LoadSession (line 47) | void LoadSession(string filePath);
    method SaveSession (line 53) | void SaveSession(string filePath);

FILE: Sentinel/Services/ServiceLocator.cs
  class ServiceLocator (line 16) | public class ServiceLocator
    method ServiceLocator (line 22) | private ServiceLocator()
    method Get (line 61) | [SuppressMessage(
    method IsRegistered (line 82) | [SuppressMessage(
    method Register (line 91) | [SuppressMessage(
    method Register (line 100) | public void Register(Type keyType, Type instanceType, bool replace)

FILE: Sentinel/Services/SessionManager.cs
  class SessionManager (line 44) | [DataContract]
    method SessionManager (line 51) | public SessionManager()
    method LoadNewSession (line 72) | public void LoadNewSession(Window parent)
    method LoadProviders (line 99) | public void LoadProviders(IEnumerable<PendingProviderRecord> providers)
    method LoadSession (line 110) | public void LoadSession(string fileName)
    method SaveSession (line 121) | public void SaveSession(string filePath)
    method ConfigureLoggerServices (line 149) | private static void ConfigureLoggerServices(
    method CleanUpResources (line 179) | private void CleanUpResources()
    method LoadChangingViewModelBases (line 195) | private void LoadChangingViewModelBases()
    method LoadServiceLocator (line 214) | private void LoadServiceLocator(IEnumerable<string> jsonObjectStrings)
    method RefreshServiceLocator (line 360) | private void RefreshServiceLocator()
    method ViewModelProperty_Changed (line 393) | private void ViewModelProperty_Changed(object sender, System.Component...

FILE: Sentinel/StartUp/IOptions.cs
  type IOptions (line 5) | public interface IOptions

FILE: Sentinel/StartUp/Log4NetOptions.cs
  class Log4NetOptions (line 5) | [Verb("log4net", HelpText = "Use log4net listener")]
    method Log4NetOptions (line 8) | public Log4NetOptions()

FILE: Sentinel/StartUp/NLogOptions.cs
  class NLogOptions (line 5) | [Verb("nlog", HelpText = "Use nlog listener")]
    method NLogOptions (line 8) | public NLogOptions()

FILE: Sentinel/Support/Converters/BooleanToWidthConverter.cs
  class BooleanToWidthConverter (line 8) | public class BooleanToWidthConverter : IValueConverter
    method Convert (line 10) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 17) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/CollapseIfNullConverter.cs
  class CollapseIfNullConverter (line 8) | public class CollapseIfNullConverter : IValueConverter
    method Convert (line 10) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 23) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/DatePreferenceConverter.cs
  class DatePreferenceConverter (line 16) | public class DatePreferenceConverter : IValueConverter
    method Convert (line 22) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 67) | public object ConvertBack(object value, Type targetType, object parame...
    method GetDateDisplayFormat (line 72) | private static string GetDateDisplayFormat(int setting, IEnumerable<st...

FILE: Sentinel/Support/Converters/ImageLibraryConverter.cs
  class ImageLibraryConverter (line 7) | public class ImageLibraryConverter : IValueConverter
    method Convert (line 19) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 34) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/LongPathToShortPathConverter.cs
  class LongPathToShortPathConverter (line 9) | [ValueConversion(typeof(string), typeof(string))]
    method Convert (line 12) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 32) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/MessageHasExceptionMetadataConverter.cs
  class MessageHasExceptionMetadataConverter (line 8) | public class MessageHasExceptionMetadataConverter : IValueConverter
    method Convert (line 20) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 38) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/MetaDataConverter.cs
  class MetaDataConverter (line 11) | public class MetaDataConverter : IValueConverter
    method Convert (line 13) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 28) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/MetaDataParameterConverter.cs
  class MetaDataParameterConverter (line 9) | public class MetaDataParameterConverter : IMultiValueConverter
    method Convert (line 11) | public object Convert(object[] values, Type targetType, object paramet...
    method ConvertBack (line 40) | public object[] ConvertBack(object value, Type[] targetTypes, object p...

FILE: Sentinel/Support/Converters/TimePreferenceConverter.cs
  class TimePreferenceConverter (line 16) | public class TimePreferenceConverter : IValueConverter
    method Convert (line 22) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 66) | public object ConvertBack(object value, Type targetType, object parame...
    method GetDateDisplayFormat (line 71) | private static string GetDateDisplayFormat(int setting, IEnumerable<st...

FILE: Sentinel/Support/Converters/TimeSinceDateTimeConverter.cs
  class TimeSinceDateTimeConverter (line 8) | public class TimeSinceDateTimeConverter : IValueConverter
    method Convert (line 10) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 34) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/TypeToImageConverter.cs
  class TypeToImageConverter (line 12) | [ValueConversion(typeof(string), typeof(ImageSource))]
    method Convert (line 17) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 48) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/Support/Converters/TypeToLargeImageConverter.cs
  class TypeToLargeImageConverter (line 5) | public class TypeToLargeImageConverter : TypeToImageConverter
    method TypeToLargeImageConverter (line 7) | public TypeToLargeImageConverter()

FILE: Sentinel/Support/Converters/TypeToMediumImageConverter.cs
  class TypeToMediumImageConverter (line 5) | public class TypeToMediumImageConverter : TypeToImageConverter
    method TypeToMediumImageConverter (line 7) | public TypeToMediumImageConverter()

FILE: Sentinel/Support/Converters/TypeToSmallImageConverter.cs
  class TypeToSmallImageConverter (line 5) | public class TypeToSmallImageConverter : TypeToImageConverter
    method TypeToSmallImageConverter (line 7) | public TypeToSmallImageConverter()

FILE: Sentinel/Support/GridViewSort.cs
  class GridViewSort (line 18) | public static class GridViewSort
    method GridViewSort (line 59) | static GridViewSort()
    method ApplySort (line 117) | public static void ApplySort(
    method GetAncestor (line 160) | [SuppressMessage(
    method GetAutoSort (line 177) | public static bool GetAutoSort(DependencyObject dependencyObject)
    method GetCommand (line 183) | public static ICommand GetCommand(DependencyObject dependencyObject)
    method GetPropertyName (line 190) | public static string GetPropertyName(DependencyObject dependencyObject)
    method GetShowSortGlyph (line 197) | public static bool GetShowSortGlyph(DependencyObject dependencyObject)
    method GetSortGlyphAscending (line 204) | public static ImageSource GetSortGlyphAscending(DependencyObject depen...
    method GetSortGlyphDescending (line 211) | public static ImageSource GetSortGlyphDescending(DependencyObject depe...
    method SetAutoSort (line 217) | public static void SetAutoSort(DependencyObject dependencyObject, bool...
    method SetCommand (line 223) | public static void SetCommand(DependencyObject dependencyObject, IComm...
    method SetPropertyName (line 229) | public static void SetPropertyName(DependencyObject dependencyObject, ...
    method SetShowSortGlyph (line 235) | public static void SetShowSortGlyph(DependencyObject dependencyObject,...
    method SetSortGlyphAscending (line 241) | public static void SetSortGlyphAscending(DependencyObject dependencyOb...
    method SetSortGlyphDescending (line 247) | public static void SetSortGlyphDescending(DependencyObject dependencyO...
    method AddSortGlyph (line 253) | private static void AddSortGlyph(
    method ColumnHeaderClick (line 262) | private static void ColumnHeaderClick(object sender, RoutedEventArgs e)
    method GetSortedColumnHeader (line 293) | private static GridViewColumnHeader GetSortedColumnHeader(DependencyOb...
    method RemoveSortGlyph (line 298) | private static void RemoveSortGlyph(GridViewColumnHeader columnHeader)
    method SetSortedColumnHeader (line 311) | private static void SetSortedColumnHeader(DependencyObject obj, GridVi...
    class SortGlyphAdorner (line 316) | private class SortGlyphAdorner : Adorner
      method SortGlyphAdorner (line 324) | public SortGlyphAdorner(
      method OnRender (line 335) | protected override void OnRender(DrawingContext drawingContext)
      method GetDefaultGlyph (line 352) | private Geometry GetDefaultGlyph()

FILE: Sentinel/Support/JsonHelper.cs
  class JsonHelper (line 10) | public static class JsonHelper
    method SerializeToFile (line 19) | public static void SerializeToFile<T>(T objectToSerialize, string file...
    method SerializeToString (line 48) | public static string SerializeToString<T>(T objectToSerialize)
    method DeserializeFromFile (line 61) | public static T DeserializeFromFile<T>(string filename)
    method DeserializeFromString (line 94) | public static T DeserializeFromString<T>(string value)

FILE: Sentinel/Support/ScrollingHelper.cs
  class ScrollingHelper (line 9) | public static class ScrollingHelper
    method GetDescendantByType (line 13) | public static Visual GetDescendantByType(Visual element, Type type)
    method ScrollToEnd (line 41) | public static void ScrollToEnd(Dispatcher dispatcher, ListBox listBox)
    method SelectLastEntry (line 56) | private static void SelectLastEntry(ListBox listBox)

FILE: Sentinel/Support/Wpf/DataBoundToolbar.cs
  class DataBoundToolbar (line 6) | public class DataBoundToolbar : ToolBar
    method OnApplyTemplate (line 10) | public override void OnApplyTemplate()

FILE: Sentinel/Support/Wpf/FixedWidthColumn.cs
  class FixedWidthColumn (line 6) | public class FixedWidthColumn : GridViewColumn
    method FixedWidthColumn (line 15) | static FixedWidthColumn()
    method OnCoerceWidth (line 35) | private static object OnCoerceWidth(DependencyObject o, object baseValue)
    method OnFixedWidthChanged (line 41) | private static void OnFixedWidthChanged(DependencyObject o, Dependency...

FILE: Sentinel/Support/Wpf/ObservableDictionary.cs
  class ObservableDictionary (line 13) | [Serializable]
    method ObservableDictionary (line 32) | public ObservableDictionary()
    method ObservableDictionary (line 37) | public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
    method ObservableDictionary (line 49) | public ObservableDictionary(IEqualityComparer<TKey> comparer)
    method ObservableDictionary (line 54) | public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqu...
    method ObservableDictionary (line 66) | protected ObservableDictionary(SerializationInfo info, StreamingContex...
    method Add (line 170) | public void Add(TKey key, TValue value)
    method Clear (line 175) | public void Clear()
    method ContainsKey (line 180) | public bool ContainsKey(TKey key) => KeyedEntryCollection.Contains(key);
    method ContainsValue (line 182) | public bool ContainsValue(TValue value) => TrueDictionary.ContainsValu...
    method GetEnumerator (line 184) | public IEnumerator GetEnumerator() => new Enumerator(this, false);
    method GetObjectData (line 186) | public virtual void GetObjectData(SerializationInfo info, StreamingCon...
    method OnDeserialization (line 199) | public virtual void OnDeserialization(object sender)
    method Remove (line 211) | public bool Remove(TKey key) => DoRemoveEntry(key);
    method TryGetValue (line 213) | public bool TryGetValue(TKey key, out TValue value)
    method Add (line 220) | void IDictionary.Add(object key, object value)
    method Clear (line 225) | void IDictionary.Clear()
    method Contains (line 230) | bool IDictionary.Contains(object key)
    method CopyTo (line 235) | void ICollection.CopyTo(Array array, int index)
    method GetEnumerator (line 240) | IDictionaryEnumerator IDictionary.GetEnumerator()
    method Remove (line 245) | void IDictionary.Remove(object key)
    method Add (line 250) | void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    method Add (line 255) | void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TV...
    method Clear (line 260) | void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    method Contains (line 265) | bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKe...
    method ContainsKey (line 270) | bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
    method CopyTo (line 275) | void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey,...
    method GetEnumerator (line 297) | IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey,...
    method GetEnumerator (line 302) | IEnumerator IEnumerable.GetEnumerator()
    method Remove (line 307) | bool IDictionary<TKey, TValue>.Remove(TKey key)
    method Remove (line 312) | bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey,...
    method TryGetValue (line 317) | bool IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)
    method AddEntry (line 322) | protected virtual bool AddEntry(TKey key, TValue value)
    method ClearEntries (line 328) | protected virtual bool ClearEntries()
    method GetIndexAndEntryForKey (line 341) | protected int GetIndexAndEntryForKey(TKey key, out DictionaryEntry entry)
    method OnCollectionChanged (line 354) | protected virtual void OnCollectionChanged(NotifyCollectionChangedEven...
    method OnPropertyChanged (line 359) | protected virtual void OnPropertyChanged(string name)
    method RemoveEntry (line 364) | protected virtual bool RemoveEntry(TKey key)
    method SetEntry (line 370) | protected virtual bool SetEntry(TKey key, TValue value)
    method DoAddEntry (line 392) | private void DoAddEntry(TKey key, TValue value)
    method DoClearEntries (line 404) | private void DoClearEntries()
    method DoRemoveEntry (line 413) | private bool DoRemoveEntry(TKey key)
    method DoSetEntry (line 431) | private void DoSetEntry(TKey key, TValue value)
    method FireEntryAddedNotifications (line 455) | private void FireEntryAddedNotifications(DictionaryEntry entry, int in...
    method FireEntryRemovedNotifications (line 475) | private void FireEntryRemovedNotifications(DictionaryEntry entry, int ...
    method FirePropertyChangedNotifications (line 495) | private void FirePropertyChangedNotifications()
    method FireResetNotifications (line 507) | private void FireResetNotifications()
    type Enumerator (line 516) | [Serializable]
      method Enumerator (line 530) | internal Enumerator(ObservableDictionary<TKey, TValue> dictionary, b...
      method Dispose (line 589) | public void Dispose()
      method MoveNext (line 593) | public bool MoveNext()
      method Reset (line 610) | void IEnumerator.Reset()
      method ValidateVersion (line 617) | private void ValidateVersion()
      method ValidateCurrent (line 625) | private void ValidateCurrent()
    class KeyedDictionaryEntryCollection (line 637) | protected class KeyedDictionaryEntryCollection : KeyedCollection<TKey,...
      method KeyedDictionaryEntryCollection (line 639) | public KeyedDictionaryEntryCollection()
      method KeyedDictionaryEntryCollection (line 643) | public KeyedDictionaryEntryCollection(IEqualityComparer<TKey> comparer)
      method GetKeyForItem (line 648) | protected override TKey GetKeyForItem(DictionaryEntry entry)

FILE: Sentinel/Support/Wpf/ThemeInfo.cs
  class ThemeInfo (line 8) | public static class ThemeInfo
    class SafeNativeMethods (line 57) | internal abstract class SafeNativeMethods
      method GetCurrentThemeName (line 69) | [DllImport("UxTheme.dll", CharSet = CharSet.Unicode, EntryPoint = "G...
      method IsThemeActive (line 82) | [DllImport("UxTheme.dll", CharSet = CharSet.Unicode, SetLastError = ...

FILE: Sentinel/Views/Gui/LogMessages.cs
  class LogMessages (line 18) | public class LogMessages : ViewModelBase, ILogViewer
    method LogMessages (line 50) | public LogMessages()
    method SetLogger (line 190) | public void SetLogger(ILogger newLogger)
    method PauseMessagesHandler (line 195) | private void PauseMessagesHandler(object obj)
    method InitialiseToolbar (line 201) | private void InitialiseToolbar()
    method ApplyFiltering (line 245) | private void ApplyFiltering()
    method AddIfPassesFilters (line 268) | private void AddIfPassesFilters(ILogEntry entry)
    method ApplyExtracting (line 287) | private void ApplyExtracting()
    method UpdateTick (line 314) | private void UpdateTick(object sender, EventArgs e)
    method LoggerPropertyChanged (line 400) | private void LoggerPropertyChanged(object sender, PropertyChangedEvent...
    method PropertyChangedHandler (line 436) | private void PropertyChangedHandler(object sender, PropertyChangedEven...

FILE: Sentinel/Views/Gui/LogMessagesControl.xaml.cs
  class LogMessagesControl (line 24) | public partial class LogMessagesControl : UserControl
    method LogMessagesControl (line 28) | public LogMessagesControl()
    method ScrollToEnd (line 78) | public void ScrollToEnd()
    method SetTypeColumnPreferences (line 83) | private void SetTypeColumnPreferences(int selectedTypeOption)
    method UpdateDateFormat (line 110) | private void UpdateDateFormat()
    method BindTimeColumn (line 124) | private void BindTimeColumn(GridViewColumn column)
    method BindDateColumn (line 132) | private void BindDateColumn(GridViewColumn column)
    method UpdateStyles (line 140) | private void UpdateStyles()
    method Messages_OnMouseDoubleClick (line 146) | private void Messages_OnMouseDoubleClick(object sender, MouseButtonEve...
    method CopySelectedLogEntries (line 168) | private void CopySelectedLogEntries()
    method AddCopyCommandBinding (line 190) | private void AddCopyCommandBinding()
    method PreferencesChanged (line 210) | private void PreferencesChanged(object s, PropertyChangedEventArgs e)

FILE: Sentinel/Views/Gui/LogViewerToolbarButton.cs
  class LogViewerToolbarButton (line 10) | public class LogViewerToolbarButton
    method LogViewerToolbarButton (line 17) | public LogViewerToolbarButton(

FILE: Sentinel/Views/Gui/MultipleViewFrame.xaml.cs
  class MultipleViewFrame (line 18) | public partial class MultipleViewFrame : INotifyPropertyChanged, IWindow...
    method MultipleViewFrame (line 31) | public MultipleViewFrame()
    method SetViews (line 151) | public void SetViews(IEnumerable<string> viewIdentifiers)
    method OnPropertyChanged (line 176) | protected void OnPropertyChanged(string propertyName)
    method PreferencesChanged (line 186) | private void PreferencesChanged(object sender, PropertyChangedEventArg...
    method SetupSplitter (line 194) | private void SetupSplitter()
    method CollapseSecondaryView (line 242) | private void CollapseSecondaryView()

FILE: Sentinel/Views/Gui/ViewInformation.cs
  class ViewInformation (line 5) | public class ViewInformation : IViewInformation
    method ViewInformation (line 7) | public ViewInformation(string identifier, string name)

FILE: Sentinel/Views/Heartbeat/HeartbeatControl.xaml.cs
  class HeartbeatControl (line 17) | public partial class HeartbeatControl : INotifyPropertyChanged
    method HeartbeatControl (line 21) | public HeartbeatControl()
    method CreatePoints (line 49) | public IEnumerable<Point> CreatePoints(IEnumerable<int> values, int wi...
    method OnPropertyChanged (line 75) | protected virtual void OnPropertyChanged(string propertyName)
    method SampleTick (line 85) | private void SampleTick(object sender, EventArgs e)
    method OnSizeChanged (line 142) | private void OnSizeChanged(object sender, SizeChangedEventArgs e)
    method OnLoaded (line 147) | private void OnLoaded(object sender, RoutedEventArgs e)
    method SetCanvasDimensions (line 152) | private void SetCanvasDimensions()

FILE: Sentinel/Views/Heartbeat/MessageHeatbeat.cs
  class MessageHeatBeat (line 17) | public class MessageHeatBeat : ViewModelBase, ILogViewer
    method MessageHeatBeat (line 36) | public MessageHeatBeat()
    method SetLogger (line 105) | public void SetLogger(ILogger newLogger)
    method PropertyChangedHandler (line 110) | private void PropertyChangedHandler(object sender, PropertyChangedEven...
    method LoggerPropertyChanged (line 119) | private void LoggerPropertyChanged(object sender, PropertyChangedEvent...
    method SampleTick (line 143) | private void SampleTick(object sender, EventArgs e)
    method PurgeData (line 187) | private void PurgeData()

FILE: Sentinel/Views/Heartbeat/ViewInformation.cs
  class ViewInformation (line 3) | public class ViewInformation : Sentinel.Views.Interfaces.IViewInformation
    method ViewInformation (line 5) | public ViewInformation(string identifier, string name)

FILE: Sentinel/Views/Interfaces/ILogViewer.cs
  type ILogViewer (line 9) | public interface ILogViewer
    method SetLogger (line 23) | void SetLogger(ILogger newLogger);

FILE: Sentinel/Views/Interfaces/ILogViewerToolbarButton.cs
  type ILogViewerToolbarButton (line 5) | public interface ILogViewerToolbarButton

FILE: Sentinel/Views/Interfaces/IViewInformation.cs
  type IViewInformation (line 3) | public interface IViewInformation

FILE: Sentinel/Views/Interfaces/IViewManager.cs
  type IViewManager (line 7) | public interface IViewManager
    method Register (line 13) | void Register(IViewInformation info, Type viewerType);
    method Get (line 15) | IViewInformation Get(string identifier);
    method GetInstance (line 17) | ILogViewer GetInstance(string identifier);

FILE: Sentinel/Views/Interfaces/IWindowFrame.cs
  type IWindowFrame (line 7) | public interface IWindowFrame
    method SetViews (line 13) | void SetViews(IEnumerable<string> viewIdentifiers);

FILE: Sentinel/Views/ViewManager.cs
  class ViewManager (line 13) | public class ViewManager : IViewManager
    method ViewManager (line 17) | public ViewManager()
    method Register (line 30) | public void Register(IViewInformation info, Type viewerType)
    method Get (line 48) | public IViewInformation Get(string identifier)
    method GetInstance (line 53) | public ILogViewer GetInstance(string identifier)

FILE: Sentinel/WpfExtras/Converters/BooleanInvertingValueConverter.cs
  class BooleanInvertingValueConverter (line 7) | public class BooleanInvertingValueConverter : IValueConverter
    method Convert (line 19) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 35) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/Converters/BooleanToDisabledConverter.cs
  class BooleanToDisabledConverter (line 7) | public class BooleanToDisabledConverter : IValueConverter
    method Convert (line 9) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 14) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/Converters/CollapseIfFalseConverter.cs
  class CollapseIfFalseConverter (line 8) | public class CollapseIfFalseConverter : IValueConverter
    method Convert (line 20) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 41) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/Converters/CollapseIfZeroConverter.cs
  class CollapseIfZeroConverter (line 8) | public class CollapseIfZeroConverter : IValueConverter
    method Convert (line 17) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 29) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/Converters/ColourConverter.cs
  class ColourConverter (line 9) | [ValueConversion(typeof(Color), typeof(Brush))]
    method Convert (line 12) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 35) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/Converters/VisibilityToCollapsedConverter.cs
  class VisibilityToCollapsedConverter (line 8) | public class VisibilityToCollapsedConverter : IValueConverter
    method Convert (line 10) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 23) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/Converters/VisibilityToHiddenConverter.cs
  class VisibilityToHiddenConverter (line 8) | public class VisibilityToHiddenConverter : IValueConverter
    method Convert (line 10) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 22) | public object ConvertBack(object value, Type targetType, object parame...

FILE: Sentinel/WpfExtras/DelegateCommand.cs
  class DelegateCommand (line 6) | public class DelegateCommand : ICommand
    method DelegateCommand (line 8) | public DelegateCommand(Action<object> executeAction, Predicate<object>...
    method CanExecute (line 31) | public bool CanExecute(object parameter)
    method Execute (line 36) | public void Execute(object parameter)

FILE: Sentinel/WpfExtras/EstablishPossibleNavigation.cs
  class EstablishPossibleNavigation (line 3) | public class EstablishPossibleNavigation
    method EstablishPossibleNavigation (line 13) | public EstablishPossibleNavigation(IWizardPage rootNode, IWizardPage n...
    method Execute (line 40) | public void Execute()
    method Visit (line 45) | private void Visit(IWizardPage node)

FILE: Sentinel/WpfExtras/IWizardPage.cs
  type IWizardPage (line 7) | public interface IWizardPage
    method AddChild (line 21) | void AddChild(IWizardPage child);
    method RemoveChild (line 23) | void RemoveChild(IWizardPage child);
    method Save (line 25) | object Save(object saveData);

FILE: Sentinel/WpfExtras/PageChange.cs
  type PageChange (line 3) | public enum PageChange

FILE: Sentinel/WpfExtras/PageNavigationTreeEntry.cs
  class PageNavigationTreeEntry (line 8) | public class PageNavigationTreeEntry : INotifyPropertyChanged
    method PageNavigationTreeEntry (line 14) | public PageNavigationTreeEntry(IWizardPage page)
    method SetCurrentPage (line 50) | public void SetCurrentPage(IWizardPage wizardPage)
    method OnPropertyChanged (line 59) | private void OnPropertyChanged(string propertyName)
    method PageChildCollectionChanged (line 69) | private void PageChildCollectionChanged(object sender, NotifyCollectio...
    method PagePropertyChanged (line 94) | private void PagePropertyChanged(object sender, PropertyChangedEventAr...

FILE: Sentinel/WpfExtras/ViewModelBase.cs
  class ViewModelBase (line 8) | public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
    method ViewModelBase (line 15) | protected ViewModelBase()
    method Dispose (line 50) | public void Dispose()
    method VerifyPropertyName (line 62) | [Conditional("DEBUG")]
    method OnPropertyChanged (line 88) | protected virtual void OnPropertyChanged(string propertyName)
    method OnDispose (line 104) | protected virtual void OnDispose()

FILE: Sentinel/WpfExtras/Wizard.xaml.cs
  class Wizard (line 16) | public partial class Wizard
    method Wizard (line 50) | public Wizard()
    method AddPage (line 124) | public void AddPage(IWizardPage page)
    method AcceptDialog (line 129) | private void AcceptDialog()
    method CancelDialog (line 140) | private void CancelDialog()
    method ChildObserver (line 146) | private void ChildObserver(object sender, PropertyChangedEventArgs e)
    method GoBack (line 160) | private void GoBack()
    method GoForward (line 167) | private void GoForward()
    method OnLoaded (line 174) | private void OnLoaded(object sender, RoutedEventArgs e)
    method PagesPropertyChangedHandler (line 183) | private void PagesPropertyChangedHandler(object sender, PropertyChange...
    method SwitchPage (line 191) | private void SwitchPage(PageChange change)
    method UpdateNavigationPossibilities (line 253) | private void UpdateNavigationPossibilities()
    method WizardPageCollectionChanged (line 264) | private void WizardPageCollectionChanged(object sender, NotifyCollecti...
    class RootPage (line 269) | private sealed class RootPage : IWizardPage
      method RootPage (line 273) | public RootPage()
      method AddChild (line 296) | public void AddChild(IWizardPage newItem)
      method RemoveChild (line 303) | public void RemoveChild(IWizardPage item)
      method Save (line 309) | public object Save(object saveData)
      method OnPropertyChanged (line 318) | private void OnPropertyChanged(string propertyName)
Condensed preview — 280 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (840K chars).
[
  {
    "path": ".gitattributes",
    "chars": 2518,
    "preview": "###############################################################################\n# Set default behavior to automatically "
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 463,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".gitignore",
    "chars": 2325,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 219,
    "preview": "Releases are made from the master branch, but new developments are done on the develop branch.  There are a lot of new d"
  },
  {
    "path": "CustomDictionary.xml",
    "chars": 516,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Dictionary>\n  <Words>\n    <Recognized>\n      <Word>Colour</Word>\n      <Word>Col"
  },
  {
    "path": "GitVersion.yml",
    "chars": 72,
    "preview": "mode: Mainline\nbranches: {}\nignore:\n  sha: []\nmerge-message-formats: {}\n"
  },
  {
    "path": "LICENSE.md",
    "chars": 2666,
    "preview": "# Microsoft Public License (Ms-PL)\n\nMicrosoft Public License (Ms-PL)\n\nThis license governs use of the accompanying softw"
  },
  {
    "path": "README.md",
    "chars": 8035,
    "preview": "# ![](docs/Debug.png) sentinel\nLog-viewer with filtering and highlighting\n\n![](docs/Home_sentinel-0.11.0.0.png)\n\n## Log "
  },
  {
    "path": "Sentinel/.vscode/launch.json",
    "chars": 1075,
    "preview": "{\n   // Use IntelliSense to find out which attributes exist for C# debugging\n   // Use hover for the description of the "
  },
  {
    "path": "Sentinel/.vscode/tasks.json",
    "chars": 1211,
    "preview": "{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"build\",\n            \"command\": \"dotnet\",\n      "
  },
  {
    "path": "Sentinel/Classification/Classifier.cs",
    "chars": 6863,
    "preview": "namespace Sentinel.Classification\n{\n    using System.Diagnostics;\n    using System.Runtime.Serialization;\n    using Sys"
  },
  {
    "path": "Sentinel/Classification/ClassifyingService.cs",
    "chars": 10146,
    "preview": "namespace Sentinel.Classification\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    usin"
  },
  {
    "path": "Sentinel/Classification/Gui/AddClassifier.cs",
    "chars": 1481,
    "preview": "namespace Sentinel.Classification.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Classification.Interfaces;\n    us"
  },
  {
    "path": "Sentinel/Classification/Gui/AddEditClassifier.cs",
    "chars": 2943,
    "preview": "namespace Sentinel.Classification.Gui\n{\n    using System.Windows;\n    using System.Windows.Input;\n\n    using Sentinel.I"
  },
  {
    "path": "Sentinel/Classification/Gui/AddEditClassifierWindow.xaml",
    "chars": 4803,
    "preview": "<Window x:Class=\"Sentinel.Classification.Gui.AddEditClassifierWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx"
  },
  {
    "path": "Sentinel/Classification/Gui/AddEditClassifierWindow.xaml.cs",
    "chars": 297,
    "preview": "namespace Sentinel.Classification.Gui\n{\n    /// <summary>\n    /// Interaction logic for AddEditClassifierWindow.xaml.\n "
  },
  {
    "path": "Sentinel/Classification/Gui/ClassificationsControl.xaml",
    "chars": 4008,
    "preview": "<UserControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.mic"
  },
  {
    "path": "Sentinel/Classification/Gui/ClassificationsControl.xaml.cs",
    "chars": 751,
    "preview": "namespace Sentinel.Classification.Gui\n{\n    using System.Windows.Controls;\n\n    using Sentinel.Classification.Interface"
  },
  {
    "path": "Sentinel/Classification/Gui/EditClassifier.cs",
    "chars": 1184,
    "preview": "namespace Sentinel.Classification.Gui\n{\n    using System.Diagnostics;\n    using System.Windows;\n\n    using Sentinel.Cla"
  },
  {
    "path": "Sentinel/Classification/Gui/RemoveClassifier.cs",
    "chars": 1021,
    "preview": "namespace Sentinel.Classification.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Classification.Interfaces;\n    us"
  },
  {
    "path": "Sentinel/Classification/Interfaces/IAddClassifyingService.cs",
    "chars": 124,
    "preview": "namespace Sentinel.Classification.Interfaces\n{\n    public interface IAddClassifyingService\n    {\n        void Add();\n   "
  },
  {
    "path": "Sentinel/Classification/Interfaces/IClassifier.cs",
    "chars": 661,
    "preview": "namespace Sentinel.Classification.Interfaces\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Interfaces;\n\n"
  },
  {
    "path": "Sentinel/Classification/Interfaces/IClassifyingService.cs",
    "chars": 587,
    "preview": "namespace Sentinel.Classification.Interfaces\n{\n    using System.Collections.ObjectModel;\n    using System.Runtime.Serial"
  },
  {
    "path": "Sentinel/Classification/Interfaces/IEditClassifyingService.cs",
    "chars": 148,
    "preview": "namespace Sentinel.Classification.Interfaces\n{\n    public interface IEditClassifyingService\n    {\n        void Edit(ICla"
  },
  {
    "path": "Sentinel/Classification/Interfaces/IRemoveClassifyingService.cs",
    "chars": 152,
    "preview": "namespace Sentinel.Classification.Interfaces\n{\n    public interface IRemoveClassifyingService\n    {\n        void Remove("
  },
  {
    "path": "Sentinel/Controls/AboutWindow.xaml",
    "chars": 1904,
    "preview": "<Window x:Class=\"Sentinel.Controls.AboutWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentatio"
  },
  {
    "path": "Sentinel/Controls/AboutWindow.xaml.cs",
    "chars": 996,
    "preview": "namespace Sentinel.Controls\n{\n    using System.Diagnostics;\n    using System.IO;\n    using System.Reflection;\n    using"
  },
  {
    "path": "Sentinel/Controls/ImageTypesControl.xaml",
    "chars": 3275,
    "preview": "<UserControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t xmlns:x=\"http://schemas.microsoft.co"
  },
  {
    "path": "Sentinel/Controls/ImageTypesControl.xaml.cs",
    "chars": 552,
    "preview": "namespace Sentinel.Controls\n{\n    using System.Windows.Controls;\n\n    using Sentinel.Images.Interfaces;\n    using Senti"
  },
  {
    "path": "Sentinel/Controls/IntegerTextBox.cs",
    "chars": 383,
    "preview": "namespace Sentinel.Controls\r\n{\r\n    using System.Linq;\r\n    using System.Windows.Controls;\r\n    using System.Windows.In"
  },
  {
    "path": "Sentinel/Controls/LogActivityControl.xaml",
    "chars": 4083,
    "preview": "<UserControl\r\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r\n    xmlns:x=\"http://schemas.micros"
  },
  {
    "path": "Sentinel/Controls/LogActivityControl.xaml.cs",
    "chars": 519,
    "preview": "namespace Sentinel.Controls\n{\n    using Sentinel.Highlighters.Interfaces;\n    using Sentinel.Services;\n\n    /// <summar"
  },
  {
    "path": "Sentinel/Controls/MainWindow.xaml",
    "chars": 31059,
    "preview": "<Window\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com"
  },
  {
    "path": "Sentinel/Controls/MainWindow.xaml.cs",
    "chars": 33343,
    "preview": "namespace Sentinel.Controls\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Collections.Obje"
  },
  {
    "path": "Sentinel/Controls/PersistingSettings.cs",
    "chars": 3653,
    "preview": "namespace Sentinel.Controls\r\n{\r\n    using System;\r\n    using System.Diagnostics;\r\n    using System.Runtime.Serializatio"
  },
  {
    "path": "Sentinel/Controls/PreferencesControl.xaml",
    "chars": 21273,
    "preview": "<UserControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.mic"
  },
  {
    "path": "Sentinel/Controls/PreferencesControl.xaml.cs",
    "chars": 271,
    "preview": "namespace Sentinel.Controls\n{\n    /// <summary>\n    /// Interaction logic for PreferencesControl.xaml.\n    /// </summar"
  },
  {
    "path": "Sentinel/Controls/PreferencesWindow.xaml",
    "chars": 728,
    "preview": "<Window x:Class=\"Sentinel.Controls.PreferencesWindow\"\r\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/pres"
  },
  {
    "path": "Sentinel/Controls/PreferencesWindow.xaml.cs",
    "chars": 961,
    "preview": "namespace Sentinel.Controls\n{\n    using System;\n\n    using Sentinel.Interfaces;\n    using Sentinel.Services;\n\n    /// <"
  },
  {
    "path": "Sentinel/Controls/RecentFileInfo.cs",
    "chars": 261,
    "preview": "namespace Sentinel.Controls\n{\n    using System.Collections.Generic;\n    using System.Runtime.Serialization;\n\n    [DataC"
  },
  {
    "path": "Sentinel/Controls/WindowPlacementInfo.cs",
    "chars": 506,
    "preview": "namespace Sentinel.Controls\r\n{\r\n    using System.Runtime.Serialization;\r\n    using System.Windows;\r\n\r\n    [DataContract"
  },
  {
    "path": "Sentinel/EventLogMonitor/CommandLineOptions.cs",
    "chars": 281,
    "preview": "namespace Sentinel.EventLogMonitor\n{\n    using CommandLine;\n\n    public class CommandLineOptions\n    {\n        [Option("
  },
  {
    "path": "Sentinel/EventLogMonitor/EventLogEntry.cs",
    "chars": 1484,
    "preview": "namespace Sentinel.EventLogMonitor\n{\n    using System;\n    using System.Diagnostics;\n    using System.Text;\n\n    using "
  },
  {
    "path": "Sentinel/EventLogMonitor/Interfaces/IEventLogEntry.cs",
    "chars": 917,
    "preview": "namespace Sentinel.EventLogMonitor.Interfaces\n{\n    using System;\n    using System.Diagnostics;\n\n    using Newtonsoft.J"
  },
  {
    "path": "Sentinel/Extractors/ExtractingService.cs",
    "chars": 4339,
    "preview": "namespace Sentinel.Extractors\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Sy"
  },
  {
    "path": "Sentinel/Extractors/Extractor.cs",
    "chars": 5630,
    "preview": "namespace Sentinel.Extractors\n{\n    using System.Diagnostics;\n    using System.Globalization;\n    using System.Runtime."
  },
  {
    "path": "Sentinel/Extractors/Gui/AddEditExtractor.cs",
    "chars": 2462,
    "preview": "namespace Sentinel.Extractors.Gui\n{\n    using System.Windows;\n    using System.Windows.Input;\n\n    using Sentinel.Inter"
  },
  {
    "path": "Sentinel/Extractors/Gui/AddEditExtractorWindow.xaml",
    "chars": 4255,
    "preview": "<Window x:Class=\"Sentinel.Extractors.Gui.AddEditExtractorWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006"
  },
  {
    "path": "Sentinel/Extractors/Gui/AddEditExtractorWindow.xaml.cs",
    "chars": 326,
    "preview": "namespace Sentinel.Extractors.Gui\n{\n    using System.Windows;\n\n    /// <summary>\n    /// Interaction logic for AddEditE"
  },
  {
    "path": "Sentinel/Extractors/Gui/AddExtractor.cs",
    "chars": 1436,
    "preview": "namespace Sentinel.Extractors.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Extractors.Interfaces;\n    using Sent"
  },
  {
    "path": "Sentinel/Extractors/Gui/EditExtractor.cs",
    "chars": 1073,
    "preview": "namespace Sentinel.Extractors.Gui\n{\n    using System.Diagnostics;\n    using System.Windows;\n\n    using Sentinel.Extract"
  },
  {
    "path": "Sentinel/Extractors/Gui/ExtractorsControl.xaml",
    "chars": 3402,
    "preview": "<UserControl\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsof"
  },
  {
    "path": "Sentinel/Extractors/Gui/ExtractorsControl.xaml.cs",
    "chars": 697,
    "preview": "namespace Sentinel.Extractors.Gui\n{\n    using System.Windows.Controls;\n\n    using Sentinel.Extractors.Interfaces;\n    u"
  },
  {
    "path": "Sentinel/Extractors/Gui/RemoveExtractor.cs",
    "chars": 998,
    "preview": "namespace Sentinel.Extractors.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Extractors.Interfaces;\n    using Sent"
  },
  {
    "path": "Sentinel/Extractors/Interfaces/IAddExtractorService.cs",
    "chars": 119,
    "preview": "namespace Sentinel.Extractors.Interfaces\n{\n    public interface IAddExtractorService\n    {\n        void Add();\n    }\n}"
  },
  {
    "path": "Sentinel/Extractors/Interfaces/IEditExtractorService.cs",
    "chars": 141,
    "preview": "namespace Sentinel.Extractors.Interfaces\n{\n    public interface IEditExtractorService\n    {\n        void Edit(IExtracto"
  },
  {
    "path": "Sentinel/Extractors/Interfaces/IExtractingService.cs",
    "chars": 427,
    "preview": "namespace Sentinel.Extractors.Interfaces\n{\n    using System.Collections.ObjectModel;\n    using System.Runtime.Serializa"
  },
  {
    "path": "Sentinel/Extractors/Interfaces/IExtractor.cs",
    "chars": 675,
    "preview": "namespace Sentinel.Extractors.Interfaces\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Interfaces;\n\n   "
  },
  {
    "path": "Sentinel/Extractors/Interfaces/IRemoveExtractorService.cs",
    "chars": 145,
    "preview": "namespace Sentinel.Extractors.Interfaces\n{\n    public interface IRemoveExtractorService\n    {\n        void Remove(IExtr"
  },
  {
    "path": "Sentinel/Extractors/Interfaces/ISearchExtractor.cs",
    "chars": 108,
    "preview": "namespace Sentinel.Extractors.Interfaces\n{\n    public interface ISearchExtractor : IExtractor\n    {\n    }\n}"
  },
  {
    "path": "Sentinel/Extractors/SearchExtractor.cs",
    "chars": 445,
    "preview": "namespace Sentinel.Extractors\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Extractors.Interfaces;\n    "
  },
  {
    "path": "Sentinel/FileMonitor/CustomMessageDecoderPage.xaml",
    "chars": 2436,
    "preview": "<UserControl x:Class=\"Sentinel.FileMonitor.CustomMessageDecoderPage\"\n             xmlns=\"http://schemas.microsoft.com/w"
  },
  {
    "path": "Sentinel/FileMonitor/CustomMessageDecoderPage.xaml.cs",
    "chars": 6192,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System;\n    using System.Collections.ObjectModel;\n    using System.Component"
  },
  {
    "path": "Sentinel/FileMonitor/FileMonitorProviderPage.xaml",
    "chars": 5988,
    "preview": "<UserControl x:Class=\"Sentinel.FileMonitor.FileMonitorProviderPage\"\n             xmlns=\"http://schemas.microsoft.com/wi"
  },
  {
    "path": "Sentinel/FileMonitor/FileMonitorProviderPage.xaml.cs",
    "chars": 8582,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System;\n    using System.Collections.ObjectModel;\n    using System.Component"
  },
  {
    "path": "Sentinel/FileMonitor/FileMonitoringProvider.cs",
    "chars": 11315,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System;\n    using System.Collections.Generic;\n    using System.ComponentMode"
  },
  {
    "path": "Sentinel/FileMonitor/FileMonitoringProviderSettings.cs",
    "chars": 1461,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System.Globalization;\n\n    using Sentinel.Interfaces.Providers;\n\n    public "
  },
  {
    "path": "Sentinel/FileMonitor/IFileMonitoringProviderSettings.cs",
    "chars": 390,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using Sentinel.Interfaces.Providers;\n\n    public interface IFileMonitoringProvider"
  },
  {
    "path": "Sentinel/FileMonitor/LogEntry.cs",
    "chars": 1326,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System;\n    using System.Collections.Generic;\n\n    using Sentinel.Interfaces;"
  },
  {
    "path": "Sentinel/FileMonitor/MessageFormatPage.xaml",
    "chars": 2776,
    "preview": "<UserControl x:Class=\"Sentinel.FileMonitor.MessageFormatPage\"\n             xmlns=\"http://schemas.microsoft.com/winfx/20"
  },
  {
    "path": "Sentinel/FileMonitor/MessageFormatPage.xaml.cs",
    "chars": 5084,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Collections.O"
  },
  {
    "path": "Sentinel/FileMonitor/ProviderRegistrationInformation.cs",
    "chars": 809,
    "preview": "namespace Sentinel.FileMonitor\n{\n    using System;\n\n    using Sentinel.Interfaces.Providers;\n\n    public class ProviderR"
  },
  {
    "path": "Sentinel/Filters/Filter.cs",
    "chars": 6400,
    "preview": "namespace Sentinel.Filters\n{\n    using System;\n    using System.Runtime.Serialization;\n    using System.Text.RegularExpr"
  },
  {
    "path": "Sentinel/Filters/FilteringService.cs",
    "chars": 4475,
    "preview": "namespace Sentinel.Filters\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Syste"
  },
  {
    "path": "Sentinel/Filters/Gui/AddEditFilter.cs",
    "chars": 2468,
    "preview": "namespace Sentinel.Filters.Gui\n{\n    using System.Windows;\n    using System.Windows.Input;\n\n    using Sentinel.Interface"
  },
  {
    "path": "Sentinel/Filters/Gui/AddEditFilterWindow.xaml",
    "chars": 4223,
    "preview": "<Window x:Class=\"Sentinel.Filters.Gui.AddEditFilterWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/"
  },
  {
    "path": "Sentinel/Filters/Gui/AddEditFilterWindow.xaml.cs",
    "chars": 313,
    "preview": "namespace Sentinel.Filters.Gui\n{\n    using System.Windows;\n\n    /// <summary>\n    /// Interaction logic for AddEditFilt"
  },
  {
    "path": "Sentinel/Filters/Gui/AddFilter.cs",
    "chars": 1272,
    "preview": "namespace Sentinel.Filters.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Filters.Interfaces;\n    using Sentinel.Se"
  },
  {
    "path": "Sentinel/Filters/Gui/EditFilter.cs",
    "chars": 1018,
    "preview": "namespace Sentinel.Filters.Gui\n{\n    using System.Diagnostics;\n    using System.Windows;\n\n    using Sentinel.Filters.Int"
  },
  {
    "path": "Sentinel/Filters/Gui/FiltersControl.xaml",
    "chars": 3419,
    "preview": "<UserControl\r\n\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r\n\txmlns:x=\"http://schemas.microsoft.co"
  },
  {
    "path": "Sentinel/Filters/Gui/FiltersControl.xaml.cs",
    "chars": 669,
    "preview": "namespace Sentinel.Filters.Gui\n{\n    using System.Windows.Controls;\n\n    using Sentinel.Filters.Interfaces;\n    using S"
  },
  {
    "path": "Sentinel/Filters/Gui/RemoveFilter.cs",
    "chars": 952,
    "preview": "namespace Sentinel.Filters.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Filters.Interfaces;\n    using Sentinel.Se"
  },
  {
    "path": "Sentinel/Filters/Interfaces/IAddFilterService.cs",
    "chars": 112,
    "preview": "namespace Sentinel.Filters.Interfaces\n{\n    public interface IAddFilterService\n    {\n        void Add();\n    }\n}"
  },
  {
    "path": "Sentinel/Filters/Interfaces/IEditFilterService.cs",
    "chars": 128,
    "preview": "namespace Sentinel.Filters.Interfaces\n{\n    public interface IEditFilterService\n    {\n        void Edit(IFilter filter);"
  },
  {
    "path": "Sentinel/Filters/Interfaces/IFilter.cs",
    "chars": 699,
    "preview": "namespace Sentinel.Filters.Interfaces\r\n{\r\n    using System.Runtime.Serialization;\r\n\r\n    using Sentinel.Interfaces;\r\n\r\n "
  },
  {
    "path": "Sentinel/Filters/Interfaces/IFilteringService.cs",
    "chars": 389,
    "preview": "namespace Sentinel.Filters.Interfaces\n{\n    using System.Collections.ObjectModel;\n    using System.Runtime.Serialization"
  },
  {
    "path": "Sentinel/Filters/Interfaces/IRemoveFilterService.cs",
    "chars": 132,
    "preview": "namespace Sentinel.Filters.Interfaces\n{\n    public interface IRemoveFilterService\n    {\n        void Remove(IFilter filt"
  },
  {
    "path": "Sentinel/Filters/Interfaces/ISearchFilter.cs",
    "chars": 99,
    "preview": "namespace Sentinel.Filters.Interfaces\n{\n    public interface ISearchFilter : IFilter\n    {\n    }\n}"
  },
  {
    "path": "Sentinel/Filters/Interfaces/IStandardDebuggingFilter.cs",
    "chars": 114,
    "preview": "namespace Sentinel.Filters.Interfaces\r\n{\r\n    public interface IStandardDebuggingFilter : IFilter\r\n    {\r\n    }\r\n}"
  },
  {
    "path": "Sentinel/Filters/SearchFilter.cs",
    "chars": 419,
    "preview": "namespace Sentinel.Filters\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Filters.Interfaces;\n    using "
  },
  {
    "path": "Sentinel/Filters/StandardFilter.cs",
    "chars": 322,
    "preview": "namespace Sentinel.Filters\n{\n    using Sentinel.Filters.Interfaces;\n    using Sentinel.Interfaces;\n\n    public class Sta"
  },
  {
    "path": "Sentinel/Highlighters/Gui/AddEditHighlighter.cs",
    "chars": 7339,
    "preview": "namespace Sentinel.Highlighters.Gui\n{\n    using System.Collections.Generic;\n    using System.ComponentModel;\n    using S"
  },
  {
    "path": "Sentinel/Highlighters/Gui/AddEditHighlighterWindow.xaml",
    "chars": 8231,
    "preview": "<Window x:Class=\"Sentinel.Highlighters.Gui.AddEditHighlighterWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/"
  },
  {
    "path": "Sentinel/Highlighters/Gui/AddEditHighlighterWindow.xaml.cs",
    "chars": 333,
    "preview": "namespace Sentinel.Highlighters.Gui\n{\n    using System.Windows;\n\n    /// <summary>\n    /// Interaction logic for AddEdi"
  },
  {
    "path": "Sentinel/Highlighters/Gui/AddNewHighlighterService.cs",
    "chars": 1907,
    "preview": "namespace Sentinel.Highlighters.Gui\n{\n    using System.Windows;\n    using System.Windows.Media;\n\n    using Sentinel.Hig"
  },
  {
    "path": "Sentinel/Highlighters/Gui/EditHighlighterService.cs",
    "chars": 2680,
    "preview": "namespace Sentinel.Highlighters.Gui\n{\n    using System.Diagnostics;\n    using System.Windows;\n    using System.Windows.M"
  },
  {
    "path": "Sentinel/Highlighters/Gui/HighlightersControl.xaml",
    "chars": 4348,
    "preview": "<UserControl x:Class=\"Sentinel.Highlighters.Gui.HighlightersControl\"\r\n             xmlns=\"http://schemas.microsoft.com/"
  },
  {
    "path": "Sentinel/Highlighters/Gui/HighlightersControl.xaml.cs",
    "chars": 618,
    "preview": "namespace Sentinel.Highlighters.Gui\n{\n    using System.Windows.Controls;\n\n    using Sentinel.Highlighters.Interfaces;\n "
  },
  {
    "path": "Sentinel/Highlighters/Gui/RemoveHighlighterService.cs",
    "chars": 1001,
    "preview": "namespace Sentinel.Highlighters.Gui\n{\n    using System.Windows;\n\n    using Sentinel.Highlighters.Interfaces;\n    using "
  },
  {
    "path": "Sentinel/Highlighters/Highlighter.cs",
    "chars": 6503,
    "preview": "namespace Sentinel.Highlighters\n{\n    using System.Diagnostics;\n    using System.Runtime.Serialization;\n    using System"
  },
  {
    "path": "Sentinel/Highlighters/HighlighterConverter.cs",
    "chars": 1334,
    "preview": "namespace Sentinel.Highlighters\n{\n    using System;\n    using System.Globalization;\n    using System.Windows.Data;\n    u"
  },
  {
    "path": "Sentinel/Highlighters/HighlighterStyle.cs",
    "chars": 1249,
    "preview": "namespace Sentinel.Highlighters\n{\n    using System.Runtime.Serialization;\n    using System.Windows.Media;\n\n    using New"
  },
  {
    "path": "Sentinel/Highlighters/HighlightingSelector.cs",
    "chars": 8939,
    "preview": "namespace Sentinel.Highlighters\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Diagnostics;\n"
  },
  {
    "path": "Sentinel/Highlighters/HighlightingService.cs",
    "chars": 8222,
    "preview": "namespace Sentinel.Highlighters\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using "
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/IAddHighlighterService.cs",
    "chars": 122,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    public interface IAddHighlighterService\n    {\n        void Add();\n    }"
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/IEditHighlighterService.cs",
    "chars": 148,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    public interface IEditHighlighterService\n    {\n        void Edit(IHighl"
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/IHighlighter.cs",
    "chars": 629,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Interfaces;\n\n  "
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/IHighlightingService.cs",
    "chars": 575,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    using System.Collections.ObjectModel;\n    using System.Windows.Input;\n\n"
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/IRemoveHighlighterService.cs",
    "chars": 152,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    public interface IRemoveHighlighterService\n    {\n        void Remove(IH"
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/ISearchHighlighter.cs",
    "chars": 419,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    using System.Collections.Generic;\n\n    using Sentinel.Interfaces;\n\n    "
  },
  {
    "path": "Sentinel/Highlighters/Interfaces/IStandardDebuggingHighlighter.cs",
    "chars": 125,
    "preview": "namespace Sentinel.Highlighters.Interfaces\n{\n    public interface IStandardDebuggingHighlighter : IHighlighter\n    {\n  "
  },
  {
    "path": "Sentinel/Highlighters/SearchHighlighter.cs",
    "chars": 2292,
    "preview": "namespace Sentinel.Highlighters\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Diagnostics;\n"
  },
  {
    "path": "Sentinel/Highlighters/StandardHighlighter.cs",
    "chars": 430,
    "preview": "namespace Sentinel.Highlighters\n{\n    using Sentinel.Highlighters.Interfaces;\n    using Sentinel.Interfaces;\n\n    publi"
  },
  {
    "path": "Sentinel/Images/AddEditTypeImageViewModel.cs",
    "chars": 15713,
    "preview": "namespace Sentinel.Images\n{\n    using System;\n    using System.Collections.Generic;\n    using System.ComponentModel;\n   "
  },
  {
    "path": "Sentinel/Images/AddTypeImageService.cs",
    "chars": 1468,
    "preview": "namespace Sentinel.Images\n{\n    using System;\n    using System.Windows;\n\n    using Sentinel.Images.Controls;\n    using S"
  },
  {
    "path": "Sentinel/Images/Controls/AddImageWindow.xaml",
    "chars": 5166,
    "preview": "<Window x:Class=\"Sentinel.Images.Controls.AddImageWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/p"
  },
  {
    "path": "Sentinel/Images/Controls/AddImageWindow.xaml.cs",
    "chars": 302,
    "preview": "namespace Sentinel.Images.Controls\n{\n    using System.Windows;\n\n    /// <summary>\n    /// Interaction logic for AddImag"
  },
  {
    "path": "Sentinel/Images/EditTypeImageMapping.cs",
    "chars": 1098,
    "preview": "namespace Sentinel.Images\n{\n    using System.Diagnostics;\n    using System.Windows;\n\n    using Sentinel.Images.Controls;"
  },
  {
    "path": "Sentinel/Images/ImageQuality.cs",
    "chars": 590,
    "preview": "namespace Sentinel.Images\r\n{\r\n    public enum ImageQuality\r\n    {\r\n        /// <summary>\r\n        /// Images of a small "
  },
  {
    "path": "Sentinel/Images/ImageTypeRecord.cs",
    "chars": 1441,
    "preview": "namespace Sentinel.Images\n{\n    using WpfExtras;\n\n    public class ImageTypeRecord : ViewModelBase\n    {\n        private"
  },
  {
    "path": "Sentinel/Images/Interfaces/IAddTypeImage.cs",
    "chars": 107,
    "preview": "namespace Sentinel.Images.Interfaces\n{\n    public interface IAddTypeImage\n    {\n        void Add();\n    }\n}"
  },
  {
    "path": "Sentinel/Images/Interfaces/IEditTypeImage.cs",
    "chars": 140,
    "preview": "namespace Sentinel.Images.Interfaces\n{\n    public interface IEditTypeImage\n    {\n        void Edit(ImageTypeRecord image"
  },
  {
    "path": "Sentinel/Images/Interfaces/IRemoveTypeImage.cs",
    "chars": 144,
    "preview": "namespace Sentinel.Images.Interfaces\n{\n    public interface IRemoveTypeImage\n    {\n        void Remove(ImageTypeRecord i"
  },
  {
    "path": "Sentinel/Images/Interfaces/ITypeImageService.cs",
    "chars": 573,
    "preview": "namespace Sentinel.Images.Interfaces\n{\n    using System.Collections.ObjectModel;\n    using System.Runtime.Serialization"
  },
  {
    "path": "Sentinel/Images/Interfaces/ImageOptions.cs",
    "chars": 283,
    "preview": "namespace Sentinel.Images.Interfaces\n{\n    public class ImageOptions\n    {\n        public ImageQuality Quality { get; se"
  },
  {
    "path": "Sentinel/Images/RemoveTypeImageMapping.cs",
    "chars": 978,
    "preview": "namespace Sentinel.Images\n{\n    using System.Windows;\n\n    using Sentinel.Images.Interfaces;\n    using Sentinel.Services"
  },
  {
    "path": "Sentinel/Images/TypeToImageService.cs",
    "chars": 6999,
    "preview": "namespace Sentinel.Images\n{\n    using System.Collections.ObjectModel;\n    using System.Diagnostics;\n    using System.Lin"
  },
  {
    "path": "Sentinel/Interfaces/CaseInsensitiveComparer.cs",
    "chars": 570,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System;\n    using System.Collections.Generic;\n\n    public class CaseInsensitiv"
  },
  {
    "path": "Sentinel/Interfaces/CodeContracts/ThrowIfNull.cs",
    "chars": 741,
    "preview": "namespace Sentinel.Interfaces.CodeContracts\n{\n    using System;\n    using System.Diagnostics;\n    using System.Diagnosti"
  },
  {
    "path": "Sentinel/Interfaces/CodeContracts/ThrowIfNullOrWhitespace.cs",
    "chars": 729,
    "preview": "namespace Sentinel.Interfaces.CodeContracts\n{\n    using System;\n    using System.Diagnostics;\n    using System.Diagnosti"
  },
  {
    "path": "Sentinel/Interfaces/CodeContracts/ValidatedNotNullAttribute.cs",
    "chars": 212,
    "preview": "namespace Sentinel.Interfaces.CodeContracts\n{\n    using System;\n\n    [AttributeUsage(AttributeTargets.Parameter, AllowMu"
  },
  {
    "path": "Sentinel/Interfaces/CollectionChangeHelper.cs",
    "chars": 2932,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Collections.Specialized;\n    using System.ComponentModel;\n    using Sy"
  },
  {
    "path": "Sentinel/Interfaces/EnumerableExtensions.cs",
    "chars": 623,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Collections.Generic;\n    using System.Linq;\n\n    public static class En"
  },
  {
    "path": "Sentinel/Interfaces/IDefaultInitialisation.cs",
    "chars": 123,
    "preview": "namespace Sentinel.Interfaces\r\n{\r\n    public interface IDefaultInitialisation\r\n    {\r\n        void Initialise();\r\n    }"
  },
  {
    "path": "Sentinel/Interfaces/IHighlighterStyle.cs",
    "chars": 198,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Windows.Media;\n\n    public interface IHighlighterStyle\n    {\n        Co"
  },
  {
    "path": "Sentinel/Interfaces/ILogEntry.cs",
    "chars": 1313,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System;\n    using System.Collections.Generic;\n\n    public interface ILogEntry\n"
  },
  {
    "path": "Sentinel/Interfaces/ILogger.cs",
    "chars": 1572,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Collections.Generic;\n    using System.ComponentModel;\n\n    /// <summar"
  },
  {
    "path": "Sentinel/Interfaces/IUserPreferences.cs",
    "chars": 1783,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Collections.Generic;\n    using System.Runtime.Serialization;\n\n    publi"
  },
  {
    "path": "Sentinel/Interfaces/LinqHelpers.cs",
    "chars": 357,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Collections.Generic;\n\n    public static class LinqHelpers\n    {\n       "
  },
  {
    "path": "Sentinel/Interfaces/LogEntryFields.cs",
    "chars": 2204,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System;\n    using System.Runtime.Serialization;\n\n    using Newtonsoft.Json;\n  "
  },
  {
    "path": "Sentinel/Interfaces/MatchMode.cs",
    "chars": 765,
    "preview": "namespace Sentinel.Interfaces\n{\n    using System.Runtime.Serialization;\n\n    using Newtonsoft.Json;\n    using Newtonsoft"
  },
  {
    "path": "Sentinel/Interfaces/Providers/ILogProvider.cs",
    "chars": 359,
    "preview": "namespace Sentinel.Interfaces.Providers\n{\n    public interface ILogProvider\n    {\n        IProviderInfo Information { ge"
  },
  {
    "path": "Sentinel/Interfaces/Providers/INetworkProvider.cs",
    "chars": 197,
    "preview": "namespace Sentinel.Interfaces.Providers\n{\n    using System.Runtime.Serialization;\n\n    public interface INetworkProvide"
  },
  {
    "path": "Sentinel/Interfaces/Providers/IProviderInfo.cs",
    "chars": 312,
    "preview": "namespace Sentinel.Interfaces.Providers\n{\n    using System;\n    using System.Runtime.Serialization;\n\n    public interfac"
  },
  {
    "path": "Sentinel/Interfaces/Providers/IProviderRegistrationRecord.cs",
    "chars": 261,
    "preview": "namespace Sentinel.Interfaces.Providers\n{\n    using System;\n\n    public interface IProviderRegistrationRecord\n    {\n   "
  },
  {
    "path": "Sentinel/Interfaces/Providers/IProviderSettings.cs",
    "chars": 423,
    "preview": "namespace Sentinel.Interfaces.Providers\n{\n    using System.Runtime.Serialization;\n\n    public interface IProviderSettin"
  },
  {
    "path": "Sentinel/Log4Net/ConfigurationPage.xaml",
    "chars": 2230,
    "preview": "<UserControl x:Class=\"Sentinel.Log4Net.ConfigurationPage\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/x"
  },
  {
    "path": "Sentinel/Log4Net/ConfigurationPage.xaml.cs",
    "chars": 3822,
    "preview": "namespace Sentinel.Log4Net\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Syste"
  },
  {
    "path": "Sentinel/Log4Net/IUdpAppenderListenerSettings.cs",
    "chars": 185,
    "preview": "namespace Sentinel.Log4Net\n{\n    using Sentinel.Interfaces.Providers;\n\n    public interface IUdpAppenderListenerSettings"
  },
  {
    "path": "Sentinel/Log4Net/Log4NetProvider.cs",
    "chars": 14192,
    "preview": "namespace Sentinel.Log4Net\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Linq;\n    using S"
  },
  {
    "path": "Sentinel/Log4Net/LogEntry.cs",
    "chars": 1571,
    "preview": "namespace Sentinel.Log4Net\n{\n    using System;\n    using System.Collections.Generic;\n\n    using Sentinel.Interfaces;\n\n  "
  },
  {
    "path": "Sentinel/Log4Net/ProviderRegistrationInformation.cs",
    "chars": 540,
    "preview": "namespace Sentinel.Log4Net\n{\n    using System;\n\n    using Sentinel.Interfaces.Providers;\n\n    public class ProviderRegis"
  },
  {
    "path": "Sentinel/Log4Net/UdpAppenderSettings.cs",
    "chars": 688,
    "preview": "namespace Sentinel.Log4Net\n{\n    using Sentinel.Interfaces.Providers;\n\n    public class UdpAppenderSettings : IUdpAppend"
  },
  {
    "path": "Sentinel/Log4Net/XElementHelpers.cs",
    "chars": 1319,
    "preview": "namespace Sentinel.Log4Net\n{\n    using System;\n    using System.Globalization;\n    using System.Xml.Linq;\n\n    using log"
  },
  {
    "path": "Sentinel/Logger/ILogViewerDetails.cs",
    "chars": 118,
    "preview": "namespace Sentinel.Logger\n{\n    public interface ILogViewerDetails\n    {\n        string LogViewerName { get; }\n    }\n}"
  },
  {
    "path": "Sentinel/Logger/IUdpLogViewer.cs",
    "chars": 158,
    "preview": "namespace Sentinel.Logger\n{\n    using Sentinel.Views.Interfaces;\n\n    public interface IUdpLogViewer : ILogViewer\n    {\n"
  },
  {
    "path": "Sentinel/Logger/LogWriter.cs",
    "chars": 1429,
    "preview": "namespace Sentinel.Logger\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using "
  },
  {
    "path": "Sentinel/Logs/Gui/AddNewLoggerWelcomePage.xaml",
    "chars": 1527,
    "preview": "<UserControl x:Class=\"Sentinel.Logs.Gui.AddNewLoggerWelcomePage\"\r\n             xmlns=\"http://schemas.microsoft.com/winf"
  },
  {
    "path": "Sentinel/Logs/Gui/AddNewLoggerWelcomePage.xaml.cs",
    "chars": 2666,
    "preview": "namespace Sentinel.Logs.Gui\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Syst"
  },
  {
    "path": "Sentinel/Logs/Gui/NewLoggerSettings.cs",
    "chars": 4963,
    "preview": "namespace Sentinel.Logs.Gui\r\n{\r\n    using System.Collections.ObjectModel;\r\n    using System.Collections.Specialized;\r\n "
  },
  {
    "path": "Sentinel/Logs/Gui/NewLoggerSummaryPage.xaml",
    "chars": 4642,
    "preview": "<UserControl x:Class=\"Sentinel.Logs.Gui.NewLoggerSummaryPage\"\r\n             xmlns=\"http://schemas.microsoft.com/winfx/2"
  },
  {
    "path": "Sentinel/Logs/Gui/NewLoggerSummaryPage.xaml.cs",
    "chars": 1598,
    "preview": "namespace Sentinel.Logs.Gui\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Syst"
  },
  {
    "path": "Sentinel/Logs/Gui/NewLoggerWizard.cs",
    "chars": 1273,
    "preview": "namespace Sentinel.Logs.Gui\n{\n    using System.Diagnostics;\n    using System.Windows;\n\n    using WpfExtras;\n\n    public"
  },
  {
    "path": "Sentinel/Logs/Gui/ProvidersPage.xaml",
    "chars": 3170,
    "preview": "<UserControl x:Class=\"Sentinel.Logs.Gui.ProvidersPage\"\r\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xam"
  },
  {
    "path": "Sentinel/Logs/Gui/ProvidersPage.xaml.cs",
    "chars": 8772,
    "preview": "namespace Sentinel.Logs.Gui\n{\n    using System.Collections.ObjectModel;\n    using System.Collections.Specialized;\n    u"
  },
  {
    "path": "Sentinel/Logs/Gui/SetLoggerNamePage.xaml",
    "chars": 2331,
    "preview": "<UserControl x:Class=\"Sentinel.Logs.Gui.SetLoggerNamePage\"\r\n             xmlns=\"http://schemas.microsoft.com/winfx/2006"
  },
  {
    "path": "Sentinel/Logs/Gui/SetLoggerNamePage.xaml.cs",
    "chars": 4699,
    "preview": "namespace Sentinel.Logs.Gui\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Syst"
  },
  {
    "path": "Sentinel/Logs/Gui/ViewSelectionPage.xaml",
    "chars": 3961,
    "preview": "<UserControl x:Class=\"Sentinel.Logs.Gui.ViewSelectionPage\"\r\n             xmlns=\"http://schemas.microsoft.com/winfx/2006"
  },
  {
    "path": "Sentinel/Logs/Gui/ViewSelectionPage.xaml.cs",
    "chars": 6966,
    "preview": "namespace Sentinel.Logs.Gui\n{\n    using System.Collections.Generic;\n    using System.Collections.ObjectModel;\n    using"
  },
  {
    "path": "Sentinel/Logs/Interfaces/ILogFileExporter.cs",
    "chars": 205,
    "preview": "namespace Sentinel.Logs.Interfaces\n{\n    using Sentinel.Views.Interfaces;\n\n    public interface ILogFileExporter\n    {\n"
  },
  {
    "path": "Sentinel/Logs/Interfaces/ILogManager.cs",
    "chars": 284,
    "preview": "namespace Sentinel.Logs.Interfaces\n{\n    using System.Collections.Generic;\n\n    using Sentinel.Interfaces;\n\n    public i"
  },
  {
    "path": "Sentinel/Logs/Log.cs",
    "chars": 5357,
    "preview": "namespace Sentinel.Logs\n{\n    using System;\n    using System.Collections.Generic;\n    using System.ComponentModel;\n    u"
  },
  {
    "path": "Sentinel/Logs/LogFileExporter.cs",
    "chars": 1220,
    "preview": "namespace Sentinel.Logs\n{\n    using System.IO;\n    using System.Text;\n\n    using Sentinel.Logs.Interfaces;\n    using Se"
  },
  {
    "path": "Sentinel/Logs/LogManager.cs",
    "chars": 2146,
    "preview": "namespace Sentinel.Logs\n{\n    using System;\n    using System.Collections;\n    using System.Collections.Generic;\n    usi"
  },
  {
    "path": "Sentinel/MSBuild/ConfigurationPage.xaml",
    "chars": 3113,
    "preview": "<UserControl x:Class=\"Sentinel.MSBuild.ConfigurationPage\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/x"
  },
  {
    "path": "Sentinel/MSBuild/ConfigurationPage.xaml.cs",
    "chars": 3369,
    "preview": "namespace Sentinel.MSBuild\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using Syste"
  },
  {
    "path": "Sentinel/MSBuild/IMSBuildListenerSettings.cs",
    "chars": 150,
    "preview": "namespace Sentinel.MSBuild\n{\n    using Sentinel.Interfaces.Providers;\n\n    public interface IMsBuildListenerSettings : I"
  },
  {
    "path": "Sentinel/MSBuild/LogEntry.cs",
    "chars": 2586,
    "preview": "namespace Sentinel.MSBuild\n{\n    using System;\n    using System.Collections.Generic;\n\n    using Newtonsoft.Json.Linq;\n\n "
  },
  {
    "path": "Sentinel/MSBuild/MSBuildListenerSettings.cs",
    "chars": 542,
    "preview": "namespace Sentinel.MSBuild\n{\n    using Sentinel.Interfaces.Providers;\n\n    public class MsBuildListenerSettings : IMsBui"
  },
  {
    "path": "Sentinel/MSBuild/MSBuildProvider.cs",
    "chars": 8354,
    "preview": "namespace Sentinel.MSBuild\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Linq;\n    using Sy"
  },
  {
    "path": "Sentinel/MSBuild/ProviderInfo.cs",
    "chars": 395,
    "preview": "namespace Sentinel.MSBuild\n{\n    using System;\n\n    using Sentinel.Interfaces.Providers;\n\n    public class ProviderInfo "
  },
  {
    "path": "Sentinel/MSBuild/ProviderRegistrationInformation.cs",
    "chars": 540,
    "preview": "namespace Sentinel.MSBuild\n{\n    using System;\n\n    using Sentinel.Interfaces.Providers;\n\n    public class ProviderRegis"
  },
  {
    "path": "Sentinel/MainApplication.xaml",
    "chars": 3617,
    "preview": "<Application x:Class=\"Sentinel.MainApplication\"\r\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r"
  },
  {
    "path": "Sentinel/MainApplication.xaml.cs",
    "chars": 2230,
    "preview": "namespace Sentinel\n{\n    using System.Windows;\n\n    using Sentinel.Properties;\n    using Sentinel.Services;\n    using S"
  },
  {
    "path": "Sentinel/NLog/INLogAppenderSettings.cs",
    "chars": 306,
    "preview": "namespace Sentinel.NLog\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Interfaces.Providers;\n\n    public "
  },
  {
    "path": "Sentinel/NLog/LogEntry.cs",
    "chars": 1566,
    "preview": "namespace Sentinel.NLog\n{\n    using System;\n    using System.Collections.Generic;\n\n    using Sentinel.Interfaces;\n\n    p"
  },
  {
    "path": "Sentinel/NLog/NLogViewerProvider.cs",
    "chars": 12039,
    "preview": "namespace Sentinel.NLog\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Linq;\n    using Syst"
  },
  {
    "path": "Sentinel/NLog/NetworkClientWrapper.cs",
    "chars": 2710,
    "preview": "namespace Sentinel.NLog\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Linq;\n    using Syste"
  },
  {
    "path": "Sentinel/NLog/NetworkConfigurationPage.xaml",
    "chars": 3133,
    "preview": "<UserControl x:Class=\"Sentinel.NLog.NetworkConfigurationPage\"\n             xmlns=\"http://schemas.microsoft.com/winfx/20"
  },
  {
    "path": "Sentinel/NLog/NetworkConfigurationPage.xaml.cs",
    "chars": 4118,
    "preview": "namespace Sentinel.NLog\n{\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;\n    using System.D"
  },
  {
    "path": "Sentinel/NLog/NetworkProtocol.cs",
    "chars": 246,
    "preview": "namespace Sentinel.NLog\n{\n    public enum NetworkProtocol\n    {\n        /// <summary>\n        /// Use UDP protocol\n     "
  },
  {
    "path": "Sentinel/NLog/NetworkSettings.cs",
    "chars": 564,
    "preview": "namespace Sentinel.NLog\n{\n    using System.Runtime.Serialization;\n\n    [DataContract]\n    public class NetworkSettings "
  },
  {
    "path": "Sentinel/NLog/ProviderInfo.cs",
    "chars": 385,
    "preview": "namespace Sentinel.NLog\n{\n    using System;\n\n    using Sentinel.Interfaces.Providers;\n\n    internal class ProviderInfo :"
  },
  {
    "path": "Sentinel/NLog/ProviderRegistrationInformation.cs",
    "chars": 547,
    "preview": "namespace Sentinel.NLog\n{\n    using System;\n\n    using Sentinel.Interfaces.Providers;\n\n    public class ProviderRegistra"
  },
  {
    "path": "Sentinel/NLog/ProviderSettings.cs",
    "chars": 474,
    "preview": "namespace Sentinel.NLog\n{\n    using System.Runtime.Serialization;\n\n    using Sentinel.Interfaces.Providers;\n\n    [DataC"
  },
  {
    "path": "Sentinel/Preferences/UserPreferences.cs",
    "chars": 12158,
    "preview": "namespace Sentinel.Preferences\n{\n    using System.Collections.Generic;\n    using System.Runtime.Serialization;\n    usin"
  },
  {
    "path": "Sentinel/Properties/AssemblyInfo.cs",
    "chars": 1302,
    "preview": "using System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Windows;\n\n// General Information about an a"
  },
  {
    "path": "Sentinel/Properties/Resources.Designer.cs",
    "chars": 2843,
    "preview": "//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     This code"
  },
  {
    "path": "Sentinel/Properties/Resources.resx",
    "chars": 5610,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    T"
  },
  {
    "path": "Sentinel/Properties/Settings.Designer.cs",
    "chars": 1089,
    "preview": "//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     This code"
  }
]

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

About this extraction

This page contains the full source code of the yarseyah/sentinel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 280 files (767.7 KB), approximately 151.3k tokens, and a symbol index with 873 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!