master 6cb138bb0c63 cached
254 files
910.8 KB
215.5k tokens
598 symbols
1 requests
Download .txt
Showing preview only (982K chars total). Download the full file or copy to clipboard to get everything.
Repository: SeriousM/WPFLocalizationExtension
Branch: master
Commit: 6cb138bb0c63
Files: 254
Total size: 910.8 KB

Directory structure:
gitextract_vs211frg/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   ├── dependabot.yml
│   ├── release-drafter.yml
│   └── workflows/
│       ├── compile.yml
│       ├── publish.yml
│       └── release-drafter.yaml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs/
│   ├── BLoc-and-FELoc.md
│   ├── FAQ.md
│   ├── Features.md
│   ├── GapText.md
│   ├── Installation-and-dependencies.md
│   ├── Keys.md
│   ├── LocProxy-&-EnumComboBox.md
│   ├── Localization-providers.md
│   ├── Localization.md
│   ├── Localize.md
│   ├── MarkupExtension-basics.md
│   ├── Multiple-assemblies-and-dictionaries.md
│   ├── Our-first-localized-text.md
│   ├── Preparing-the-XAML-code.md
│   ├── README.md
│   ├── Resource-files.md
│   ├── Supported-platforms.md
│   └── ValueConverters.md
├── src/
│   ├── Deprecated/
│   │   ├── Engine/
│   │   │   ├── GapTextControl.cs
│   │   │   ├── LocBinding.cs
│   │   │   └── LocProxy.cs
│   │   ├── Extensions/
│   │   │   └── Compatibility.cs
│   │   └── Providers/
│   │       ├── CSVEmbeddedLocalizationProvider.cs
│   │       ├── CSVLocalizationProvider.cs
│   │       └── CSVLocalizationProviderBase.cs
│   ├── Engine/
│   │   ├── EnumComboBox.cs
│   │   ├── EnumRun.cs
│   │   ├── FallbackBehavior.cs
│   │   ├── IDictionaryEventListener.cs
│   │   ├── ListenerList.cs
│   │   ├── LocalizeDictionary.cs
│   │   ├── MissingKeyEventArgs.cs
│   │   ├── ObjectDependencyManager.cs
│   │   ├── ParentNotifiers.cs
│   │   ├── SafeTargetInfo.cs
│   │   └── WeakReference.cs
│   ├── Extensions/
│   │   ├── BLoc.cs
│   │   ├── FELoc.cs
│   │   └── LocExtension.cs
│   ├── Providers/
│   │   ├── FQAssemblyDictionaryKey.cs
│   │   ├── FullyQualifiedResourceKeyBase.cs
│   │   ├── IInheritingLocalizationProvider.cs
│   │   ├── ILocalizationProvider.cs
│   │   ├── InheritingResxLocalizationProvider.cs
│   │   ├── ParentChangedNotifierHelper.cs
│   │   ├── ProviderEventArgs.cs
│   │   ├── ResxLocalizationProvider.cs
│   │   └── ResxLocalizationProviderBase.cs
│   ├── Themes/
│   │   └── Generic.xaml
│   ├── TypeConverters/
│   │   ├── BitmapSourceTypeConverter.cs
│   │   ├── DefaultConverter.cs
│   │   ├── RegisterMissingTypeConverters.cs
│   │   └── ThicknessConverter.cs
│   ├── ValueConverters/
│   │   ├── PrependTypeConverter.cs
│   │   ├── StringFormatConverter.cs
│   │   ├── ToLowerConverter.cs
│   │   ├── ToUpperConverter.cs
│   │   ├── TranslateConverter.cs
│   │   └── TypeValueConverterBase.cs
│   ├── WPFLocalizeExtension.csproj
│   ├── WPFLocalizeExtension.sln
│   ├── XmlnsPrefix.cs
│   ├── packages.lock.json
│   └── public.snk
└── tests/
    ├── AssemblyTest/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── AssemblyTest.csproj
    │   ├── CaseConverter.cs
    │   ├── CountryRes.Designer.cs
    │   ├── CountryRes.de.resx
    │   ├── CountryRes.resx
    │   ├── Example.csv
    │   ├── Example.de.csv
    │   ├── Item.cs
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── MyViewModel.cs
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── Resource.With.Dot.Designer.cs
    │   ├── Resource.With.Dot.de.resx
    │   ├── Resource.With.Dot.en.resx
    │   ├── Resource.With.Dot.resx
    │   ├── StringFormatProxy.cs
    │   ├── Strings.Designer.cs
    │   ├── Strings.de.resx
    │   ├── Strings.resx
    │   ├── Strings2.Designer.cs
    │   ├── Strings2.de.resx
    │   ├── Strings2.resx
    │   ├── TestDataClass.cs
    │   ├── TestEnum.cs
    │   └── ViewModelBase.cs
    ├── AssemblyTestResourceLib/
    │   ├── AssemblyTest.csproj
    │   ├── AssemblyTestResourceLib.csproj
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── Strings.Designer.cs
    │   ├── Strings.de.resx
    │   ├── Strings.resx
    │   ├── Strings2.Designer.cs
    │   ├── Strings2.de.resx
    │   └── Strings2.resx
    ├── FluentLexTest/
    │   ├── Application.xaml
    │   ├── Application.xaml.cs
    │   ├── Fluent.Sample.Foundation.csproj
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.de.resx
    │   │   └── Resources.resx
    │   ├── Window.xaml
    │   ├── Window.xaml.cs
    │   └── app.config
    ├── GapTextWpfTest/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── Converters/
    │   │   └── ObjectTypeEqualsConverter.cs
    │   ├── GapTextWpfTest.csproj
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   └── Resources.resx
    │   └── packages.config
    ├── HelloWorldWPF/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── HelloWorldWPF.csproj
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── Ressourcen.Designer.cs
    │   ├── Ressourcen.ar.resx
    │   ├── Ressourcen.de.resx
    │   ├── Ressourcen.en.resx
    │   ├── Ressourcen.he.resx
    │   ├── Ressourcen.resx
    │   └── TestVM.cs
    ├── HelloWorldWPF.sln
    ├── LeakSample/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── LeakSample.csproj
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── MainWindowViewModel.cs
    │   ├── Properties/
    │   │   ├── Annotations.cs
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   └── Resources/
    │       ├── Localization.Designer.cs
    │       └── Localization.resx
    ├── LeakSample.sln
    ├── LocalizationTest/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── Loader.xaml
    │   ├── Loader.xaml.cs
    │   ├── LocalizationTest.csproj
    │   ├── Popup.xaml
    │   ├── Popup.xaml.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   ├── TestResource.Designer.cs
    │   ├── TestResource.en-GB.resx
    │   ├── TestResource.pl-PL.resx
    │   └── TestResource.resx
    ├── LocalizationTest.sln
    ├── MemoryTest/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── MemoryTest.csproj
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.de.resx
    │   │   ├── Resources.en.resx
    │   │   └── Resources.resx
    │   ├── TestWindow.xaml
    │   ├── TestWindow.xaml.cs
    │   ├── TestWindowUnlocalized.xaml
    │   └── TestWindowUnlocalized.xaml.cs
    ├── MemoryTest.sln
    ├── ProviderExample/
    │   ├── CSVLocalizationProvider.cs
    │   ├── ProviderExample.csproj
    │   └── TestProvider.cs
    ├── ResourceAssembly/
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── ResTexts.Designer.cs
    │   ├── ResTexts.resx
    │   └── ResourceAssembly.csproj
    ├── SatelliteAssemblyTest/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── SatelliteAssemblyTest.csproj
    │   ├── TestRes.Designer.cs
    │   ├── TestRes.de.resx
    │   ├── TestRes.es.resx
    │   ├── TestRes.fr.resx
    │   ├── TestRes.resx
    │   └── packages.config
    ├── SatelliteAssemblyTest.sln
    ├── Tests.sln
    ├── ThreadPerformance/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── MainView.xaml
    │   ├── MainView.xaml.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   ├── Resources/
    │   │   ├── MainView.Designer.cs
    │   │   ├── MainView.de.resx
    │   │   └── MainView.resx
    │   ├── ThreadPerformance.csproj
    │   └── packages.config
    ├── ThreadPerformance.sln
    ├── VbWpfApplication/
    │   ├── Application.xaml
    │   ├── Application.xaml.vb
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.vb
    │   ├── My Project/
    │   │   ├── AssemblyInfo.vb
    │   │   ├── MyExtensions/
    │   │   │   └── MyWpfExtension.vb
    │   │   ├── Resources.Designer.vb
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.vb
    │   │   └── Settings.settings
    │   ├── Strings.Designer.vb
    │   ├── Strings.en-GB.Designer.vb
    │   ├── Strings.en-GB.resx
    │   ├── Strings.resx
    │   ├── Strings.sv-SE.Designer.vb
    │   ├── Strings.sv-SE.resx
    │   ├── VbWpfApplication.vbproj
    │   └── packages.config
    ├── VbWpfApplication.sln
    ├── WPFLocalizeExtension.UnitTests/
    │   ├── ValueConvertersTests/
    │   │   ├── LocExtensionTests.cs
    │   │   └── StringFormatConverterTests.cs
    │   └── WPFLocalizeExtension.UnitTests.csproj
    └── XamlLocalizationTest.sln

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

================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [konne, seriousm]


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Code snipet, or better a small code example that shows the issue

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Enviroment (please complete the following information):**
 - OS: [e.g. iOS]
 - .NET Framework: [e.g. NET452, netcore30]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: nuget
  directory: "/src"
  schedule:
    interval: daily
    time: "08:00"
    timezone: Europe/Berlin
  target-branch: development

- package-ecosystem: "github-actions"
  directory: "/"
  schedule:
    # Check for updates to GitHub Actions every weekday
    interval: "daily"


================================================
FILE: .github/release-drafter.yml
================================================
categories:
  - title: 'Features'
    labels:
      - 'feature'
      - 'enhancement'
  - title: 'Bug Fixes'
    labels:
      - 'fix'
      - 'bugfix'
      - 'bug'
  - title: 'Maintenance'
    labels:
      - 'chore'
      - 'dependencies'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
  ## Changes

  $CHANGES


================================================
FILE: .github/workflows/compile.yml
================================================
name: .NET

on:
  push:
    branches: [ master, development ]
    paths-ignore:
      - '*.md'
      - 'docs/**'

  pull_request:
    branches: [ master, development ]
    paths-ignore:
      - '*.md'
      - 'docs/**'

  workflow_dispatch:
    branches: [ master, development ]
    paths-ignore:
      - '*.md'
      - 'docs/**'

jobs:
  build:
    runs-on: windows-latest

    steps:
    - name: checkout
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Fetch all history for all tags and branches
      run: |
        git fetch --prune

    - name: Setup MSBuild.exe
      uses: microsoft/setup-msbuild@v2

    - name: Cache Nuget
      uses: actions/cache@v4.0.2
      with:
        path: ~/.nuget/packages
        key: ${{ runner.os }}-nugetv1-${{ hashFiles('**/packages.lock.json') }}
        restore-keys: |
          ${{ runner.os }}-nugetv1-

    - name: Build
      working-directory: src
      run: |
        dotnet restore --disable-parallel
        # dotnet build --disable-parallel --configuration Release
        # can't use pure dotnet build because gitversion issues
        msbuild ${{ github.event.repository.name }}.csproj -verbosity:minimal /p:Configuration=Release /property:DisableGitVersionTask=true

        # add check for PR against master from development -> build preRelease to nuget
        # if merged into master -> build Release -> nuget
        # if: github.ref == 'refs/heads/master' || (startsWith(github.ref, 'refs/tags/') && contains(github.ref,'-alpha'))
        #/property:NugetAPIKey=${{ secrets.NugetAPIKey }}


================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish

on:
  release:
    types: [ published ]

jobs:
  build:
    runs-on: windows-latest

    steps:
    - name: checkout
      uses: actions/checkout@v4

    - name: Setup MSBuild.exe
      uses: microsoft/setup-msbuild@v2

    - name: Write Fullkey.snk
      uses: RollyPeres/base64-to-path@v1
      with:
        filePath: ${{ github.workspace }}/src/fullkey.snk
        encodedString: ${{ secrets.SIGNKEY }}

    - name: Create msbuild params
      run: |
        echo "::set-output name=params::${{ github.event.repository.name }}.csproj -verbosity:minimal /p:Configuration=Release /property:DisableGitVersionTask=true /property:GitVersion_NuGetVersion=${{ github.event.release.tag_name }} /property:Version=${{ github.event.release.tag_name }}"
      id: msbuild
    
    - name: add nuget API Key for releases
      if: "!github.event.release.prerelease"
      run: |
        echo "::set-output name=params::/property:NugetAPIKey=${{ secrets.NugetAPIKey }}"      
      id: apikey

    - name: Restore
      working-directory: src
      run: |
        dotnet restore --disable-parallel

    - name: Restore & Build & (Publish)
      working-directory: src
      run: |
        msbuild ${{ steps.msbuild.outputs.params }} ${{ steps.apikey.outputs.params }}
        rm -R .\obj\Release
        msbuild ${{ steps.msbuild.outputs.params }} ${{ steps.apikey.outputs.params }} /property:UnSigned=true

    - name: Upload Release Assets
      uses: softprops/action-gh-release@v2
      with:
        files: src/bin/Release/*.nupkg


================================================
FILE: .github/workflows/release-drafter.yaml
================================================
name: Release

on:
  push:
    branches: [ master ]
    paths:
      - 'src/**'
      - '.github/workflows/release-drafter.yml'

jobs:
  release:
    runs-on: ubuntu-latest

    steps:
    - name: checkout
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Fetch all history for all tags and branches
      run: |
        git fetch --prune

    - name: Install GitVersion
      uses: gittools/actions/gitversion/setup@v3.0.0
      with:
         versionSpec: '5.6.x'

    - name: Use GitVersion
      id: gitversion
      uses: gittools/actions/gitversion/execute@v3.0.0

    - name: create release
      id: create_release
      uses: release-drafter/release-drafter@v6
      with:
        tag: '${{ steps.gitversion.outputs.semVer }}'
        name: 'Release ${{ steps.gitversion.outputs.semVer }}'
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .gitignore
================================================
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
Sandbox
*Sandbox*
*.ncrunchsolution
*.xap
ClientBin/*
*.zip
*.pfx
Example.xlsx
packages/
.vs/
*.nupkg

# Jetbrain Rider Cache
.idea/ 

================================================
FILE: CONTRIBUTING.md
================================================
Thanks for reporting an issue!

Please keep in mind that this project is not actively developed and that @MrCircuit and I (@SeriousM) don't work full-time on it.

If you have a clue how to resolve the issue please try to resolve it yourself and send us a Pull Request including unit tests.

Open-Source means not only the "free" availability of source code, it also means that the users are free to contribute to it to make it better.

Thank you for your help and understanding.


================================================
FILE: LICENSE
================================================
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
================================================
# WPFLocalizeExtension
[![CodeFactor](https://www.codefactor.io/repository/github/xamlmarkupextensions/WPFLocalizeExtension/badge/master)](https://www.codefactor.io/repository/github/xamlmarkupextensions/WPFLocalizeExtension/overview/master)
[![Nuget](https://img.shields.io/nuget/v/WpfLocalizeExtension.svg)](https://www.nuget.org/packages/WpfLocalizeExtension)
![.NET](https://github.com/XAMLMarkupExtensions/WPFLocalizeExtension/workflows/.NET/badge.svg)
[![Join the chat at https://gitter.im/SeriousM/WPFLocalizationExtension](https://badges.gitter.im/SeriousM/WPFLocalizationExtension.svg)](https://gitter.im/SeriousM/WPFLocalizationExtension?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

#### ...is a really the easiest way to localize any type of DependencyProperties or native Properties on DependencyObjects since 2008!

## Supported Frameworks

* .Net Framework 4.0+
* .Net CORE 3.0+

## Installation

[NuGet Package](https://nuget.org/packages/WpfLocalizeExtension/)

```net
dotnet add package WPFLocalizationExtension
```

## Getting started

Coming soon

## Documentation & Tutorial:
[Documentation / Wiki](docs/README.md)

## Localization Tools:
[ResXManager (Visual Studio Plugin and StandAlone)](http://visualstudiogallery.msdn.microsoft.com/3b64e04c-e8de-4b97-8358-06c73a97cc68)  
[Zeta Resource Editor (Freeware)](http://www.zeta-resource-editor.com/index.html)

-----

## Products that use this Solution:

![](/docs/SAPLogo.gif) SAP Crystal Reports, Version for Visual Studio .NET

## License:
[MS-PL](https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE)


================================================
FILE: docs/BLoc-and-FELoc.md
================================================
# BLoc

This Extensions is a 

# FELoc

================================================
FILE: docs/FAQ.md
================================================
# FAQ

## Strong Name and signing

The current nuget is public signed, this is in general a good compromise, but there are sometimes issue like:

* "Could not load file or assembly 'WPFLocalizeExtension' ... Strong name signature could not be verified
    * xUnit can be solve with disable shadowCoping see #225
    * in general integrate [StrongNameSigner](https://github.com/brutaldev/StrongNameSigner)

There is also a long discussion here just some issues: #225 #150 #141 #110 #106


## Issued Design mode

We try to do our best to have the extension as best as possible working in Visual Studio Designer, but in some cases
this doesn't work even everything is fine. Here some points / steps that can help:
1. restart / reopen (xaml, sln, complete Visualt Studio)
2. remove cache (bin/obj dirs + %USERPROFILE%\AppData\Local\Microsoft\VisualStudio\\**[VS VERSION]**\Designer\ShadowCache)
3. check .net compile proj with any cpu or 32bit see #217


## Missing Keys

If you like to see what keys are not translated you can easily register to the following event.

```csharp
LocalizeDictionary.Instance.MissingKeyEvent += Instance_MissingKeyEvent;
```

The issue or bad design is that this is only triggered if you use the LocExtension, BLoc and not if you make codebehind translation.
If you do that you should use a different Event.

```csharp
LocalizeDictionary.Instance.GetLocalizedObject(....) 

LocalizeDictionary.Instance.DefaultProvider.ProviderError  += ...
```

## Binding cannot be changed after it has been used

Binding does not support any changes on Properties after it is bound the firts time. So if you like to do thinks like:

```xaml
{Binding Source={lex:Loc Foo}}
{Binding StringFormat={lex:Loc Bar}}
```
This will crash. For StringFormat use cases we have implemented a [StringFormatConverter](ValueConverters.md).

## Access modifier for resource assemblies
The LocalizationExtension will fail to look up a localized value, if the resource is compiled with its access modifier set to internal.
To set up the resource build tool to use a public access modifier, open the resource file and change the value of the field.

## NeutralResourcesLanguage in Assembly Manifest
The Assembly.cs contains sometimes the line _[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]_
which has side effects on resource lookups.

Please remove it.

## Bad ResX Filename
As long as you are using custom ResX files that are not located under the Properties folder
in your project you **may not call the file Resource**.
It will break the lookup mechanism for the resources.

## Startuptime for Available Cultures Search with Resx Provider
To reduce the full search through all cultures and all resx files if they are available per
culture you can set the searchlist of the culture. _ResxLocalizationProviderBase.SearchCultures_

<details><summary>Example</summary>
<p>
   
```csharp
 (LocalizeDictionary.Instance.DefaultProvider as ResxLocalizationProvider).SearchCultures =
                new List<System.Globalization.CultureInfo>()
                {
                    System.Globalization.CultureInfo.GetCultureInfo("de-de"),
                    System.Globalization.CultureInfo.GetCultureInfo("en"),
                    System.Globalization.CultureInfo.GetCultureInfo("he"),
                    System.Globalization.CultureInfo.GetCultureInfo("ar"),
                };
```

</p>
</details>


================================================
FILE: docs/Features.md
================================================
# Features:

* First of all: ITS FREE (and will stay free - refer to license section below)
* Obtain stable results in
	* WPF applications using .NET 3.5 and higher
	* Windows Phone 7.x/8.x applications
* **New:** Localization source/provider can be changed freely at arbitrary nodes
	* Use the Provider property in LocalizeDictionary to change the provider for the particular sub tree
	* Use the DefaultProvider property to set the provider for the whole application
	* Built-in RESX provider for resource file lookup (Default) - **fully backward compatible to older versions of this extension**
	* Interface for custom providers
	* Notification about provider changes and errors
	* Notification about resource changes
	* Get the list of all available cultures from a provider - or just take the bindable merged list from LocalizeDictionary
	* CSV provider project in the Tests folder as an example for custom providers
	* **Multiple UI thread support**
* BLoc Extension that derives from Binding to support binding scenarios
* Supports binding-like write style like "Text = {lex:LocText ResAssembly:ResFile:ResKey}"
	* Define a default assembly and / or resource file to reduce the key to ResAssembly::ResKey, ResFile:ResKey or even ResKey
	* Automatic key lookup: If no key is specified, the Name and Property Name of the target are used (e.g. MyButton_Content)
	* Default assembly, dictionary and culture can be changed dynamically at the RESX provider
	* Default assembly and dictionary inherit along the visual tree and can be redefined at each node
* It is available at designtime (MS Expression Blend 3.0 & 4.0, MS VisualStudio 2008 & 2010 & 2012
    * not for dynamic loaded assemblies which only can be found at runtime and as long the resource (.resx) is built at designtime
	* Even for Silverlight!
	* No extra preview application needed
	* Offers a DesignValue Property to support custom values during design mode
* Full support of various application scenarios
	* Works with normal dependency properties
	* Works with normal properties (e.g. Ribbon)
	* Works with control/data templates
* Various culture setup features
	* List of available cultures
	* Culture swapping by Commands (SetCultureCommand)
	* Works with the .resx-fallback mechanism (e.g. en-us -> en -> invariant culture)
	* Supports culture forcing (e.g. "this object has to be in english all the time")
	* Buffering allows fast switching of the language at runtime
	* Offers a design language for visual testing at designtime
	* Offers a "SpecificCulture" to use as IFormatProvider (e.g. (123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20" or "123,20")
	* Does not alter the culture on Thread.CurrentCulture or Thread.CurrentUICulture (can be changed easily)
* Code behind features:
	* Can be used in code behind to bind localized values to dynamic generated controls
	* Implements INotifyPropertyChanged for advanced use
	* Offers some functionality to check and get resource values in code behind (e.g. ResolveLocalizedValue)
* Easy to use
	* Can be used with any resource file (.resx) across all assemblies (also the dynamic loaded one at runtime)
	* Does not need any initializing process (like "call xyz to register a special localize dictionary")
	* Can localize any type of data type, as long a TypeConverter exists for it
* Example extensions included for
	* Formating e.g. "this is the '{0}' value" (not bindable at the moment)
	* Prefix and suffix values (currently with LocText extension)
	* Upper and lower Text
* Last, but not least
	* Does not create any memory leaks
	* Leaves the UID property untouched
	* Does not need an additional build task
	* Is in use in various productive systems

================================================
FILE: docs/GapText.md
================================================
# Gap Text

Use a multibinding with the [StringFormatConverter](ValueConverters.md).
The first **parameter** is the StringFormat
All others are parameter.
```XML
<element.Text>
    <MultiBinding Converter={lex:StringFormatConverter}>
        <lex:BLoc Path="assembly:resource:key" />
         <Binding Foo />
         <Binding Bar />
         <Binding ... />
    </MultiBinding>
</element.Text>
```

integrate [SmartFormat](https://github.com/axuno/SmartFormat/wiki) so that we have even a possibility to have real i18n with pluralization,...

================================================
FILE: docs/Installation-and-dependencies.md
================================================
### Installation

The library itself can be obtained by two ways: 

* If you just want to use it without the need of compiling it, use the NuGet package manager of your VisualStudio or download it directly from our [NuGet package](https://www.nuget.org/packages/WpfLocalizeExtension). 
* If you are interested in the project details, feel free to get your own copy of the source code from GitHub.

By using NuGet you just have to choose the projects where you want to use the extension - the rest is done automatically by NuGet as usual. 

### Dependencies

Starting with version 1.0.3, the project depends on the project [XAML Markup Extensions](https://github.com/XAMLMarkupExtensions/XAMLMarkupExtensions). NuGet will automatically ask you to download this package along with the LocalizationExtension.


================================================
FILE: docs/Keys.md
================================================
Keys are entered either directly after the extension name or using the Key property of the LocExtension class. Both will yield the same result (here with the key named Test):
```xaml
<Button Content="{lex:Loc Test}" />
<Button Content="{lex:Loc Key=Test}" />
```
### Automatic key retrieval
If the control already got or can get a value for its _Name_ or _x:Name_ property, the key may be neglected, provided, that a key exists that matches one of the following criteria (checked in exactly this order): 

* _ControlName_PropertyName_ 
* _ControlName_

Using our button example we could imagine the following scenario:
```xaml
<Button Name="MyButton" Content="{lex:Loc}" />
```
As no key was provided, the extension will first try to resolve a resource key named _MyButton_Content_. If this fails, it will then look for a resource key named _MyButton_. If this fails too, no value will be provided.

The separation character (default is underscore) can be individually set up for each control using the _LocalizeDictionary.Separation_ property.


================================================
FILE: docs/LocProxy-&-EnumComboBox.md
================================================
Beginning with v2.1.3 the extension also features an Enum value localization technique. To achieve this one has to employ the new **LocProxy** class. Just pass the particular enum value to the **Source** property and check the right setting of the **PrependType** flag. If this is used, you may also specify a **Separator** that will be used between the type suffix and the value itself leading to key entries like this "MyEnum_MyValue" using underscore as the separator. This allows us to create unique localization keys for different enum types and their values. To get the localized value, just bind your text element to the **Result** property of the **LocProxy**:
```xaml
<lex:LocProxy Source="{Binding}" x:Name="Proxy" PrependType="True" />
<TextBlock Text="{Binding Result, ElementName=Proxy}" Margin="2" FontWeight="Normal" />
```
In general, this proxy class triggers the _ToString_ function of the object that is bound to the **Source** property. It is therefore also applicable to all other kinds of objects where you need value localization.

To enhance this feature, also an **EnumComboBox** class was introduced with v2.1.3. Just feed your enum type to the **Type** property of this class and it does the rest for you, provided, that you correctly style the entries, e.g. using the XAML code snippet from above. You may also hide particular enum values using the **BrowsableAttribute**. A complete example is included in the _AssemblyTest_ example located in the source code of the library.

================================================
FILE: docs/Localization-providers.md
================================================
The project was restructured to separate the target identification and value conversion in the markup extension from the logic that actually provides the value by introducing the ILocalizationProvider interface. This enables us to plug in other provider services without touching the base, the LocExtension. 

![](Structure.png)

### Changing the provider
The provider can be changed using the **LocalizeDictionary.Provider** attached property at any node in the XAML document. Depending on the provider, a static singleton reference (e.g. resx provider) or an instance (e.g. csv provider) must be assigned to this property.

The default provider is set to the ResxLocalizationProvider. If you need another application wide default provider, just overwrite the static backed-up attached property **LocalizeDictionary.DefaultProvider**. 

### Provider features
Besides its localized look up functionality, providers can give you a list of available cultures. This observable collection can be read out or bound - whatever you need or prefer. The list is additionally observed by the LocalizeDictionary instance providing a merged bindable list of all available cultures.

Furthermore, providers fire events, when critical values in the provider changed (triggering an update of the LocExtension) or when an error occured. 

### Implementing custom providers
To implement your own provider, create a class that implements the ILocalizationProvider interface. There is no restriction concerning its base class.
```c#
public interface ILocalizationProvider
{
    /// <summary>
    /// Get the localized object.
    /// </summary>
    /// <param name="key">The key to the value.</param>
    /// <param name="target">The target <see cref="DependencyObject"/>.</param>
    /// <param name="culture">The culture to use.</param>
    /// <returns>The value corresponding to the key and culture.</returns>
    object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture);

    /// <summary>
    /// An observable list of available cultures.
    /// </summary>
    ObservableCollection<CultureInfo> AvailableCultures { get; }

    /// <summary>
    /// An event when the provider changed.
    /// </summary>
    event ProviderChangedEventHandler ProviderChanged;

    /// <summary>
    /// An event when an error occurred.
    /// </summary>
    event ProviderErrorEventHandler ProviderError;
}
```
You can then assign your own provider to the properties of LocalizeDictionary.

================================================
FILE: docs/Localization.md
================================================
Localization is the task to adapt values such as strings, colors or the text flow direction to the specific language and culture of the user. To fulfill this task, two major prerequisites are needed: 

* The designer has to decide **where** to apply a localized value. This means he needs a tool to mark the spot and to refer to a certain key in the translation dictionary. Note: Not all values have to be localized (e.g. usually the width of a control is calculated from the content size in an auto-layout application). 
* The designer and/or a translation agency has to fill out a cross-table containing all the keys mentioned above and values for each culture that should be supported by the application.

This project offers the tool to easily define which value has to be localized to the developer - already in design time. It even tries to find the right key if none is given thus speeding up localized XAML coding while still providing a good code readability.


================================================
FILE: docs/Localize.md
================================================
# Localize Resources

The main Extension that will be used is `{lex:Loc}` and is a Markupextension with a wide range usage.
For some use cases there it is not possible to use a Markupextension in XAML like Multibindings, Trigger, ...
there are substitutes [BLoc and FELoc](BLoc-and-FELoc.md) that try to fullfill the job, but they don't have 100% compatibility. 

```xaml
{lex:Loc Key=, ForceCulture=, Converter=, ConverterParameter=,}
```

| Parameter          | Description |
|--------------------|-------------|
| Key (default)      | the key for the resource for the resource lookup     |
| ForceCulture       | enforce a different culture for this resource lookup |
| Converter          | like Converter of Binding Class [see](https://docs.microsoft.com/de-de/dotnet/api/system.windows.data.binding.converter) |
| ConverterParameter | like ConverterParameter of Binding Class [see](https://docs.microsoft.com/de-de/dotnet/api/system.windows.data.binding.converter) |

## Key strategy

To make it for you as easy as possible and follow the "Don’t Repeat Yourself" (DRY) principle the Extension try find always the right key even if you just write `{lex:Loc}`
So you can find for example the following line in XAML:
```xaml
<Button x:Name="MyButton" Content="{lex:Loc}" ToolTip="{lex:Loc}" FontSize="{lex:Loc}"/>
```
But how does the magic work?

For a detailed explanation please red the [Key strategy](Keys.md) 

In the this example the Extension would look into the defaultassembly and then into the defaultressource and search for this 3 keys

| Property      | Requested Key     | Type    |
|---------------|-------------------|---------|
| Content=...   | MyButton_Content  | string  |
| ToolTip=...   | MyButton_ToolTip  | string  |
| FontSize=...  | MyButton_FontSize | double  |

If the resource has a different type the extensions try to convert is. This is more details describe in Target types.

## Target types
The LocExtension automatically retrieves the type of the target property and tries to find a _TypeConverter_ for this type. By additionally supplying a converter for _Bitmap_ (from resource files) to _BitmapSource_ (WPF) all normal cases should be covered. 
If you encounter an unsupported conversion, you have different options:
* provide a custom IValueConverter (Converter) along with a converter parameter
* feel free to write a working converter code and make a pull request to our GIT repository.

Enum types are supported in general and do not need any specific converter.

## Binding support for Enum / MVVM localization

If you have an enum or a MVVM use case there you need to have the key in the data model and like to use this as a key for the required resource
the extensions support to add the Binding as Constructor. Because of WPF restriction it is not possible to write it attach it to the key parameter (~~Key={Binding Path=Foo}~~). You have to add it as constructor without a property.

```xaml
{lex:Loc {Binding Path=Foo}}
```

This gives you the full flexibility because the Markupextensions is the pure Binding and this supports Converters, StringFormat, ...

### Enums

If you have now the following situation.

```csharp
public enum TestEnum
{
    Test1,
    Test2
}

...

public TestEnum Foo {get; set;}

... 

Foo = TestEnum.Test1;
```

and you bind this in the xaml with `{lex:Loc {Binding Path=Foo}}` the system will look to the key *Test1*
in the resources. This is okay but in the most cases you like to have a key like *TestEnum.Test1*.
RESX don't support key with dots so the common approach is to replace thge dot with an underscore to the
key *TestEnum_Test1*. To make this now working you have two options.

1. use `{lex:Loc {Binding Path=Foo, StringFormat=TestEnum_{0}}}` with the disadvantage that you have to manually type the TypeName of the enum and that refactoring is not working. On the otherhand you are fully free to change the key.
2. use `{lex:Loc {Binding Path=Foo, Converter={lex:PrependTypeConverter}}}` and get the automated prepending of the type to the key retreval process. This works also for any kind ot .net type, but we see at the moment only the use case for enums. For a details and the possibility to change the separation character read the details [ValueConverters](ValueConverters.md) doc.

### Gap texts / complex translation with pluralisation

For translation of complex texts there some value should be in the text like this:

>You have selected 10 car(s).

TWe have introduces a StringFormatConverter see [ValueConverters](ValueConverters.md) with automatic using of [smartFormat](https://github.com/axuno/SmartFormat) if this is available.
A detailed explanation how to use can be found [here](GapText.md). 



================================================
FILE: docs/MarkupExtension-basics.md
================================================
The project is based on the MarkupExtension class of the .NET framework. All classes that derive from this class are asked by the framework to deliver a value to the target object and property.

The LocalizationExtension uses this feature in order to provide the culture-specific values to localized properties. The general syntax of markup extensions that is applied to a particular _Property_ of a certain _Element_ is as follows:
```xaml
<Element Property="{ExtensionName ...}" />
```
The _ExtensionName_ has to be replaced by the class name of the extension without its ending "Extension". Usually, the XAML editor will propose the possible extensions to you. After the name, several properties of the extension itself can be initialized. It is obvious that this mechanism gives us the possibility to easily mark the localized property and give necessary information to look up its resource key.


================================================
FILE: docs/Multiple-assemblies-and-dictionaries.md
================================================
In the previous sections we presumed that a default assembly and dictionary indicating the location of the resource file is set up in the XAML document root. There may be situations, where more than one assembly and/or dictionary is used for a single XAML code file. This scenario is fully supported by the LocExtension and **ResxLocalizationProvider**. 

### Switching assemblies and dictionaries
You may change the values of **ResxLocalizationProvider.DefaultAssembly** and **ResxLocalizationProvider.DefaultDictionary** on arbitrary locations throughout the VisualTree of your XAML code - where and as often you need it. The various LocExtension instances will automatically resolve the corresponding values. This implies, that you may also change both values dynamically during runtime. Refer to the test application AssemblyTest in the source code of the library. 

### Directly provided assembly and/or dictionary
You may also define the assembly or dictionary that will be used at each instance of LocExtension by using their properties _Assembly_ or _Dict_ respectively. Alternatively, you may use the constructor syntax already described for the keys. The following three buttons will have the same text:
```xaml
<Button Content="{lex:Loc MyAssembly:MyResource:Test}" />
// If you need different Assembly or Dic you should use the attached properties of ResxLocalizationProvider
<Button Content="{lex:Loc Test}" />
<Button Content="{lex:Loc Key=Test}" />
```
### Assembly name differing from the default namespace
This scenario is supported by the ResxLocalizationProvider. In case you have several resource files in a single assembly with the same name but in different namespaces, you have to provide a qualified name of your dictionary.


================================================
FILE: docs/Our-first-localized-text.md
================================================
With the window or control control properly prepared in the previous section, we can now create our first localized text. Create a key named Test in your resource file(s) and give some distinct values to it (e.g. "Hello World" for culture "en" and "Hallo Welt" for culture "de").
Now, create a button with our extension set to the Content property:
```xaml
<Button Content="{lex:Loc Test}" />
```
Note, that Test was our key in the resource file. That's it - you're done!

### Target types
The LocExtension automatically retrieves the type of the target property and tries to find a _TypeConverter_ for this type. By additionally supplying a converter for _Bitmap_ (from resource files) to _BitmapSource_ (WPF) all normal cases should be covered. If you encounter an unsupported conversion, feel free to write a working converter code and make a pull request to our GIT repository. You may also provide a custom IValueConverter (Converter) along with a converter parameter in the LocExtension.
Enum types are supported in general and do not need any specific converter.


================================================
FILE: docs/Preparing-the-XAML-code.md
================================================
You have to initialize the localization engine in order to get values at design-time and to set up default dictionaries and assemblies (refer to [Multiple assemblies and dictionaries](Multiple-assemblies-and-dictionaries.md)).

First of all, create a _xmlns_ reference to "http://wpflocalizeextension.codeplex.com". The next step is to set the design time culture as well as default assembly and dictionary where the resource is located:
```xaml
<Window xmlns:lex="http://wpflocalizeextension.codeplex.com"
        lex:LocalizeDictionary.DesignCulture="en"
        lex:ResxLocalizationProvider.DefaultAssembly="AssemblyTestResourceLib"
        lex:ResxLocalizationProvider.DefaultDictionary="Strings">
<!-- Some controls -->
</Window>
```
The value of DesignCulture can be changed dynamically during design time and will have an immediate effect on all localized properties. This gives you the possibility to check the correct localization directly in the WPF designer. This example configures the resx provider. For a full explanation on this provider, refer to [Localization providers](Localization-providers.md).


================================================
FILE: docs/README.md
================================================
### Introduction
* [Localization](Localization.md) 
* [MarkupExtension basics](MarkupExtension-basics.md)
* [Supported platforms](Supported-platforms.md)
* [**Change log**](https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/releases)

### Usage
* [Installation and dependencies](Installation-and-dependencies.md)
* [Resource files](Resource-files.md)
* [Preparing the XAML code](Preparing-the-XAML-code.md)
* [Localize XAML](Localize.md)
* [Keys](Keys.md)
* [Multiple assemblies and dictionaries](Multiple-assemblies-and-dictionaries.md)
* [Localization providers](Localization-providers.md)
* DEPRECATED [LocProxy & EnumComboBox](LocProxy-&-EnumComboBox.md)

### [Common mistakes & FAQ](FAQ.md)

================================================
FILE: docs/Resource-files.md
================================================
### General instructions

As explained in the section [Supported platforms](Supported-platform.md), the LocalizationExtension supports **resx** files for the storage of localized values. Create such a resource file with a suitable name and check its access modifier, if needed (refer to [Common mistakes - Access modifier for resource assemblies](FAQ.md#access-modifier-for-resource-assemblies)). Now, create further resource files for each culture your application will support and give them the same name as the first one - just add the general or specific culture code (e.g. "en-US", "de", "de-AT", ...) before the ".resx" ending yielding: _Name.CultureCode_.resx. Don't forget the dot before the culture code.

Now, populate the resource files with your key/value pairs. Be sure to have the same name of a particular key for all cultures. You may use the automatic key retrieval mechanism (refer to [Keys](Keys.md)). 

### Pay attention to:
* The correct naming scheme of culture-specific resource files 
* The _Custom Tool_ property of the main resource file (ResXFileCodeGenerator), the others leave this field empty 
* The _Build_ Action property of all resource files (Embedded Resource) 
* The access modifier, if needed 
* Consistent key naming 
* **Rebuild** the project where the resource is located after adding new keys and values in order to see it in design time.

### How to get a treeview of culture-specific resources
1. Unload the project 
1. Edit the corresponding **csproj** file 
1. Locate the tags of the resources and rewrite them using the _DependentUpon_ syntax:
```xml
    <EmbeddedResource Include="Strings.de.resx">
      <SubType>Designer</SubType>
      <DependentUpon>Strings.resx</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Strings.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Strings.Designer.cs</LastGenOutput>
    </EmbeddedResource>
```

================================================
FILE: docs/Supported-platforms.md
================================================
The LocalizationExtension is designed for and tested under the following frameworks: 

* WPF with .NET 4.0+

The project comes along with the ability to plugin any custom localization provider that implements the _ILocalizationProvider_ interface. The support of resx of previous versions was transferred to such a provider that also serves as the default provider (can be changed, see [Localization providers](Localization-providers.md)). The resx files can be distributed over several assemblies in the project. As an example, another custom provider for CSV files was implemented.


================================================
FILE: docs/ValueConverters.md
================================================
# Value Converters

The library delivers some very usefull ValueConverts. All Valueconverters can be used with the standard syntax and the definition as resource, but the also implement a MarkupExtension declaration so that you can write as an example for the TranslateConverter:

```xaml
<Element Converter="{lex:TranslateConverter}" />
```

## TranslateConverter

This converters allows to make the translation process as a converter. The input of the converter is the key for the lookup and the result the translated result.

## PrependTypeConverter

This converter is especially for translation of enums. If you bind to an enum, only the
the Enum Value is used as key for the resource lookup. A commonn approach in the resx
file is to write like:
    MyEnum_Value1 -> Translation for Value1
    MyEnum_Value2 -> Translation for Value2

For a more elegant use this converter automatically prepend the Type of the parameter
to the key.

## StringFormatConverter

This converter solves the issue that Binding unfortunately don't support changing of the StringFormat after the firts usage of the Binding.
The StringFormatConverter expects as the first value the StringFormat and all further Values are given the StringFormat as paramter.
If [smartFormat](https://github.com/axuno/SmartFormat) is available it will be automatically used for the StringFormat for extended possibilities especially pluralisation.

## ToLower & ToUpperConverter

This converter just make an ToLower or ToUpper to the value. If you used the deprecated LocTextUpperExtension & LocTextLowerExtension this
this is the Converter to have the same effect.

================================================
FILE: src/Deprecated/Engine/GapTextControl.cs
================================================
#region Copyright information
// <copyright file="GapTextControl.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Peter Wendorff</author>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Engine
{
    #region Usings
    using System;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Markup;
    using System.Xml;
    #endregion

    /// <summary>
    /// A gap text control.
    /// </summary>
    [Obsolete("GapTextControl is deprecated and will be removed in version 4.0, see documentation",false)]
    [TemplatePart(Name = PART_TextBlock, Type = typeof(TextBlock))]
    public class GapTextControl : Control
    {
        #region Dependency Properties
        /// <summary>
        /// This property is the string that may contain gaps for controls.
        /// </summary>
        public static readonly DependencyProperty FormatStringProperty = DependencyProperty.Register(
            nameof(FormatString),
            typeof(string),
            typeof(GapTextControl),
            new PropertyMetadata(string.Empty, OnFormatStringChanged));

        /// <summary>
        /// If this property is set to true there is no error thrown
        /// when the FormatString contains less gaps than placeholders are available.
        /// Missing placeholders for available elements may be a problem,
        /// as something else may refer to the element in a binding e.g. by name,
        /// but the element is not available in the visual tree.
        ///
        /// As an example consider a submit button would be missing due to a missing placeholder in the FormatString.
        /// </summary>
        public static readonly DependencyProperty IgnoreLessGapsProperty = DependencyProperty.Register(
            nameof(IgnoreLessGaps),
            typeof(bool),
            typeof(GapTextControl),
            new PropertyMetadata(false));

        /// <summary>
        /// If this property is true, any FormatString that refers to the same string item multiple times produces an exception.
        /// </summary>
        public static readonly DependencyProperty IgnoreDuplicateStringReferencesProperty = DependencyProperty.Register(
            nameof(IgnoreDuplicateStringReferences),
            typeof(bool),
            typeof(GapTextControl),
            new PropertyMetadata(true));

        /// <summary>
        /// If this property is true, any FormatString that refers to the same control item multiple times produces an exception.
        /// </summary>
        public static readonly DependencyProperty IgnoreDuplicateControlReferencesProperty = DependencyProperty.Register(
            nameof(IgnoreDuplicateControlReferences),
            typeof(bool),
            typeof(GapTextControl),
            new PropertyMetadata(false));

        /// <summary>
        /// property that stores the items to be inserted into the gaps.
        /// any item that can be inserted as such into the TextBox get's inserted itself.
        /// All other items are converted to Text using their ToString() implementation.
        /// </summary>
        public static readonly DependencyProperty GapsProperty = DependencyProperty.Register(
            nameof(Gaps),
            typeof(ObservableCollection<object>),
            typeof(GapTextControl),
            new PropertyMetadata(default(ObservableCollection<object>), OnGapsChanged));

        private static void OnGapsChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            // TODO: make sure there's an event handler on CollectionChanged!

            // re-assemble children:
            if (dependencyPropertyChangedEventArgs.OldValue != dependencyPropertyChangedEventArgs.NewValue)
            {
                var self = (GapTextControl)dependencyObject;
                self.OnContentChanged();
            }
        }
        #endregion

        #region Constructors
        static GapTextControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GapTextControl), new FrameworkPropertyMetadata(typeof(GapTextControl)));
        }

        /// <summary>
        /// Creates a new instance.
        /// </summary>
        public GapTextControl()
        {
            Gaps = new ObservableCollection<object>();
            Gaps.CollectionChanged += (sender, args) => OnContentChanged();
        }
        #endregion

        #region Properties matching the DependencyProperties
        /// <summary>
        /// Gets or set the format string.
        /// </summary>
        public string FormatString
        {
            get => (string)GetValue(FormatStringProperty);
            set => SetValue(FormatStringProperty, value);
        }

        /// <summary>
        /// Ignore the Less Gaps
        /// </summary>
        public bool IgnoreLessGaps
        {
            get => (bool)GetValue(IgnoreLessGapsProperty);
            set => SetValue(IgnoreLessGapsProperty, value);
        }

        /// <summary>
        /// Ignore Duplicate String References
        /// </summary>
        public bool IgnoreDuplicateStringReferences
        {
            get => (bool)GetValue(IgnoreDuplicateStringReferencesProperty);
            set => SetValue(IgnoreDuplicateStringReferencesProperty, value);
        }

        /// <summary>
        /// Ignore Duplicate Control References
        /// </summary>
        public bool IgnoreDuplicateControlReferences
        {
            get => (bool)GetValue(IgnoreDuplicateControlReferencesProperty);
            set => SetValue(IgnoreDuplicateControlReferencesProperty, value);
        }

        /// <summary>
        /// Gets or sets the gap collection.
        /// </summary>
        public ObservableCollection<object> Gaps
        {
            get => (ObservableCollection<object>)GetValue(GapsProperty);
            set => SetValue(GapsProperty, value);
        }
        #endregion

        #region Constants
        /// <summary>
        /// Pattern to split the FormatString, see https://github.com/SeriousM/WPFLocalizationExtension/issues/78#issuecomment-163023915 for documentation ( TODO!!!)
        /// </summary>
        public const string RegexPattern = @"(.*?){(\d*)}";
        #endregion

        #region Constants for TemplateParts
        // ReSharper disable once InconsistentNaming
        private const string PART_TextBlock = "PART_TextBlock";
        #endregion

        #region Sub-Controls
        private TextBlock _theTextBlock = new TextBlock();
        #endregion

        #region DependencyProperty changed event handlers
        private static void OnFormatStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != e.NewValue)
            {
                var self = (GapTextControl)d;
                self.OnContentChanged();
            }
        }

        private static T DeepCopy<T>(T obj)
            where T : DependencyObject
        {
            var xaml = XamlWriter.Save(obj);
            var stringReader = new StringReader(xaml);
            var xmlTextReader = new XmlTextReader(stringReader);
            var result = (T)XamlReader.Load(xmlTextReader);

            var enumerator = obj.GetLocalValueEnumerator();
            while (enumerator.MoveNext())
            {
                var dp = enumerator.Current.Property;
                var be = BindingOperations.GetBindingExpression(obj, dp);
                if (be?.ParentBinding?.Path != null)
                    BindingOperations.SetBinding(result, dp, be.ParentBinding);
            }

            return result;
        }

        private void OnContentChanged()
        {
            // Re-arrange the children:
            _theTextBlock.Inlines.Clear();

            if (FormatString != null)
            {
                var matchedUpToIndex = 0;

                // 1) determine which items are to be used as string and which are to be inserted as controls:
                // allowed according to https://msdn.microsoft.com/de-de/library/system.windows.documents.inlinecollection%28v=vs.110%29.aspx are
                // Inline, String (creates an implicit Run), UIElement (creates an implicit InlineUIContainer with the supplied UIElement inside),
                if (Gaps != null)
                {
                    var match = Regex.Match(FormatString, RegexPattern);

                    while (match.Success)
                    {
                        // Handle match here...
                        var wholeMatch = match.Groups[0].Value; // contains string and simple placeholder at the end.
                        var formatStringPartial = match.Groups[1].Value;
                        // has still to be formatted TODO or even better bound accordingly by lex:loc binding
                        var itemIndex = int.Parse(match.Groups[2].Value);
                        // it's secure to parse an int here as this follows from the regex.

                        matchedUpToIndex += wholeMatch.Length;

                        // get next match:
                        match = match.NextMatch();

                        // add the inlines:
                        // 1) the prefix that is formatted with the whole gaps parameters:
                        _theTextBlock.Inlines.Add(string.Format(formatStringPartial, Gaps));

                        // Check availability of a classified gap.
                        if (Gaps.Count <= itemIndex)
                            continue;
                        var gap = Gaps[itemIndex];

                        // 2) the item encoded in the placeholder:
                        try
                        {
                            if (gap is UIElement element)
                            {
                                var item = DeepCopy(element);
                                _theTextBlock.Inlines.Add(item);
                            }
                            else if (gap is Inline)
                            {
                                var item = DeepCopy((Inline)gap);
                                _theTextBlock.Inlines.Add(item);
                            }
                            else if (gap != null)
                                _theTextBlock.Inlines.Add(gap.ToString());
                        }
                        catch (Exception)
                        {
                            // break for now
                        }
                    }
                }

                // add the remaining part:
                _theTextBlock.Inlines.Add(string.Format(FormatString.Substring(matchedUpToIndex), Gaps));

                InvalidateVisual();
            }
            else
            {
                throw new Exception("FormatString is not a string!");
            }
        }
        #endregion

        #region Template stuff
        /// <summary>
        /// Will be called prior to display of the control.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            AttachToVisualTree();
        }

        private void AttachToVisualTree()
        {
            if (Template != null)
            {
                var textBlock = Template.FindName(PART_TextBlock, this) as TextBlock;
                if (textBlock != _theTextBlock)
                {
                    _theTextBlock = textBlock;
                    OnContentChanged();
                }
            }
        }
        #endregion
    }
}

================================================
FILE: src/Deprecated/Engine/LocBinding.cs
================================================
#region Copyright information
// <copyright file="LocBinding.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Engine
{
    #region Usings
    using System;
    using System.Windows;
    using System.Windows.Data;
    using WPFLocalizeExtension.Extensions;
    #endregion

    /// <summary>
    /// A binding proxy class that accepts bindings and forwards them to the LocExtension.
    /// Based on: http://www.codeproject.com/Articles/71348/Binding-on-a-Property-which-is-not-a-DependencyPro
    /// </summary>
    [Obsolete("LocBinding is deprecated and will be removed in version 4.0, because lex:Loc supports now direct Binding, see documentation", false)]
    public class LocBinding : FrameworkElement
    {
        #region Source DP
        /// <summary>
        /// We don't know what will be the Source/target type so we keep 'object'.
        /// </summary>
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(object), typeof(LocBinding),
            new FrameworkPropertyMetadata(OnPropertyChanged)
            {
                BindsTwoWayByDefault = true,
                DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            });

        /// <summary>
        /// The source.
        /// </summary>
        public object Source
        {
            get => GetValue(SourceProperty);
            set => SetValue(SourceProperty, value);
        }
        #endregion

        #region Target LocExtension
        private LocExtension _target;
        /// <summary>
        /// The target extension.
        /// </summary>
        public LocExtension Target
        {
            get => _target;
            set
            {
                _target = value;
                if (_target != null && Source != null)
                    _target.Key = Source.ToString();
            }
        }
        #endregion

        #region OnPropertyChanged
        private static void OnPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is LocBinding locBinding && args.Property == SourceProperty)
            {
                if (!ReferenceEquals(locBinding.Source, locBinding._target) && locBinding._target != null && locBinding.Source != null)
                    locBinding._target.Key = locBinding.Source.ToString();
            }
        }
        #endregion
    }
}


================================================
FILE: src/Deprecated/Engine/LocProxy.cs
================================================
#region Copyright information
// <copyright file="LocBinding.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Engine
{
    #region Usings
    using System;
    using System.ComponentModel;
    using System.Windows;
    using WPFLocalizeExtension.Extensions;
    #endregion

    /// <summary>
    /// A proxy class to localize object strings.
    /// </summary>
    [Obsolete("LocProxy is deprecated and will be removed in version 4.0, because lex:Loc supports now direct Binding, see documentation", false)]
    public class LocProxy : FrameworkElement
    {
        /// <summary>
        /// Our own <see cref="LocExtension"/> instance.
        /// </summary>
        private LocExtension _ext;

        #region Source property
        /// <summary>
        /// The source.
        /// </summary>
        public static DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(object), typeof(LocProxy), new PropertyMetadata(PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="LocProxy.SourceProperty"/>
        /// </summary>
        [Category("Common")]
        public object Source
        {
            get => GetValue(SourceProperty);
            set => SetValue(SourceProperty, value);
        }
        #endregion

        #region PrependType property
        /// <summary>
        /// This flag determines, if the type should be added using the given separator.
        /// </summary>
        public static DependencyProperty PrependTypeProperty = DependencyProperty.Register("PrependType", typeof(bool), typeof(LocProxy), new PropertyMetadata(false, PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="PrependTypeProperty"/>
        /// </summary>
        [Category("Common")]
        public bool PrependType
        {
            get => (bool)GetValue(PrependTypeProperty);
            set => SetValue(PrependTypeProperty, value);
        }
        #endregion

        #region Separator property
        /// <summary>
        /// The Separator.
        /// </summary>
        public static DependencyProperty SeparatorProperty = DependencyProperty.Register("Separator", typeof(string), typeof(LocProxy), new PropertyMetadata("_", PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="SeparatorProperty"/>
        /// </summary>
        [Category("Common")]
        public string Separator
        {
            get => (string)GetValue(SeparatorProperty);
            set => SetValue(SeparatorProperty, value);
        }
        #endregion

        #region Prefix property
        /// <summary>
        /// The Prefix.
        /// </summary>
        public static DependencyProperty PrefixProperty = DependencyProperty.Register("Prefix", typeof(string), typeof(LocProxy), new PropertyMetadata(null, PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="PrefixProperty"/>
        /// </summary>
        [Category("Common")]
        public string Prefix
        {
            get => (string)GetValue(PrefixProperty);
            set => SetValue(PrefixProperty, value);
        }
        #endregion

        #region Readonly result property
        /// <summary>
        /// The result.
        /// </summary>
        public static DependencyPropertyKey ResultProperty = DependencyProperty.RegisterReadOnly("Result", typeof(string), typeof(LocProxy), new PropertyMetadata(""));

        /// <summary>
        /// The backing property for <see cref="ResultProperty"/>
        /// </summary>
        [Category("Common")]
        public string Result
        {
            get => (string)GetValue(ResultProperty.DependencyProperty) ?? this.Source.ToString();
            set => SetValue(ResultProperty, value);
        }
        #endregion

        /// <summary>
        /// A notification handler for the <see cref="SourceProperty"/>.
        /// </summary>
        /// <param name="d">The object.</param>
        /// <param name="e">The event arguments.</param>
        private static void PropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is LocProxy proxy)
            {
                var source = proxy.Source;
                if (source != null)
                {
                    var key = source.ToString();

                    if (proxy.PrependType)
                        key = source.GetType().Name + proxy.Separator + key;

                    if (!string.IsNullOrEmpty(proxy.Prefix))
                        key = proxy.Prefix + proxy.Separator + key;

                    if (proxy._ext == null)
                    {
                        proxy._ext = new LocExtension { Key = key };
                        proxy._ext.SetBinding(proxy, proxy.GetType().GetProperty("Result"));
                    }
                    else
                        proxy._ext.Key = key;
                }
            }
        }
    }
}

================================================
FILE: src/Deprecated/Extensions/Compatibility.cs
================================================
#region Copyright information
// <copyright file="Compatibility.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Extensions
{
    #region Usings
    using System;
    using System.Windows.Markup;
    using WPFLocalizeExtension.Engine;
    using WPFLocalizeExtension.Extensions;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <inheritdoc/>
    [Obsolete("LocBrushExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    [MarkupExtensionReturnType(typeof(System.Windows.Media.Brush))]
    public class LocBrushExtension : LocExtension
    {
        /// <inheritdoc/>
        public LocBrushExtension()
        { }

        /// <inheritdoc/>
        public LocBrushExtension(string key) : base(key) { }
    }

    /// <inheritdoc/>
    [Obsolete("LocDoubleExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    [MarkupExtensionReturnType(typeof(double))]
    public class LocDoubleExtension : LocExtension
    {
        /// <inheritdoc/>
        public LocDoubleExtension()
        { }

        /// <inheritdoc/>
        public LocDoubleExtension(string key) : base(key) { }
    }

    /// <inheritdoc/>
    [MarkupExtensionReturnType(typeof(System.Windows.FlowDirection))]
    [Obsolete("LocFlowDirectionExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    public class LocFlowDirectionExtension : LocExtension
    {
        /// <inheritdoc/>
        public LocFlowDirectionExtension()
        { }

        /// <inheritdoc/>
        public LocFlowDirectionExtension(string key) : base(key) { }
    }

    /// <inheritdoc/>
    [MarkupExtensionReturnType(typeof(System.Windows.Media.Imaging.BitmapSource))]
    [Obsolete("LocImageExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    public class LocImageExtension : LocExtension
    {
        /// <inheritdoc/>
        public LocImageExtension()
        { }

        /// <inheritdoc/>
        public LocImageExtension(string key) : base(key) { }
    }

    /// <inheritdoc/>
    [MarkupExtensionReturnType(typeof(string))]
    [Obsolete("LocTextExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    public class LocTextExtension : LocExtension
    {
        #region Constructors
        /// <inheritdoc/>
        public LocTextExtension()
        { }

        /// <inheritdoc/>
        public LocTextExtension(string key) : base(key) { }
        #endregion

        #region Enum Definition
        /// <summary>
        /// This enumeration is used to determine the type
        /// of the return value of <see cref="GetAppendText"/>
        /// </summary>
        protected enum TextAppendType
        {
            /// <summary>
            /// The return value is used as prefix
            /// </summary>
            Prefix,

            /// <summary>
            /// The return value is used as suffix
            /// </summary>
            Suffix
        }
        #endregion

        #region Variables
        /// <summary>
        /// Holds the local prefix value
        /// </summary>
        private string _prefix;

        /// <summary>
        /// Holds the local suffix value
        /// </summary>
        private string _suffix;

        /// <summary>
        /// Holds the local format segment array
        /// </summary>
        private readonly string[] _formatSegments = new string[5];
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets a prefix for the localized text
        /// </summary>
        public string Prefix
        {
            get => _prefix;
            set => _prefix = value;
        }

        /// <summary>
        /// Gets or sets a suffix for the localized text
        /// </summary>
        public string Suffix
        {
            get => _suffix;
            set => _suffix = value;
        }

        /// <summary>
        /// Gets or sets the format segment 1.
        /// This will be used to replace format place holders from the localized text.
        /// <see cref="LocTextLowerExtension"/> and <see cref="LocTextUpperExtension"/> will format this segment.
        /// </summary>
        /// <value>The format segment 1.</value>
        public string FormatSegment1
        {
            get => _formatSegments[0];
            set => _formatSegments[0] = value;
        }

        /// <summary>
        /// Gets or sets the format segment 2.
        /// This will be used to replace format place holders from the localized text.
        /// <see cref="LocTextUpperExtension"/> and <see cref="LocTextLowerExtension"/> will format this segment.
        /// </summary>
        /// <value>The format segment 2.</value>
        public string FormatSegment2
        {
            get => _formatSegments[1];
            set => _formatSegments[1] = value;
        }

        /// <summary>
        /// Gets or sets the format segment 3.
        /// This will be used to replace format place holders from the localized text.
        /// <see cref="LocTextUpperExtension"/> and <see cref="LocTextLowerExtension"/> will format this segment.
        /// </summary>
        /// <value>The format segment 3.</value>
        public string FormatSegment3
        {
            get => _formatSegments[2];
            set => _formatSegments[2] = value;
        }

        /// <summary>
        /// Gets or sets the format segment 4.
        /// This will be used to replace format place holders from the localized text.
        /// <see cref="LocTextUpperExtension"/> and <see cref="LocTextLowerExtension"/> will format this segment.
        /// </summary>
        /// <value>The format segment 4.</value>
        public string FormatSegment4
        {
            get => _formatSegments[3];
            set => _formatSegments[3] = value;
        }

        /// <summary>
        /// Gets or sets the format segment 5.
        /// This will be used to replace format place holders from the localized text.
        /// <see cref="LocTextUpperExtension"/> and <see cref="LocTextLowerExtension"/> will format this segment.
        /// </summary>
        /// <value>The format segment 5.</value>
        public string FormatSegment5
        {
            get => _formatSegments[4];
            set => _formatSegments[4] = value;
        }
        #endregion

        #region Text Formatting
        /// <summary>
        /// Returns the prefix or suffix text, depending on the supplied <see cref="TextAppendType"/>.
        /// If the prefix or suffix is null, it will be returned a string.empty.
        /// </summary>
        /// <param name="at">The <see cref="TextAppendType"/> defines the format of the return value</param>
        /// <returns>Returns the formated prefix or suffix</returns>
        private string GetAppendText(TextAppendType at)
        {
            // define a return value
            var retVal = string.Empty;

            // check if it should be a prefix, the format will be [PREFIX],
            // or check if it should be a suffix, the format will be [SUFFIX]
            if (at == TextAppendType.Prefix && !string.IsNullOrEmpty(_prefix))
            {
                retVal = _prefix ?? string.Empty;
            }
            else if (at == TextAppendType.Suffix && !string.IsNullOrEmpty(_suffix))
            {
                retVal = _suffix ?? string.Empty;
            }

            // return the formated prefix or suffix
            return retVal;
        }

        /// <summary>
        /// This method formats the localized text.
        /// If the passed target text is null, string.empty will be returned.
        /// </summary>
        /// <param name="target">The text to format.</param>
        /// <returns>Returns the formated text or string.empty, if the target text was null.</returns>
        protected virtual string FormatText(string target)
        {
            return target ?? string.Empty;
        }

        /// <inheritdoc/>
        public override object FormatOutput(TargetInfo endPoint, TargetInfo info)
        {
            var textMain = base.FormatOutput(endPoint, info) as string ?? string.Empty;

            try
            {
                // add some format segments, in case that the main text contains format place holders like {0}
                textMain = string.Format(
                    LocalizeDictionary.Instance.SpecificCulture,
                    textMain,
                    _formatSegments[0] ?? string.Empty,
                    _formatSegments[1] ?? string.Empty,
                    _formatSegments[2] ?? string.Empty,
                    _formatSegments[3] ?? string.Empty,
                    _formatSegments[4] ?? string.Empty);
            }
            catch (FormatException)
            {
                // if a format exception was thrown, change the text to an error string
                textMain = "TextFormatError: Max 5 Format PlaceHolders! {0} to {4}";
            }

            // get the prefix
            var textPrefix = GetAppendText(TextAppendType.Prefix);

            // get the suffix
            var textSuffix = GetAppendText(TextAppendType.Suffix);

            // format the text with prefix and suffix to [PREFIX]LocalizedText[SUFFIX]
            textMain = FormatText(textPrefix + textMain + textSuffix);

            return textMain;
        }
        #endregion
    }

    /// <inheritdoc/>
    [MarkupExtensionReturnType(typeof(string))]
    [Obsolete("LocTextLowerExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    public class LocTextLowerExtension : LocTextExtension
    {
        #region Constructors
        /// <inheritdoc/>
        public LocTextLowerExtension()
        { }

        /// <inheritdoc/>
        public LocTextLowerExtension(string key) : base(key) { }
        #endregion

        #region Text Formatting
        /// <inheritdoc/>
        protected override string FormatText(string target)
        {
            return target?.ToLower(GetForcedCultureOrDefault()) ?? string.Empty;
        }
        #endregion
    }

    /// <inheritdoc/>
    [MarkupExtensionReturnType(typeof(string))]
    [Obsolete("LocTextUpperExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    public class LocTextUpperExtension : LocTextExtension
    {
        #region Constructors
        /// <inheritdoc/>
        public LocTextUpperExtension()
        { }

        /// <inheritdoc/>
        public LocTextUpperExtension(string key) : base(key) { }
        #endregion

        #region Text Formatting
        /// <inheritdoc/>
        protected override string FormatText(string target)
        {
            return target?.ToUpper(GetForcedCultureOrDefault()) ?? string.Empty;
        }
        #endregion
    }

    /// <inheritdoc/>
    [MarkupExtensionReturnType(typeof(System.Windows.Thickness))]
    [Obsolete("LocThicknessExtension is deprecated and will be removed in version 4.0, please use lex:Loc instead and see documentation", false)]
    public class LocThicknessExtension : LocExtension
    {
        /// <inheritdoc/>
        public LocThicknessExtension()
        { }

        /// <inheritdoc/>
        public LocThicknessExtension(string key) : base(key) { }
    }
}


================================================
FILE: src/Deprecated/Providers/CSVEmbeddedLocalizationProvider.cs
================================================
#region Copyright information
// <copyright file="CSVEmbeddedLocalizationProvider.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Sébastien Sevrin</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Providers
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Resources;
    using System.Text;
    using System.Windows;
    using WPFLocalizeExtension.Engine;
    using WPFLocalizeExtension.Providers;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <summary>
    /// A singleton CSV provider that uses attached properties and the Parent property to iterate through the visual tree.
    /// </summary>
    [Obsolete("CSVEmbeddedLocalizationProvider is deprecated and will be removed in version 4.0, see documentation", false)]
    public class CSVEmbeddedLocalizationProvider : CSVLocalizationProviderBase
    {
        #region Dependency Properties
        /// <summary>
        /// <see cref="DependencyProperty"/> DefaultDictionary to set the fallback resource dictionary.
        /// </summary>
        public static readonly DependencyProperty DefaultDictionaryProperty =
                DependencyProperty.RegisterAttached(
                "DefaultDictionary",
                typeof(string),
                typeof(CSVEmbeddedLocalizationProvider),
                new PropertyMetadata(null, AttachedPropertyChanged));

        /// <summary>
        /// <see cref="DependencyProperty"/> DefaultAssembly to set the fallback assembly.
        /// </summary>
        public static readonly DependencyProperty DefaultAssemblyProperty =
            DependencyProperty.RegisterAttached(
                "DefaultAssembly",
                typeof(string),
                typeof(CSVEmbeddedLocalizationProvider),
                new PropertyMetadata(null, AttachedPropertyChanged));
        #endregion

        #region Dependency Property Callback
        /// <summary>
        /// Indicates, that one of the attached properties changed.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void AttachedPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            Instance.OnProviderChanged(obj);
        }
        #endregion

        #region Dependency Property Management
        #region Get
        /// <summary>
        /// Getter of <see cref="DependencyProperty"/> default dictionary.
        /// </summary>
        /// <param name="obj">The dependency object to get the default dictionary from.</param>
        /// <returns>The default dictionary.</returns>
        public static string GetDefaultDictionary(DependencyObject obj)
        {
            return obj.GetValueSync<string>(DefaultDictionaryProperty);
        }

        /// <summary>
        /// Getter of <see cref="DependencyProperty"/> default assembly.
        /// </summary>
        /// <param name="obj">The dependency object to get the default assembly from.</param>
        /// <returns>The default assembly.</returns>
        public static string GetDefaultAssembly(DependencyObject obj)
        {
            return obj.GetValueSync<string>(DefaultAssemblyProperty);
        }
        #endregion

        #region Set
        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> default dictionary.
        /// </summary>
        /// <param name="obj">The dependency object to set the default dictionary to.</param>
        /// <param name="value">The dictionary.</param>
        public static void SetDefaultDictionary(DependencyObject obj, string value)
        {
            obj.SetValueSync(DefaultDictionaryProperty, value);
        }

        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> default assembly.
        /// </summary>
        /// <param name="obj">The dependency object to set the default assembly to.</param>
        /// <param name="value">The assembly.</param>
        public static void SetDefaultAssembly(DependencyObject obj, string value)
        {
            obj.SetValueSync(DefaultAssemblyProperty, value);
        }
        #endregion
        #endregion

        #region Variables
        /// <summary>
        /// A dictionary for notification classes for changes of the individual target Parent changes.
        /// </summary>
        private readonly ParentNotifiers _parentNotifiers = new ParentNotifiers();
        #endregion

        #region Singleton Variables, Properties & Constructor
        /// <summary>
        /// The instance of the singleton.
        /// </summary>
        private static CSVEmbeddedLocalizationProvider _instance;

        /// <summary>
        /// Lock object for the creation of the singleton instance.
        /// </summary>
        private static readonly object InstanceLock = new object();

        /// <summary>
        /// Gets the <see cref="CSVEmbeddedLocalizationProvider"/> singleton.
        /// </summary>
        public static CSVEmbeddedLocalizationProvider Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (InstanceLock)
                    {
                        if (_instance == null)
                            _instance = new CSVEmbeddedLocalizationProvider();
                    }
                }

                // return the existing/new instance
                return _instance;
            }
        }

        /// <summary>
        /// The singleton constructor.
        /// </summary>
        private CSVEmbeddedLocalizationProvider()
        {
            ResourceManagerList = new Dictionary<string, ResourceManager>();
            AvailableCultures = new ObservableCollection<CultureInfo> { CultureInfo.InvariantCulture };
        }

        private bool _hasHeader;
        /// <summary>
        /// A flag indicating, if it has a header row.
        /// </summary>
        public bool HasHeader
        {
            get => _hasHeader;
            set => _hasHeader = value;
        }
        #endregion

        #region Abstract assembly & dictionary lookup
        /// <summary>
        /// An action that will be called when a parent of one of the observed target objects changed.
        /// </summary>
        /// <param name="obj">The target <see cref="DependencyObject"/>.</param>
        private void ParentChangedAction(DependencyObject obj)
        {
            OnProviderChanged(obj);
        }

        /// <summary>
        /// Get the assembly from the context, if possible.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>The assembly name, if available.</returns>
        protected override string GetAssembly(DependencyObject target)
        {
            return target?.GetValueOrRegisterParentNotifier<string>(DefaultAssemblyProperty, ParentChangedAction, _parentNotifiers);
        }

        /// <summary>
        /// Get the dictionary from the context, if possible.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>The dictionary name, if available.</returns>
        protected override string GetDictionary(DependencyObject target)
        {
            return target?.GetValueOrRegisterParentNotifier<string>(DefaultDictionaryProperty, ParentChangedAction, _parentNotifiers);
        }

        /// <summary>
        /// Get the localized object.
        /// </summary>
        /// <param name="key">The key to the value.</param>
        /// <param name="target">The target object.</param>
        /// <param name="culture">The culture to use.</param>
        /// <returns>The value corresponding to the source/dictionary/key path for the given culture (otherwise NULL).</returns>
        public override object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture)
        {
            string ret = null;

            var filename = "";

            // Call this function to provide backward compatibility.
            ParseKey(key, out var assembly, out var dictionary, out key);

            // Now try to read out the default assembly and/or dictionary.
            if (string.IsNullOrEmpty(assembly))
                assembly = GetAssembly(target);

            if (string.IsNullOrEmpty(dictionary))
                dictionary = GetDictionary(target);

            var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var assemblyInAppDomain in loadedAssemblies)
            {
                // get the assembly name object
                var assemblyName = new AssemblyName(assemblyInAppDomain.FullName);

                // check if the name of the assembly is the seached one
                if (assemblyName.Name == assembly)
                {
                    //filename = assemblyInAppDomain.GetManifestResourceNames().Where(r => r.Contains(dictionary)).FirstOrDefault();
                    filename = assemblyInAppDomain.GetManifestResourceNames().FirstOrDefault(r => r.Contains($"{dictionary}{(string.IsNullOrEmpty(culture.Name) ? "" : "-")}{culture.Name}"));
                    if (filename != null)
                    {
                        using (var reader = new StreamReader(assemblyInAppDomain.GetManifestResourceStream(filename) ?? throw new InvalidOperationException(), Encoding.Default))
                        {
                            if (HasHeader && !reader.EndOfStream)
                                reader.ReadLine();

                            // Read each line and split it.
                            while (!reader.EndOfStream)
                            {
                                var line = reader.ReadLine();
                                if (line != null)
                                {
                                    var parts = line.Split(";".ToCharArray());

                                    if (parts.Length < 2)
                                        continue;

                                    // Check the key (1st column).
                                    if (parts[0] != key)
                                        continue;

                                    // Get the value (2nd column).
                                    ret = parts[1];
                                }
                                break;
                            }
                        }
                    }
                }
            }

            // Nothing found -> Raise the error message.
            if (ret == null)
                OnProviderError(target, key, "The key does not exist in " + filename + ".");

            return ret;
        }
        #endregion
    }
}


================================================
FILE: src/Deprecated/Providers/CSVLocalizationProvider.cs
================================================
#region Copyright information
// <copyright file="CSVLocalizationProvider.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Sébastien Sevrin</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Providers
{
    #region Usings
    using System;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Windows;
    using WPFLocalizeExtension.Engine;
    using WPFLocalizeExtension.Providers;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <summary>
    /// A singleton CSV provider that uses attached properties and the Parent property to iterate through the visual tree.
    /// </summary>
    [Obsolete("CSVLocalizationProvider is deprecated and will be removed in version 4.0, see documentation", false)]
    public class CSVLocalizationProvider : CSVLocalizationProviderBase
    {
        #region Dependency Properties
        /// <summary>
        /// <see cref="DependencyProperty"/> DefaultDictionary to set the fallback resource dictionary.
        /// </summary>
        public static readonly DependencyProperty DefaultDictionaryProperty =
                DependencyProperty.RegisterAttached(
                "DefaultDictionary",
                typeof(string),
                typeof(CSVLocalizationProvider),
                new PropertyMetadata(null, AttachedPropertyChanged));
        #endregion

        #region Dependency Property Callback
        /// <summary>
        /// Indicates, that one of the attached properties changed.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void AttachedPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            Instance.OnProviderChanged(obj);
        }
        #endregion

        #region Dependency Property Management
        #region Get
        /// <summary>
        /// Getter of <see cref="DependencyProperty"/> default dictionary.
        /// </summary>
        /// <param name="obj">The dependency object to get the default dictionary from.</param>
        /// <returns>The default dictionary.</returns>
        public static string GetDefaultDictionary(DependencyObject obj)
        {
            return obj.GetValueSync<string>(DefaultDictionaryProperty);
        }
        #endregion

        #region Set
        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> default dictionary.
        /// </summary>
        /// <param name="obj">The dependency object to set the default dictionary to.</param>
        /// <param name="value">The dictionary.</param>
        public static void SetDefaultDictionary(DependencyObject obj, string value)
        {
            obj.SetValueSync(DefaultDictionaryProperty, value);
        }
        #endregion
        #endregion

        #region Variables
        /// <summary>
        /// A dictionary for notification classes for changes of the individual target Parent changes.
        /// </summary>
        private readonly ParentNotifiers _parentNotifiers = new ParentNotifiers();
        #endregion

        #region Singleton Variables, Properties & Constructor
        /// <summary>
        /// The instance of the singleton.
        /// </summary>
        private static CSVLocalizationProvider _instance;

        /// <summary>
        /// Lock object for the creation of the singleton instance.
        /// </summary>
        private static readonly object InstanceLock = new object();

        /// <summary>
        /// Gets the <see cref="CSVLocalizationProvider"/> singleton.
        /// </summary>
        public static CSVLocalizationProvider Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (InstanceLock)
                    {
                        if (_instance == null)
                            _instance = new CSVLocalizationProvider();
                    }
                }

                // return the existing/new instance
                return _instance;
            }
        }

        /// <summary>
        /// The singleton constructor.
        /// </summary>
        private CSVLocalizationProvider()
        {
            AvailableCultures = new ObservableCollection<CultureInfo> { CultureInfo.InvariantCulture };
        }

        private bool _hasHeader;
        /// <summary>
        /// A flag indicating, if it has a header row.
        /// </summary>
        public bool HasHeader
        {
            get => _hasHeader;
            set => _hasHeader = value;
        }
        #endregion

        #region Abstract dictionary lookup
        /// <summary>
        /// An action that will be called when a parent of one of the observed target objects changed.
        /// </summary>
        /// <param name="obj">The target <see cref="DependencyObject"/>.</param>
        private void ParentChangedAction(DependencyObject obj)
        {
            OnProviderChanged(obj);
        }

        /// <summary>
        /// Get the dictionary from the context, if possible.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>The dictionary name, if available.</returns>
        protected override string GetDictionary(DependencyObject target)
        {
            return target?.GetValueOrRegisterParentNotifier<string>(DefaultDictionaryProperty, ParentChangedAction, _parentNotifiers);
        }

        /// <summary>
        /// Get the assembly from the context, if possible.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>The assembly name, if available.</returns>
        protected override string GetAssembly(DependencyObject target)
        {
            return target?.GetValueOrRegisterParentNotifier<string>(CSVEmbeddedLocalizationProvider.DefaultAssemblyProperty, ParentChangedAction, _parentNotifiers);
        }

        /// <summary>
        /// Get the localized object.
        /// </summary>
        /// <param name="key">The key to the value.</param>
        /// <param name="target">The target object.</param>
        /// <param name="culture">The culture to use.</param>
        /// <returns>The value corresponding to the source/dictionary/key path for the given culture (otherwise NULL).</returns>
        public override object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture)
        {
            string ret = null;
            const string filename = "";

            // Call this function to provide backward compatibility.
            ParseKey(key, out _, out var dictionary, out key);

            // Now try to read out the default assembly and/or dictionary.
            if (string.IsNullOrEmpty(dictionary))
                dictionary = GetDictionary(target);

            // Try to get the culture specific file.
            const string csvDirectory = "Localization";
            var csvPath = "";

            while (culture != CultureInfo.InvariantCulture)
            {
                csvPath = Path.Combine(csvDirectory, dictionary + (string.IsNullOrEmpty(culture.Name) ? "" : "." + culture.Name) + ".csv");

                if (File.Exists(csvPath))
                    break;

                culture = culture.Parent;
            }

            if (!File.Exists(csvPath))
            {
                // Take the invariant culture.
                csvPath = Path.Combine(csvDirectory, dictionary + ".csv");

                if (!File.Exists(csvPath))
                {
                    OnProviderError(target, key, "A file for the provided culture " + culture.EnglishName + " does not exist at " + csvPath + ".");
                    return null;
                }
            }

            // Open the file.
            using (var reader = new StreamReader(csvPath, Encoding.Default))
            {
                // Skip the header if needed.
                if (HasHeader && !reader.EndOfStream)
                    reader.ReadLine();

                // Read each line and split it.
                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    if (line != null)
                    {
                        var parts = line.Split(";".ToCharArray());

                        if (parts.Length < 2)
                            continue;

                        // Check the key (1st column).
                        if (parts[0] != key)
                            continue;

                        // Get the value (2nd column).
                        ret = parts[1];
                    }
                    break;
                }
            }

            // Nothing found -> Raise the error message.
            if (ret == null)
                OnProviderError(target, key, "The key does not exist in " + filename + ".");

            return ret;
        }
        #endregion
    }
}


================================================
FILE: src/Deprecated/Providers/CSVLocalizationProviderBase.cs
================================================
#region Copyright information
// <copyright file="CSVLocalizationProviderBase.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Sébastien Sevrin</author>
#endregion

namespace WPFLocalizeExtension.Deprecated.Providers
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Reflection;
    using System.Resources;
    using System.Windows;
    using WPFLocalizeExtension.Providers;
    #endregion

    /// <summary>
    /// The base for CSV file providers.
    /// </summary>
    [Obsolete("CSVLocalizationProviderBase is deprecated and will be removed in version 4.0, see documentation", false)]
    public abstract class CSVLocalizationProviderBase : DependencyObject, ILocalizationProvider
    {
        #region Variables
        /// <summary>
        /// Gets the used ResourceManagers with their corresponding <c>namespaces</c>.
        /// </summary>
        protected Dictionary<string, ResourceManager> ResourceManagerList;

        /// <summary>
        /// Lock object for concurrent access to the resource manager list.
        /// </summary>
        protected object ResourceManagerListLock = new object();

        /// <summary>
        /// Lock object for concurrent access to the available culture list.
        /// </summary>
        protected object AvailableCultureListLock = new object();
        #endregion

        #region Helper functions
        /// <summary>
        /// Returns the <see cref="AssemblyName"/> of the passed assembly instance
        /// </summary>
        /// <param name="assembly">The Assembly where to get the name from</param>
        /// <returns>The Assembly name</returns>
        protected string GetAssemblyName(Assembly assembly)
        {
            if (assembly == null)
                throw new ArgumentNullException(nameof(assembly));

            if (assembly.FullName == null)
                throw new NullReferenceException("assembly.FullName is null");

            return assembly.FullName.Split(',')[0];
        }

        /// <summary>
        /// Parses a key ([[Assembly:]Dict:]Key and return the parts of it.
        /// </summary>
        /// <param name="inKey">The key to parse.</param>
        /// <param name="outAssembly">The found or default assembly.</param>
        /// <param name="outDict">The found or default dictionary.</param>
        /// <param name="outKey">The found or default key.</param>
        public static void ParseKey(string inKey, out string outAssembly, out string outDict, out string outKey)
        {
            // Reset everything to null.
            outAssembly = null;
            outDict = null;
            outKey = null;

            if (!string.IsNullOrEmpty(inKey))
            {
                var split = inKey.Trim().Split(":".ToCharArray());

                // assembly:dict:key
                if (split.Length == 3)
                {
                    outAssembly = !string.IsNullOrEmpty(split[0]) ? split[0] : null;
                    outDict = !string.IsNullOrEmpty(split[1]) ? split[1] : null;
                    outKey = split[2];
                }

                // dict:key
                if (split.Length == 2)
                {
                    outDict = !string.IsNullOrEmpty(split[0]) ? split[0] : null;
                    outKey = split[1];
                }

                // key
                if (split.Length == 1)
                    outKey = split[0];
            }
        }
        #endregion

        #region Abstract assembly & dictionary lookup
        /// <summary>
        /// Get the assembly from the context, if possible.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>The assembly name, if available.</returns>
        protected abstract string GetAssembly(DependencyObject target);

        /// <summary>
        /// Get the dictionary from the context, if possible.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>The dictionary name, if available.</returns>
        protected abstract string GetDictionary(DependencyObject target);
        #endregion

        #region Culture Management
        /// <summary>
        /// Thread-safe access to the AvailableCultures list.
        /// </summary>
        /// <param name="c">The CultureInfo.</param>
        protected void AddCulture(CultureInfo c)
        {
            lock (AvailableCultureListLock)
            {
                if (!AvailableCultures.Contains(c))
                    AvailableCultures.Add(c);
            }
        }
        #endregion

        #region ILocalizationProvider implementation
        /// <summary>
        /// Uses the key and target to build a fully qualified resource key (Assembly, Dictionary, Key)
        /// </summary>
        /// <param name="key">Key used as a base to find the full key</param>
        /// <param name="target">Target used to help determine key information</param>
        /// <returns>Returns an object with all possible pieces of the given key (Assembly, Dictionary, Key)</returns>
        public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(string key, DependencyObject target)
        {
            if (string.IsNullOrEmpty(key))
                return null;

            ParseKey(key, out var assembly, out var dictionary, out key);

            if (target == null)
                return new FQAssemblyDictionaryKey(key, assembly, dictionary);

            if (string.IsNullOrEmpty(assembly))
                assembly = GetAssembly(target);

            if (string.IsNullOrEmpty(dictionary))
                dictionary = GetDictionary(target);

            return new FQAssemblyDictionaryKey(key, assembly, dictionary);
        }

        /// <summary>
        /// Gets fired when the provider changed.
        /// </summary>
        public event ProviderChangedEventHandler ProviderChanged;

        /// <summary>
        /// An event that is fired when an error occurred.
        /// </summary>
        public event ProviderErrorEventHandler ProviderError;

        /// <summary>
        /// An event that is fired when a value changed.
        /// </summary>
        public event ValueChangedEventHandler ValueChanged;

        /// <summary>
        /// Calls the <see cref="ILocalizationProvider.ProviderChanged"/> event.
        /// </summary>
        /// <param name="target">The target object.</param>
        protected virtual void OnProviderChanged(DependencyObject target)
        {
            try
            {
                var assembly = GetAssembly(target);
                var dictionary = GetDictionary(target);

                //if (!String.IsNullOrEmpty(assembly) && !String.IsNullOrEmpty(dictionary))
                //    GetResourceManager(assembly, dictionary);
            }
            catch
            {
                // ignored
            }

            ProviderChanged?.Invoke(this, new ProviderChangedEventArgs(target));
        }

        /// <summary>
        /// Calls the <see cref="ILocalizationProvider.ProviderError"/> event.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <param name="key">The key.</param>
        /// <param name="message">The error message.</param>
        protected virtual void OnProviderError(DependencyObject target, string key, string message)
        {
            ProviderError?.Invoke(this, new ProviderErrorEventArgs(target, key, message));
        }

        /// <summary>
        /// Calls the <see cref="ILocalizationProvider.ValueChanged"/> event.
        /// </summary>
        /// <param name="key">The key where the value was changed.</param>
        /// <param name="value">The new value.</param>
        /// <param name="tag">A custom tag.</param>
        protected virtual void OnValueChanged(string key, object value, object tag)
        {
            ValueChanged?.Invoke(this, new ValueChangedEventArgs(key, value, tag));
        }

        /// <summary>
        /// Get the localized object.
        /// </summary>
        /// <param name="key">The key to the value.</param>
        /// <param name="target">The target object.</param>
        /// <param name="culture">The culture to use.</param>
        /// <returns>The value corresponding to the source/dictionary/key path for the given culture (otherwise NULL).</returns>
        public virtual object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture)
        {
            throw new InvalidOperationException("GetLocalizedObject needs to be overriden");
        }

        /// <summary>
        /// An observable list of available cultures.
        /// </summary>
        public ObservableCollection<CultureInfo> AvailableCultures { get; protected set; }
        #endregion
    }
}

================================================
FILE: src/Engine/EnumComboBox.cs
================================================
#region Copyright information
// <copyright file="EnumComboBox.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;
    #endregion

    /// <summary>
    /// An extended combobox that is enumerating Enum values.
    /// <para>Use the <see cref="T:System.ComponentModel.BrowsableAttribute" /> to hide specific entries.</para>
    /// </summary>
    public class EnumComboBox : ComboBox
    {
        #region Type property
        /// <summary>
        /// The Type.
        /// </summary>
        public static DependencyProperty TypeProperty = DependencyProperty.Register("Type", typeof(Type), typeof(EnumComboBox), new PropertyMetadata(TypeChanged));

        /// <summary>
        /// The backing property for <see cref="EnumComboBox.TypeProperty"/>
        /// </summary>
        [Category("Common")]
        public Type Type
        {
            get => (Type)GetValue(TypeProperty);
            set => SetValue(TypeProperty, value);
        }

        private static void TypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is EnumComboBox ecb))
                return;

            ecb.SetType(ecb.Type);
        }
        #endregion

        #region PrependType property
        /// <summary>
        /// This flag determines, if the type should be added using the given separator.
        /// </summary>
        public static DependencyProperty PrependTypeProperty = DependencyProperty.Register("PrependType", typeof(bool), typeof(EnumComboBox), new PropertyMetadata(false));

        /// <summary>
        /// The backing property for <see cref="EnumComboBox.PrependTypeProperty"/>
        /// </summary>
        [Category("Common")]
        public bool PrependType
        {
            get => (bool)GetValue(PrependTypeProperty);
            set => SetValue(PrependTypeProperty, value);
        }
        #endregion

        #region Separator property
        /// <summary>
        /// The Separator.
        /// </summary>
        public static DependencyProperty SeparatorProperty = DependencyProperty.Register("Separator", typeof(string), typeof(EnumComboBox), new PropertyMetadata("_"));

        /// <summary>
        /// The backing property for <see cref="EnumComboBox.SeparatorProperty"/>
        /// </summary>
        [Category("Common")]
        public string Separator
        {
            get => (string)GetValue(SeparatorProperty);
            set => SetValue(SeparatorProperty, value);
        }
        #endregion

        #region Prefix property
        /// <summary>
        /// The Prefix.
        /// </summary>
        public static DependencyProperty PrefixProperty = DependencyProperty.Register("Prefix", typeof(string), typeof(EnumComboBox), new PropertyMetadata(null));

        /// <summary>
        /// The backing property for <see cref="EnumComboBox.PrefixProperty"/>
        /// </summary>
        [Category("Common")]
        public string Prefix
        {
            get => (string)GetValue(PrefixProperty);
            set => SetValue(PrefixProperty, value);
        }
        #endregion

        #region XamlWriter Hack
        /// <summary>
        /// Overwrite and bypass the Items property.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new ItemCollection Items => base.Items;

        private bool _shouldSerializeTemplate;

        /// <inheritdoc/>
        protected override void OnItemTemplateChanged(DataTemplate oldItemTemplate, DataTemplate newItemTemplate)
        {
            if (oldItemTemplate != null)
                _shouldSerializeTemplate = true;

            base.OnItemTemplateChanged(oldItemTemplate, newItemTemplate);
        }

        /// <inheritdoc/>
        protected override bool ShouldSerializeProperty(DependencyProperty dp)
        {
            if (dp == ItemTemplateProperty && !_shouldSerializeTemplate)
                return false;

            return base.ShouldSerializeProperty(dp);
        }
        #endregion

        private void SetType(Type type)
        {
            try
            {
                var items = new List<object>();

                // First we need to get list of all enum fields
                var fields = type.GetFields();

                foreach (var field in fields)
                {
                    // Continue only for normal fields
                    if (field.IsSpecialName)
                        continue;

                    // Get the first BrowsableAttribute and add the item accordingly.
                    var attr = field.GetCustomAttributes(false).OfType<BrowsableAttribute>().FirstOrDefault();

                    if (attr == null || attr.Browsable)
                        items.Add(field.GetValue(0));
                }

                ItemsSource = items;
            }
            catch
            {
                // ignored
            }
        }

        /// <summary>
        /// Creates a new instance.
        /// </summary>
        public EnumComboBox()
        {
            var context = new ParserContext();

            context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            context.XmlnsDictionary.Add("lex", "http://wpflocalizeextension.codeplex.com");

            var xaml = "<DataTemplate><TextBlock><lex:EnumRun EnumValue=\"{Binding}\"";
            xaml += " PrependType=\"{Binding PrependType, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=lex:EnumComboBox}}\"";
            xaml += " Separator=\"{Binding Separator, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=lex:EnumComboBox}}\"";
            xaml += " Prefix=\"{Binding Prefix, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=lex:EnumComboBox}}\"";
            xaml += " /></TextBlock></DataTemplate>";

            ItemTemplate = (DataTemplate)XamlReader.Parse(xaml, context);
        }
    }
}


================================================
FILE: src/Engine/EnumRun.cs
================================================
#region Copyright information
// <copyright file="EnumRun.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Documents;
    using WPFLocalizeExtension.Extensions;
    #endregion

    /// <summary>
    /// An extension of <see cref="T:System.Windows.Documents.Run" /> for displaying localized enums.
    /// </summary>
    public class EnumRun : Run
    {
        /// <summary>
        /// Our own <see cref="LocExtension"/> instance.
        /// </summary>
        private LocExtension _ext;

        #region EnumValue property
        /// <summary>
        /// The EnumValue.
        /// </summary>
        public static DependencyProperty EnumValueProperty = DependencyProperty.Register("EnumValue", typeof(Enum), typeof(EnumRun), new PropertyMetadata(PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="EnumRun.EnumValueProperty"/>
        /// </summary>
        [Category("Common")]
        public Enum EnumValue
        {
            get => (Enum)GetValue(EnumValueProperty);
            set => SetValue(EnumValueProperty, value);
        }
        #endregion

        #region PrependType property
        /// <summary>
        /// This flag determines, if the type should be added using the given separator.
        /// </summary>
        public static DependencyProperty PrependTypeProperty = DependencyProperty.Register("PrependType", typeof(bool), typeof(EnumRun), new PropertyMetadata(false, PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="EnumRun.PrependTypeProperty"/>
        /// </summary>
        [Category("Common")]
        public bool PrependType
        {
            get => (bool)GetValue(PrependTypeProperty);
            set => SetValue(PrependTypeProperty, value);
        }
        #endregion

        #region Separator property
        /// <summary>
        /// The Separator.
        /// </summary>
        public static DependencyProperty SeparatorProperty = DependencyProperty.Register("Separator", typeof(string), typeof(EnumRun), new PropertyMetadata("_", PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="EnumRun.SeparatorProperty"/>
        /// </summary>
        [Category("Common")]
        public string Separator
        {
            get => (string)GetValue(SeparatorProperty);
            set => SetValue(SeparatorProperty, value);
        }
        #endregion

        #region Prefix property
        /// <summary>
        /// The Prefix.
        /// </summary>
        public static DependencyProperty PrefixProperty = DependencyProperty.Register("Prefix", typeof(string), typeof(EnumRun), new PropertyMetadata(null, PropertiesChanged));

        /// <summary>
        /// The backing property for <see cref="EnumRun.PrefixProperty"/>
        /// </summary>
        [Category("Common")]
        public string Prefix
        {
            get => (string)GetValue(PrefixProperty);
            set => SetValue(PrefixProperty, value);
        }
        #endregion

        #region PropertiesChanged
        /// <summary>
        /// A notification handler for changed properties.
        /// </summary>
        /// <param name="d">The object.</param>
        /// <param name="e">The event arguments.</param>
        private static void PropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is EnumRun run)
            {
                var value = run.EnumValue;
                if (value != null)
                {
                    var key = value.ToString();

                    if (run.PrependType)
                        key = value.GetType().Name + run.Separator + key;
                    if (!string.IsNullOrEmpty(run.Prefix))
                        key = run.Prefix + run.Separator + key;

                    if (run._ext == null)
                    {
                        run._ext = new LocExtension { Key = key };
                        run._ext.SetBinding(run, run.GetType().GetProperty("Text"));
                    }
                    else
                        run._ext.Key = key;
                }
            }
        }
        #endregion
    }
}


================================================
FILE: src/Engine/FallbackBehavior.cs
================================================
namespace WPFLocalizeExtension.Engine
{
    /// <summary>
    /// Behavior when key is not found at the localization provider.
    /// </summary>
    public enum FallbackBehavior
    {
        /// <summary>
        /// Display "Key: {key}" string.
        /// </summary>
        Default,
        
        /// <summary>
        /// Display key string itself.
        /// </summary>
        Key,
        
        /// <summary>
        /// Display an empty string.
        /// </summary>
        EmptyString
    }
}

================================================
FILE: src/Engine/IDictionaryEventListener.cs
================================================
#region Copyright information
// <copyright file="IDictionaryEventListener.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using System.Windows;
    #endregion

    /// <summary>
    /// Interface for listeners on dictionary events of the <see cref="LocalizeDictionary"/> class.
    /// </summary>
    public interface IDictionaryEventListener
    {
        /// <summary>
        /// This method is called when the resource somehow changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event arguments.</param>
        void ResourceChanged(DependencyObject sender, DictionaryEventArgs e);
    }

    /// <summary>
    /// An enumeration of dictionary event types.
    /// </summary>
    public enum DictionaryEventType
    {
        /// <summary>
        /// The separation changed.
        /// </summary>
        SeparationChanged,
        /// <summary>
        /// The provider changed.
        /// </summary>
        ProviderChanged,
        /// <summary>
        /// A provider reports an update.
        /// </summary>
        ProviderUpdated,
        /// <summary>
        /// The culture changed.
        /// </summary>
        CultureChanged,
        /// <summary>
        /// A certain value changed.
        /// </summary>
        ValueChanged,
    }

    /// <summary>
    /// Event argument for dictionary events.
    /// </summary>
    public class DictionaryEventArgs : EventArgs
    {
        /// <summary>
        /// The type of the event.
        /// </summary>
        public DictionaryEventType Type { get; }

        /// <summary>
        /// A corresponding tag.
        /// </summary>
        public object Tag { get; }

        /// <summary>
        /// The constructor.
        /// </summary>
        /// <param name="type">The type of the event.</param>
        /// <param name="tag">The corresponding tag.</param>
        public DictionaryEventArgs(DictionaryEventType type, object tag)
        {
            Type = type;
            Tag = tag;
        }

        /// <summary>
        /// Returns the type and tag as a string.
        /// </summary>
        /// <returns>The type and tag as a string.</returns>
        public override string ToString()
        {
            return Type + ": " + Tag;
        }
    }
}


================================================
FILE: src/Engine/ListenerList.cs
================================================
namespace WPFLocalizeExtension.Engine
{
    #region Usings
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    #endregion
    
    /// <summary>
    /// Represents a collection of listeners.
    /// </summary>
    internal class ListenersList
    {
        private readonly Dictionary<WeakReference, int> listeners;
        private readonly Dictionary<int, List<WeakReference>> listenersHashCodes;
        private readonly List<WeakReference> deadListeners;

        /// <summary>
        /// Create new empty <see cref="ListenersList" /> instance.
        /// </summary>
        public ListenersList()
        {
            listeners = new Dictionary<WeakReference, int>();
            listenersHashCodes = new Dictionary<int, List<WeakReference>>();
            deadListeners = new List<WeakReference>();
        }

        /// <summary>
        /// The count of listeners.
        /// </summary>
        public int Count => listeners.Count;

        /// <summary>
        /// Add new listener.
        /// </summary>
        public void AddListener(IDictionaryEventListener listener)
        {
            // Add listener if it not registered yet.
            var weakReference = new WeakReference(listener);
            var hashCode = listener.GetHashCode();
            if (!listenersHashCodes.TryGetValue(hashCode, out var sameHashCodeListeners))
            {
                listeners.Add(weakReference, hashCode);
                listenersHashCodes.Add(hashCode, new List<WeakReference> { weakReference });
            }
            else if (sameHashCodeListeners.All(wr => wr.Target != listener))
            {
                listeners.Add(weakReference, hashCode);
                sameHashCodeListeners.Add(weakReference);
            }
        }

        /// <summary>
        /// Get all alive listeners.
        /// </summary>
        public IEnumerable<IDictionaryEventListener> GetListeners()
        {
            try
            {
                foreach (var listener in listeners)
                {
                    var listenerReference = listener.Key.Target as IDictionaryEventListener;
                    if (listenerReference == null)
                    {
                        deadListeners.Add(listener.Key);
                        continue;
                    }

                    yield return listenerReference;
                }
            }
            finally
            {
                // Finally block is necessary because of `yield return`.
                // It guarantees this method will be called even if listeners won't enumerate till the end.
                ClearDeadReferences();
            }
        }

        /// <summary>
        /// Remove listener.
        /// </summary>
        public void RemoveListener(IDictionaryEventListener listener)
        {
            var hashCode = listener.GetHashCode();
            if (!listenersHashCodes.TryGetValue(hashCode, out var hashCodes))
                return;

            var wr = hashCodes.FirstOrDefault(l => l.Target == listener);
            if (wr == null)
                return;

            if (hashCodes.Count > 1)
                hashCodes.Remove(wr);
            else
                listenersHashCodes.Remove(hashCode);

            listeners.Remove(wr);
        }

        /// <summary>
        /// Clear internal list from all dead listeners.
        /// </summary>
        private void ClearDeadReferences()
        {
            if (deadListeners.Count == 0)
                return;
            
            foreach (var deadListener in deadListeners)
            {
                var hashCode = listeners[deadListener];
                listenersHashCodes[hashCode].Remove(deadListener);
                if (!listenersHashCodes[hashCode].Any())
                    listenersHashCodes.Remove(hashCode);

                listeners.Remove(deadListener);
            }

            deadListeners.Clear();
        }
    }
}

================================================
FILE: src/Engine/LocalizeDictionary.cs
================================================
#region Copyright information
// <copyright file="LocalizeDictionary.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Threading;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Threading;
    using WPFLocalizeExtension.Extensions;
    using WPFLocalizeExtension.Providers;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <summary>
    /// Represents the culture interface for localization
    /// </summary>
    public sealed class LocalizeDictionary : DependencyObject, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Implementation
        /// <summary>
        /// Informiert über sich ändernde Eigenschaften.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notify that a property has changed
        /// </summary>
        /// <param name="property">
        /// The property that changed
        /// </param>
        internal void RaisePropertyChanged(string property)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
        }
        #endregion

        #region Dependency Properties
        /// <summary>
        /// <see cref="DependencyProperty"/> DefaultProvider to set the default ILocalizationProvider.
        /// </summary>
        public static readonly DependencyProperty DefaultProviderProperty =
            DependencyProperty.RegisterAttached(
                "DefaultProvider",
                typeof(ILocalizationProvider),
                typeof(LocalizeDictionary),
                new PropertyMetadata(null, SetDefaultProviderFromDependencyProperty));

        /// <summary>
        /// <see cref="DependencyProperty"/> Provider to set the ILocalizationProvider.
        /// </summary>
        public static readonly DependencyProperty ProviderProperty =
            DependencyProperty.RegisterAttached(
                "Provider",
                typeof(ILocalizationProvider),
                typeof(LocalizeDictionary),
                new PropertyMetadata(null, SetProviderFromDependencyProperty));

        /// <summary>
        /// <see cref="DependencyProperty"/> DesignCulture to set the Culture.
        /// Only supported at DesignTime.
        /// </summary>
        [DesignOnly(true)]
        public static readonly DependencyProperty DesignCultureProperty =
            DependencyProperty.RegisterAttached(
                "DesignCulture",
                typeof(string),
                typeof(LocalizeDictionary),
                new PropertyMetadata(SetCultureFromDependencyProperty));

        /// <summary>
        /// <see cref="DependencyProperty"/> Separation to set the separation character/string for resource name patterns.
        /// </summary>
        public static readonly DependencyProperty SeparationProperty =
            DependencyProperty.RegisterAttached(
                "Separation",
                typeof(string),
                typeof(LocalizeDictionary),
                new PropertyMetadata(DefaultSeparation, SetSeparationFromDependencyProperty));

        /// <summary>
        /// A flag indicating that the invariant culture should be included.
        /// </summary>
        public static readonly DependencyProperty IncludeInvariantCultureProperty =
            DependencyProperty.RegisterAttached(
                "IncludeInvariantCulture",
                typeof(bool),
                typeof(LocalizeDictionary),
                new PropertyMetadata(true, SetIncludeInvariantCultureFromDependencyProperty));

        /// <summary>
        /// A flag indicating that the cache is disabled.
        /// </summary>
        public static readonly DependencyProperty DisableCacheProperty =
            DependencyProperty.RegisterAttached(
                "DisableCache",
                typeof(bool),
                typeof(LocalizeDictionary),
                new PropertyMetadata(false, SetDisableCacheFromDependencyProperty));

        /// <summary>
        /// A flag indicating that missing keys should be output.
        /// </summary>
        public static readonly DependencyProperty OutputMissingKeysProperty =
            DependencyProperty.RegisterAttached(
                "OutputMissingKeys",
                typeof(bool),
                typeof(LocalizeDictionary),
                new PropertyMetadata(true, SetOutputMissingKeysFromDependencyProperty));
        #endregion

        #region Dependency Property Callbacks
        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.Culture if set in Xaml.
        /// Only supported at DesignTime.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        [DesignOnly(true)]
        private static void SetCultureFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (!Instance.GetIsInDesignMode())
                return;

            CultureInfo culture;

            try
            {
                culture = new CultureInfo((string)args.NewValue);
            }
            catch
            {
                if (Instance.GetIsInDesignMode())
                    culture = DefaultCultureInfo;
                else
                    throw;
            }

            if (culture != null)
                Instance.Culture = culture;
        }

        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.Provider if set in Xaml.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void SetProviderFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            DictionaryEvent.Invoke(obj, new DictionaryEventArgs(DictionaryEventType.ProviderChanged, args.NewValue));

            if (args.OldValue is ILocalizationProvider oldProvider)
            {
                oldProvider.ProviderChanged -= ProviderUpdated;
                oldProvider.ValueChanged -= ValueChanged;
                oldProvider.AvailableCultures.CollectionChanged -= Instance.AvailableCulturesCollectionChanged;
            }

            if (args.NewValue is ILocalizationProvider provider)
            {
                provider.ProviderChanged += ProviderUpdated;
                provider.ValueChanged += ValueChanged;
                provider.AvailableCultures.CollectionChanged += Instance.AvailableCulturesCollectionChanged;

                foreach (var c in provider.AvailableCultures)
                    if (!Instance.MergedAvailableCultures.Contains(c))
                        Instance.MergedAvailableCultures.Add(c);
            }
        }

        private static void ProviderUpdated(object sender, ProviderChangedEventArgs args)
        {
            DictionaryEvent.Invoke(args.Object, new DictionaryEventArgs(DictionaryEventType.ProviderUpdated, sender));
        }

        private static void ValueChanged(object sender, ValueChangedEventArgs args)
        {
            DictionaryEvent.Invoke(null, new DictionaryEventArgs(DictionaryEventType.ValueChanged, args));
        }

        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.DefaultProvider if set in Xaml.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void SetDefaultProviderFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue is ILocalizationProvider provider)
                Instance.DefaultProvider = provider;
        }

        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.Separation if set in Xaml.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void SetSeparationFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
        }

        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.IncludeInvariantCulture if set in Xaml.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void SetIncludeInvariantCultureFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue is bool b)
                Instance.IncludeInvariantCulture = b;
        }

        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.DisableCache if set in Xaml.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void SetDisableCacheFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue is bool b)
                Instance.DisableCache = b;
        }

        /// <summary>
        /// Callback function. Used to set the <see cref="LocalizeDictionary"/>.OutputMissingKeys if set in Xaml.
        /// </summary>
        /// <param name="obj">The dependency object.</param>
        /// <param name="args">The event argument.</param>
        private static void SetOutputMissingKeysFromDependencyProperty(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue is bool b)
                Instance.OutputMissingKeys = b;
        }
        #endregion

        #region Dependency Property Management
        #region Get
        /// <summary>
        /// Getter of <see cref="DependencyProperty"/> Provider.
        /// </summary>
        /// <param name="obj">The dependency object to get the provider from.</param>
        /// <returns>The provider.</returns>
        public static ILocalizationProvider GetProvider(DependencyObject obj)
        {
            return obj.GetValueSync<ILocalizationProvider>(ProviderProperty);
        }

#pragma warning disable IDE0060
        /// <summary>
        /// Getter of <see cref="DependencyProperty"/> DefaultProvider.
        /// </summary>
        /// <param name="obj">The dependency object to get the default provider from.</param>
        /// <returns>The default provider.</returns>
        public static ILocalizationProvider GetDefaultProvider(DependencyObject obj)
        {
            return Instance.DefaultProvider;
        }

        /// <summary>
        /// Tries to get the separation from the given target object or of one of its parents.
        /// </summary>
        /// <param name="target">The target object for context.</param>
        /// <returns>The separation of the given context or the default.</returns>
        public static string GetSeparation(DependencyObject target)
        {
            return Instance.Separation;
        }

        /// <summary>
        /// Tries to get the flag from the given target object or of one of its parents.
        /// </summary>
        /// <param name="target">The target object for context.</param>
        /// <returns>The flag.</returns>
        public static bool GetIncludeInvariantCulture(DependencyObject target)
        {
            return Instance.IncludeInvariantCulture;
        }

        /// <summary>
        /// Tries to get the flag from the given target object or of one of its parents.
        /// </summary>
        /// <param name="target">The target object for context.</param>
        /// <returns>The flag.</returns>
        public static bool GetDisableCache(DependencyObject target)
        {
            return Instance.DisableCache;
        }

        /// <summary>
        /// Tries to get the flag from the given target object or of one of its parents.
        /// </summary>
        /// <param name="target">The target object for context.</param>
        /// <returns>The flag.</returns>
        public static bool GetOutputMissingKeys(DependencyObject target)
        {
            return Instance.OutputMissingKeys;
        }
#pragma warning restore IDE0060

        /// <summary>
        /// Getter of <see cref="DependencyProperty"/> DesignCulture.
        /// Only supported at DesignTime.
        /// If its in Runtime, <see cref="LocalizeDictionary"/>.Culture will be returned.
        /// </summary>
        /// <param name="obj">The dependency object to get the design culture from.</param>
        /// <returns>The design culture at design time or the current culture at runtime.</returns>
        [DesignOnly(true)]
        public static string GetDesignCulture(DependencyObject obj)
        {
            if (Instance.GetIsInDesignMode())
                return obj.GetValueSync<string>(DesignCultureProperty);

            return Instance.Culture.ToString();
        }
        #endregion

        #region Set
        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> Provider.
        /// </summary>
        /// <param name="obj">The dependency object to set the provider to.</param>
        /// <param name="value">The provider.</param>
        public static void SetProvider(DependencyObject obj, ILocalizationProvider value)
        {
            obj.SetValueSync(ProviderProperty, value);
        }

#pragma warning disable IDE0060
        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> DefaultProvider.
        /// </summary>
        /// <param name="obj">The dependency object to set the default provider to.</param>
        /// <param name="value">The default provider.</param>
        public static void SetDefaultProvider(DependencyObject obj, ILocalizationProvider value)
        {
            Instance.DefaultProvider = value;
        }

        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> Separation.
        /// </summary>
        /// <param name="obj">The dependency object to set the separation to.</param>
        /// <param name="value">The separation.</param>
        public static void SetSeparation(DependencyObject obj, string value)
        {
            Instance.Separation = value;
        }

        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> IncludeInvariantCulture.
        /// </summary>
        /// <param name="obj">The dependency object to set the separation to.</param>
        /// <param name="value">The flag.</param>
        public static void SetIncludeInvariantCulture(DependencyObject obj, bool value)
        {
            Instance.IncludeInvariantCulture = value;
        }

        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> DisableCache.
        /// </summary>
        /// <param name="obj">The dependency object to set the separation to.</param>
        /// <param name="value">The flag.</param>
        public static void SetDisableCache(DependencyObject obj, bool value)
        {
            Instance.DisableCache = value;
        }

        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> OutputMissingKeys.
        /// </summary>
        /// <param name="obj">The dependency object to set the separation to.</param>
        /// <param name="value">The flag.</param>
        public static void SetOutputMissingKeys(DependencyObject obj, bool value)
        {
            Instance.OutputMissingKeys = value;
        }
#pragma warning restore IDE0060

        /// <summary>
        /// Setter of <see cref="DependencyProperty"/> DesignCulture.
        /// Only supported at DesignTime.
        /// </summary>
        /// <param name="obj">The dependency object to set the culture to.</param>
        /// <param name="value">The value.</param>
        [DesignOnly(true)]
        public static void SetDesignCulture(DependencyObject obj, string value)
        {
            if (Instance.GetIsInDesignMode())
                obj.SetValueSync(DesignCultureProperty, value);
        }
        #endregion
        #endregion

        #region Variables
        /// <summary>
        /// Holds a SyncRoot to be thread safe
        /// </summary>
        private static readonly object SyncRoot = new object();

        /// <summary>
        /// Holds the instance of singleton
        /// </summary>
        private static LocalizeDictionary _instance;

        /// <summary>
        /// Holds the current chosen <see cref="CultureInfo"/>
        /// </summary>
        private CultureInfo _culture;

        /// <summary>
        /// Holds the separation char/string.
        /// </summary>
        private string _separation = DefaultSeparation;

        /// <summary>
        /// Determines, if the <see cref="MergedAvailableCultures"/> contains the invariant culture.
        /// </summary>
        private bool _includeInvariantCulture = true;

        /// <summary>
        /// Determines, if the cache is disabled.
        /// </summary>
        private bool _disableCache = true;

        /// <summary>
        /// Determines, if missing keys should be output.
        /// </summary>
        private bool _outputMissingKeys = true;

        /// <summary>
        /// A default provider.
        /// </summary>
        private ILocalizationProvider _defaultProvider;

        /// <summary>
        /// Determines, if the CurrentThread culture is set along with the Culture property.
        /// </summary>
        private bool _setCurrentThreadCulture = true;

        /// <summary>
        /// Determines if the code is run in DesignMode or not.
        /// </summary>
        private bool? _isInDesignMode;

        #endregion

        #region Constructor
        /// <summary>
        /// Prevents a default instance of the <see cref="T:WPFLocalizeExtension.Engine.LocalizeDictionary" /> class from being created.
        /// Static Constructor
        /// </summary>
        private LocalizeDictionary()
        {
            DefaultProvider = ResxLocalizationProvider.Instance;
            SetCultureCommand = new CultureInfoDelegateCommand(SetCulture);
        }

        private void AvailableCulturesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            Dispatcher.BeginInvoke(new Action<NotifyCollectionChangedEventArgs>(args =>
            {
                if (args.NewItems != null)
                {
                    foreach (CultureInfo c in args.NewItems)
                    {
                        if (!MergedAvailableCultures.Contains(c))
                            MergedAvailableCultures.Add(c);
                    }
                }

                if (args.OldItems != null)
                {
                    foreach (CultureInfo c in args.OldItems)
                    {
                        if (MergedAvailableCultures.Contains(c))
                            MergedAvailableCultures.Remove(c);
                    }
                }

                if (!_includeInvariantCulture && MergedAvailableCultures.Count > 1 && MergedAvailableCultures.Contains(CultureInfo.InvariantCulture))
                    MergedAvailableCultures.Remove(CultureInfo.InvariantCulture);
            }), e);
        }

        /// <summary>
        /// Destructor code.
        /// </summary>
        ~LocalizeDictionary()
        {
            LocExtension.ClearResourceBuffer();
            FELoc.ClearResourceBuffer();
            BLoc.ClearResourceBuffer();
        }
        #endregion

        #region Static Properties
        /// <summary>
        /// Gets the default <see cref="CultureInfo"/> to initialize the <see cref="LocalizeDictionary"/>.<see cref="CultureInfo"/>
        /// </summary>
        public static CultureInfo DefaultCultureInfo => CultureInfo.InvariantCulture;

        /// <summary>
        /// Gets the default separation char/string.
        /// </summary>
        public static string DefaultSeparation => "_";

        /// <summary>
        /// Gets the <see cref="LocalizeDictionary"/> singleton.
        /// If the underlying instance is null, a instance will be created.
        /// </summary>
        public static LocalizeDictionary Instance
        {
            get
            {
                // check if the underlying instance is null
                if (_instance == null)
                {
                    // if it is null, lock the syncroot.
                    // if another thread is accessing this too,
                    // it have to wait until the syncroot is released
                    lock (SyncRoot)
                    {
                        // check again, if the underlying instance is null
                        if (_instance == null)
                        {
                            // create a new instance
                            _instance = new LocalizeDictionary();
                        }
                    }
                }

                // return the existing/new instance
                return _instance;
            }
        }

        /// <summary>
        /// Gets the culture of the singleton instance.
        /// </summary>
        public static CultureInfo CurrentCulture => Instance.Culture;

        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the <see cref="CultureInfo"/> for localization.
        /// On set, <see cref="DictionaryEvent"/> is raised.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">
        /// You have to set <see cref="LocalizeDictionary"/>.Culture first or
        /// wait until System.Windows.Application.Current.MainWindow is created.
        /// Otherwise you will get an Exception.</exception>
        /// <exception cref="System.ArgumentNullException">thrown if Culture will be set to null</exception>
        public CultureInfo Culture
        {
            get
            {
                if (_culture == null)
                    _culture = DefaultCultureInfo;

                return _culture;
            }

            set
            {
                // the cultureinfo cannot contain a null reference
                if (value == null)
                    value = DefaultCultureInfo;

                // Let's see if we already got this culture
                var newCulture = value;

                if (!GetIsInDesignMode())
                {
                    foreach (var c in MergedAvailableCultures)
                        if (c == CultureInfo.InvariantCulture && !IncludeInvariantCulture)
                            continue;
                        else if (c.Name == value.Name)
                        {
                            newCulture = c;
                            break;
                        }
                        else if (c.Parent.Name == value.Name)
                        {
                            // We found a parent culture, but continue - maybe there is a specific one available too.
                            newCulture = c;
                        }
                        else if (value.Parent.Name == c.Name)
                        {
                            // We found a parent culture, but continue - maybe there is a specific one available too.
                            newCulture = value;
                        }
                }

                if (_culture != newCulture)
                {
                    if (newCulture != null && !MergedAvailableCultures.Contains(newCulture))
                        MergedAvailableCultures.Add(newCulture);

                    _culture = newCulture;

                    // Change the CurrentThread culture if needed.
                    if (_setCurrentThreadCulture && !GetIsInDesignMode())
                    {
                        Thread.CurrentThread.CurrentCulture = _culture;
                        Thread.CurrentThread.CurrentUICulture = _culture;
                    }

                    // Raise the OnLocChanged event
                    DictionaryEvent.Invoke(null, new DictionaryEventArgs(DictionaryEventType.CultureChanged, value));

                    RaisePropertyChanged(nameof(Culture));
                }
            }
        }

        /// <summary>
        /// Gets or sets a flag that determines, if the CurrentThread culture should be changed along with the Culture property.
        /// </summary>
        public bool SetCurrentThreadCulture
        {
            get => _setCurrentThreadCulture;
            set
            {
                if (_setCurrentThreadCulture != value)
                {
                    _setCurrentThreadCulture = value;
                    RaisePropertyChanged(nameof(SetCurrentThreadCulture));
                }
            }
        }

        /// <summary>
        /// Gets or sets the flag indicating if the invariant culture is included in the <see cref="MergedAvailableCultures"/> list.
        /// </summary>
        public bool IncludeInvariantCulture
        {
            get => _includeInvariantCulture;
            set
            {
                if (_includeInvariantCulture != value)
                {
                    _includeInvariantCulture = value;

                    var c = CultureInfo.InvariantCulture;
                    var existing = MergedAvailableCultures.Contains(c);

                    if (_includeInvariantCulture && !existing)
                        MergedAvailableCultures.Insert(0, c);
                    else if (!_includeInvariantCulture && existing && MergedAvailableCultures.Count > 1)
                        MergedAvailableCultures.Remove(c);
                }
            }
        }

        /// <summary>
        /// Gets or sets the flag that disables the cache.
        /// </summary>
        public bool DisableCache
        {
            get => _disableCache;
            set => _disableCache = value;
        }

        /// <summary>
        /// Gets or sets the flag that controls the output of missing keys.
        /// </summary>
        public bool OutputMissingKeys
        {
            get => _outputMissingKeys;
            set => _outputMissingKeys = value;
        }

        /// <summary>
        /// The separation char for automatic key retrieval.
        /// </summary>
        public string Separation
        {
            get => _separation;
            set
            {
                _separation = value;
                DictionaryEvent.Invoke(null, new DictionaryEventArgs(DictionaryEventType.SeparationChanged, value));
            }
        }

        /// <summary>
        /// Gets or sets the default <see cref="ILocalizationProvider"/>.
        /// </summary>
        public ILocalizationProvider DefaultProvider
        {
            get => _defaultProvider;
            set
            {
                if (_defaultProvider != value)
                {
                    if (_defaultProvider != null)
                    {
                        _defaultProvider.ProviderChanged -= ProviderUpdated;
                        _defaultProvider.ValueChanged -= ValueChanged;
                        _defaultProvider.AvailableCultures.CollectionChanged -= AvailableCulturesCollectionChanged;
                    }

                    _defaultProvider = value;

                    if (_defaultProvider != null)
                    {
                        _defaultProvider.ProviderChanged += ProviderUpdated;
                        _defaultProvider.ValueChanged += ValueChanged;
                        _defaultProvider.AvailableCultures.CollectionChanged += AvailableCulturesCollectionChanged;

                        foreach (var c in _defaultProvider.AvailableCultures)
                        {
                            if (!MergedAvailableCultures.Contains(c))
                                MergedAvailableCultures.Add(c);
                        }
                    }

                    RaisePropertyChanged(nameof(DefaultProvider));
                }
            }
        }

        private ObservableCollection<CultureInfo> _mergedAvailableCultures;

        /// <summary>
        /// Gets the merged list of all available cultures.
        /// </summary>
        public ObservableCollection<CultureInfo> MergedAvailableCultures
        {
            get
            {
                if (_mergedAvailableCultures == null)
                {
                    _mergedAvailableCultures = new ObservableCollection<CultureInfo> { CultureInfo.InvariantCulture };
                    _mergedAvailableCultures.CollectionChanged += (s, e) => { Culture = Culture; };
                }

                return _mergedAvailableCultures;
            }
        }

        /// <summary>
        /// A command for culture changes.
        /// </summary>
        public ICommand SetCultureCommand { get; }

        /// <summary>
        /// Gets the specific <see cref="CultureInfo"/> of the current culture.
        /// This can be used for format manners.
        /// If the Culture is an invariant <see cref="CultureInfo"/>,
        /// SpecificCulture will also return an invariant <see cref="CultureInfo"/>.
        /// </summary>
        public CultureInfo SpecificCulture => CultureInfo.CreateSpecificCulture(Culture.ToString());

        #endregion

        #region Localization Core
        /// <summary>
        /// Get the localized object using the built-in ResxLocalizationProvider.
        /// </summary>
        /// <param name="source">The source of the dictionary.</param>
        /// <param name="dictionary">The dictionary with key/value pairs.</param>
        /// <param name="key">The key to the value.</param>
        /// <param name="culture">The culture to use.</param>
        /// <returns>The value corresponding to the source/dictionary/key path for the given culture (otherwise NULL).</returns>
        public object GetLocalizedObject(string source, string dictionary, string key, CultureInfo culture)
        {
            return GetLocalizedObject(source + ":" + dictionary + ":" + key, null, culture, DefaultProvider);
        }

        /// <summary>
        /// Get the localized object using the given target for context information.
        /// </summary>
        /// <param name="key">The key to the value.</param>
        /// <param name="target">The target <see cref="DependencyObject"/>.</param>
        /// <param name="culture">The culture to use.</param>
        /// <returns>The value corresponding to the source/dictionary/key path for the given culture (otherwise NULL).</returns>
        public object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture)
        {
            if (DefaultProvider is IInheritingLocalizationProvider)
                return GetLocalizedObject(key, target, culture, DefaultProvider);

            var provider = target?.GetValue(GetProvider);

            if (provider == null)
                provider = DefaultProvider;

            return GetLocalizedObject(key, target, culture, provider);
        }

        /// <summary>
        /// Get the localized object using the given target and provider.
        /// </summary>
        /// <param name="key">The key to the value.</param>
        /// <param name="target">The target <see cref="DependencyObject"/>.</param>
        /// <param name="culture">The culture to use.</param>
        /// <param name="provider">The provider to use.</param>
        /// <returns>The value corresponding to the source/dictionary/key path for the given culture (otherwise NULL).</returns>
        public object GetLocalizedObject(string key, DependencyObject target, CultureInfo culture, ILocalizationProvider provider)
        {
            if (provider == null)
                throw new InvalidOperationException("No provider found and no default provider given.");

            return provider.GetLocalizedObject(key, target, culture);
        }

        /// <summary>
        /// Uses the key and target to build a fully qualified resource key (Assembly, Dictionary, Key)
        /// </summary>
        /// <param name="key">Key used as a base to find the full key</param>
        /// <param name="target">Target used to help determine key information</param>
        /// <returns>Returns an object with all possible pieces of the given key (Assembly, Dictionary, Key)</returns>
        public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(string key, DependencyObject target)
        {
            if (DefaultProvider is IInheritingLocalizationProvider)
                return GetFullyQualifiedResourceKey(key, target, DefaultProvider);

            var provider = target?.GetValue(GetProvider);

            if (provider == null)
                provider = DefaultProvider;

            return GetFullyQualifiedResourceKey(key, target, provider);
        }

        /// <summary>
        /// Uses the key and target to build a fully qualified resource key (Assembly, Dictionary, Key)
        /// </summary>
        /// <param name="key">Key used as a base to find the full key</param>
        /// <param name="target">Target used to help determine key information</param>
        /// <param name="provider">Provider to use</param>
        /// <returns>Returns an object with all possible pieces of the given key (Assembly, Dictionary, Key)</returns>
        public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(string key, DependencyObject target, ILocalizationProvider provider)
        {
            if (provider == null)
                throw new InvalidOperationException("No provider found and no default provider given.");

            return provider.GetFullyQualifiedResourceKey(key, target);
        }

        /// <summary>
        /// Looks up the ResourceManagers for the searched <paramref name="resourceKey"/>
        /// in the <paramref name="resourceDictionary"/> in the <paramref name="resourceAssembly"/>
        /// with an Invariant Culture.
        /// </summary>
        /// <param name="resourceAssembly">The resource assembly</param>
        /// <param name="resourceDictionary">The dictionary to look up</param>
        /// <param name="resourceKey">The key of the searched entry</param>
        /// <returns>
        /// TRUE if the searched one is found, otherwise FALSE
        /// </returns>
        public bool ResourceKeyExists(string resourceAssembly, string resourceDictionary, string resourceKey)
        {
            return ResourceKeyExists(resourceAssembly, resourceDictionary, resourceKey, CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Looks up the ResourceManagers for the searched <paramref name="resourceKey"/>
        /// in the <paramref name="resourceDictionary"/> in the <paramref name="resourceAssembly"/>
        /// with the passed culture. If the searched one does not exists with the passed culture, is will searched
        /// until the invariant culture is used.
        /// </summary>
        /// <param name="resourceAssembly">The resource assembly</param>
        /// <param name="resourceDictionary">The dictionary to look up</param>
        /// <param name="resourceKey">The key of the searched entry</param>
        /// <param name="cultureToUse">The culture to use.</param>
        /// <returns>
        /// TRUE if the searched one is found, otherwise FALSE
        /// </returns>
        public bool ResourceKeyExists(string resourceAssembly, string resourceDictionary, string resourceKey, CultureInfo cultureToUse)
        {
            var provider = ResxLocalizationProvider.Instance;

            return ResourceKeyExists(resourceAssembly + ":" + resourceDictionary + ":" + resourceKey, cultureToUse, provider);
        }

        /// <summary>
        /// Looks up the ResourceManagers for the searched <paramref name="key"/>
        /// with the passed culture. If the searched one does not exists with the passed culture, is will searched
        /// until the invariant culture is used.
        /// </summary>
        /// <param name="key">The key of the searched entry</param>
        /// <param name="cultureToUse">The culture to use.</param>
        /// <param name="provider">The localization provider.</param>
        /// <returns>
        /// TRUE if the searched one is found, otherwise FALSE
        /// </returns>
        public bool ResourceKeyExists(string key, CultureInfo cultureToUse, ILocalizationProvider provider)
        {
            return provider.GetLocalizedObject(key, null, cultureToUse) != null;
        }
        #endregion

        #region Helper Functions
        /// <summary>
        /// Gets the status of the design mode
        /// </summary>
        /// <returns>TRUE if in design mode, else FALSE</returns>
        public bool GetIsInDesignMode()
        {
            lock (SyncRoot)
            {
                if (_isInDesignMode.HasValue)
                    return _isInDesignMode.Value;

                if (Dispatcher?.Thread == null || !Dispatcher.Thread.IsAlive)
                {
                    _isInDesignMode = false;
                    return _isInDesignMode.Value;
                }

                if (!Dispatcher.CheckAccess())
                {
                    try
                    {
                        _isInDesignMode = (bool)Dispatcher.Invoke(DispatcherPriority.Normal, TimeSpan.FromMilliseconds(100), new Func<bool>(GetIsInDesignMode));
                    }
                    catch (Exception)
                    {
                        _isInDesignMode = default(bool);
                    }

                    return _isInDesignMode.Value;
                }
                _isInDesignMode = DesignerProperties.GetIsInDesignMode(this);
                return _isInDesignMode.Value;
            }
        }
        #endregion

        #region MissingKeyEvent (standard event)
        /// <summary>
        /// An event for missing keys.
        /// </summary>
        public event EventHandler<MissingKeyEventArgs> MissingKeyEvent;

        /// <summary>
        /// Triggers a MissingKeyEvent.
        /// </summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="key">The missing key.</param>
        /// <returns>True, if a reload should be performed.</returns>
        internal MissingKeyEventArgs OnNewMissingKeyEvent(object sender, string key)
        {
            var args = new MissingKeyEventArgs(key);
            MissingKeyEvent?.Invoke(sender, args);
            return args;
        }
        #endregion

        #region DictionaryEvent (using weak references)
        internal static class DictionaryEvent
        {
            /// <summary>
            /// The list of listeners
            /// </summary>
            private static readonly ListenersList Listeners = new ListenersList();
            private static readonly object ListenersLock = new object();

            /// <summary>
            /// Fire the event.
            /// </summary>
            /// <param name="sender">The sender of the event.</param>
            /// <param name="args">The event arguments.</param>
            internal static void Invoke(DependencyObject sender, DictionaryEventArgs args)
            {
                lock (ListenersLock)
                {
                    var exceptions = new List<Exception>();
                    
                    foreach (var listener in Listeners.GetListeners())
                    {
                        try
                        {
                            listener.ResourceChanged(sender, args);
                        }
                        catch (Exception e)
                        {
                            exceptions.Add(e);
                        }
                    }

                    if (exceptions.Count > 0)
                        throw new AggregateException(exceptions);
                }
            }

            /// <summary>
            /// Adds a listener to the inner list of listeners.
            /// </summary>
            /// <param name="listener">The listener to add.</param>
            internal static void AddListener(IDictionaryEventListener listener)
            {
                if (listener == null)
                    return;
                
                lock (ListenersLock)
                {
                    Listeners.AddListener(listener);
                }
            }

            /// <summary>
            /// Removes a listener from the inner list of listeners.
            /// </summary>
            /// <param name="listener">The listener to remove.</param>
            internal static void RemoveListener(IDictionaryEventListener listener)
            {
                if (listener == null)
                    return;

                lock (ListenersLock)
                {
                    Listeners.RemoveListener(listener);
                }
            }

            /// <summary>
            /// Enumerates all listeners of type T.
            /// </summary>
            /// <typeparam name="T">The listener type.</typeparam>
            /// <returns>An enumeration of listeners.</returns>
            internal static IEnumerable<T> EnumerateListeners<T>()
            {
                lock (ListenersLock)
                {
                    foreach (var listener in Listeners.GetListeners().OfType<T>())
                    {
                        yield return listener;
                    }
                }
            }
        }
        #endregion

        #region CultureInfoDelegateCommand
        private void SetCulture(CultureInfo c)
        {
            Culture = c;
        }

        /// <summary>
        /// A class for culture commands.
        /// </summary>
        internal class CultureInfoDelegateCommand : ICommand
        {
            #region Functions for execution and evaluation
            /// <summary>
            /// Predicate that determines if an object can execute
            /// </summary>
            private readonly Predicate<CultureInfo> _canExecute;

            /// <summary>
            /// The action to execute when the command is invoked
            /// </summary>
            private readonly Action<CultureInfo> _execute;
            #endregion

            #region Constructor
            /// <summary>
            /// Initializes a new instance of the <see cref="CultureInfoDelegateCommand"/> class.
            /// Creates a new command that can always execute.
            /// </summary>
            /// <param name="execute">
            /// The execution logic.
            /// </param>
            public CultureInfoDelegateCommand(Action<CultureInfo> execute)
                : this(execute, null)
            {
            }

            /// <summary>
            /// Initializes a new instance of the <see cref="CultureInfoDelegateCommand"/> class.
            /// Creates a new command.
            /// </summary>
            /// <param name="execute">
            /// The execution logic.
            /// </param>
            /// <param name="canExecute">
            /// The execution status logic.
            /// </param>
            public CultureInfoDelegateCommand(Action<CultureInfo> execute, Predicate<CultureInfo> canExecute)
            {
                _execute = execute ?? throw new ArgumentNullException(nameof(execute));
                _canExecute = canExecute;
            }
            #endregion

            #region ICommand interface
            /// <summary>
            /// Occurs when changes occur that affect whether or not the command should execute.
            /// </summary>
            public event EventHandler CanExecuteChanged
            {
                add => CommandManager.RequerySuggested += value;
                remove => CommandManager.RequerySuggested -= value;
            }

            /// <summary>
            /// Determines whether the command can execute in its current state.
            /// </summary>
            /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
            /// <returns>true if this command can be executed; otherwise, false.</returns>
            public bool CanExecute(object parameter)
            {
                return _canExecute == null || _canExecute((CultureInfo)parameter);
            }

            /// <summary>
            /// Is called when the command is invoked.
            /// </summary>
            /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
            public void Execute(object parameter)
            {
                var c = new CultureInfo((string)parameter);
                _execute(c);
            }
            #endregion
        }
        #endregion
    }
}


================================================
FILE: src/Engine/MissingKeyEventArgs.cs
================================================
#region Copyright information
// <copyright file="MissingKeyEventArgs.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    #endregion

    /// <summary>
    /// Event arguments for a missing key event.
    /// </summary>
    public class MissingKeyEventArgs : EventArgs
    {
        /// <summary>
        /// The key that is missing or has no data.
        /// </summary>
        public string Key { get; }

        /// <summary>
        /// A flag indicating that a reload should be performed.
        /// </summary>
        public bool Reload { get; set; }

        /// <summary>
        /// A custom returnmessage for the missing key
        /// </summary>
        public string MissingKeyResult { get; set; }

        /// <summary>
        /// Creates a new instance of <see cref="MissingKeyEventArgs"/>.
        /// </summary>
        /// <param name="key">The missing key.</param>
        public MissingKeyEventArgs(string key)
        {
            Key = key;
            Reload = false;
            MissingKeyResult = null;
        }
    }
}


================================================
FILE: src/Engine/ObjectDependencyManager.cs
================================================
#region Copyright information
// <copyright file="ObjectDependencyManager.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;
    #endregion

    /// <summary>
    /// This class ensures, that a specific object lives as long a associated object is alive.
    /// </summary>
    public static class ObjectDependencyManager
    {
        /// <summary>
        /// This member holds the list of all <see cref="WeakReference"/>s and their appropriate objects.
        /// </summary>
        private static readonly Dictionary<object, List<WeakReference>> InternalList;

        /// <summary>
        /// Initializes static members of the <see cref="ObjectDependencyManager"/> class.
        /// Static Constructor. Creates a new instance of
        /// Dictionary(object, <see cref="WeakReference"/>) and set it to the <see cref="InternalList"/>.
        /// </summary>
        static ObjectDependencyManager()
        {
            InternalList = new Dictionary<object, List<WeakReference>>();
        }

        /// <summary>
        /// This method adds a new object dependency
        /// </summary>
        /// <param name="weakRefDp">The <see cref="WeakReference"/>, which ensures the live cycle of <paramref name="objToHold"/></param>
        /// <param name="objToHold">The object, which should stay alive as long <paramref name="weakRefDp"/> is alive</param>
        /// <returns>
        /// true, if the binding was successfully, otherwise false
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        /// The <paramref name="objToHold"/> cannot be null
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="objToHold"/> cannot be type of <see cref="WeakReference"/>
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// The <see cref="WeakReference"/>.Target cannot be the same as <paramref name="objToHold"/>
        /// </exception>
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static bool AddObjectDependency(WeakReference weakRefDp, object objToHold)
        {
            // run the clean up to ensure that only objects are watched they are realy still alive
            CleanUp();

            // if the objToHold is null, we cannot handle this afterwards.
            if (objToHold == null)
            {
                throw new ArgumentNullException(nameof(objToHold), "The objToHold cannot be null");
            }

            // if the objToHold is a weakreference, we cannot handle this type afterwards.
            if (objToHold.GetType() == typeof(WeakReference))
            {
                throw new ArgumentException("objToHold cannot be type of WeakReference", nameof(objToHold));
            }

            // if the target of the weakreference is the objToHold, this would be a cycling play.
            if (weakRefDp.Target == objToHold)
            {
                throw new InvalidOperationException("The WeakReference.Target cannot be the same as objToHold");
            }

            // holds the status of registration of the object dependency
            var itemRegistered = false;

            // check if the objToHold is contained in the internalList.
            if (!InternalList.ContainsKey(objToHold))
            {
                // add the objToHold to the internal list.
                List<WeakReference> lst = new List<WeakReference> { weakRefDp };

                InternalList.Add(objToHold, lst);

                itemRegistered = true;
            }
            else
            {
                // otherweise, check if the weakRefDp exists and add it if necessary
                List<WeakReference> lst = InternalList[objToHold];
                if (!lst.Contains(weakRefDp))
                {
                    lst.Add(weakRefDp);

                    itemRegistered = true;
                }
            }

            // return the status of the registration
            return itemRegistered;
        }

        /// <summary>
        /// This method cleans up all independent (!<see cref="WeakReference"/>.IsAlive) objects.
        /// </summary>
        public static void CleanUp()
        {
            // call the overloaded method
            CleanUp(null);
        }

        /// <summary>
        /// This method cleans up all independent (!<see cref="WeakReference"/>.IsAlive) objects or a single object.
        /// </summary>
        /// <param name="objToRemove">
        /// If defined, the associated object dependency will be removed instead of a full CleanUp
        /// </param>
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void CleanUp(object objToRemove)
        {
            // if a particular object is passed, remove it.
            if (objToRemove != null)
            {
                // if the key wasnt found, throw an exception.
                if (!InternalList.Remove(objToRemove))
                {
                    throw new Exception("Key was not found!");
                }

                // stop here
                return;
            }

            // perform an full clean up

            // this list will hold all keys they has to be removed
            List<object> keysToRemove = new List<object>();

            // step through all object dependenies
            foreach (KeyValuePair<object, List<WeakReference>> kvp in InternalList)
            {
                // step recursive through all weak references
                for (int i = kvp.Value.Count - 1; i >= 0; i--)
                {
                    // if this weak reference is no more alive, remove it
                    var targetReference = kvp.Value[i].Target;
                    if (targetReference == null)
                    {
                        kvp.Value.RemoveAt(i);
                    }
                }

                // if the list of weak references is empty, temove the whole entry
                if (kvp.Value.Count == 0)
                {
                    keysToRemove.Add(kvp.Key);
                }
            }

            // step recursive through all keys that have to be remove
            for (int i = keysToRemove.Count - 1; i >= 0; i--)
            {
                // remove the key from the internalList
                InternalList.Remove(keysToRemove[i]);
            }

            // clear up the keysToRemove
            keysToRemove.Clear();
        }
    }
}

================================================
FILE: src/Engine/ParentNotifiers.cs
================================================
#region Copyright information
// <copyright file="ParentChangedNotifierHelper.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <summary>
    /// A memory safe dictionary storage for <see cref="ParentChangedNotifier"/> instances.
    /// </summary>
    public class ParentNotifiers
    {
        readonly Dictionary<WeakReference<DependencyObject>, ParentChangedNotifier> _inner =
            new Dictionary<WeakReference<DependencyObject>, ParentChangedNotifier>();

        /// <summary>
        /// Check, if it contains the key.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>True, if the key exists.</returns>
        public bool ContainsKey(DependencyObject target)
        {
            return _inner.Keys.Any(x => x.TryGetTarget(out var item) && ReferenceEquals(item, target));
        }

        /// <summary>
        /// Removes the entry.
        /// </summary>
        /// <param name="target">The target object.</param>
        public void Remove(DependencyObject target)
        {
            if (_inner.Count == 0)
                return;

            var deadItems = new List<KeyValuePair<WeakReference<DependencyObject>, ParentChangedNotifier>>();

            foreach (var item in _inner)
            {
                // If we can't get target (== target is dead) or this is the item which we have to remove - add it to the collection for removing.
                if (!item.Key.TryGetTarget(out var itemTarget) || ReferenceEquals(itemTarget, target))
                {
                    deadItems.Add(item);
                }
            }

            foreach (var deadItem in deadItems)
            {
                deadItem.Value?.Dispose();
                _inner.Remove(deadItem.Key);
            }
        }

        /// <summary>
        /// Adds the key-value-pair.
        /// </summary>
        /// <param name="target">The target key object.</param>
        /// <param name="parentChangedNotifier">The notifier.</param>
        public void Add(DependencyObject target, ParentChangedNotifier parentChangedNotifier)
        {
            _inner.Add(new WeakReference<DependencyObject>(target), parentChangedNotifier);
        }
    }
}

================================================
FILE: src/Engine/SafeTargetInfo.cs
================================================
#region Copyright information
// <copyright file="SafeTargetInfo.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Engine
{
    #region Usings
    using System;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <summary>
    /// An extension to the <see cref="T:XAMLMarkupExtensions.Base.TargetInfo" /> class with WeakReference instead of direct object linking.
    /// </summary>
    public class SafeTargetInfo : TargetInfo
    {
        /// <summary>
        /// Gets the target object reference.
        /// </summary>
        public WeakReference TargetObjectReference { get; }

        /// <summary>
        /// Creates a new TargetInfo instance.
        /// </summary>
        /// <param name="targetObject">The target object.</param>
        /// <param name="targetProperty">The target property.</param>
        /// <param name="targetPropertyType">The target property type.</param>
        /// <param name="targetPropertyIndex">The target property index.</param>
        public SafeTargetInfo(object targetObject, object targetProperty, Type targetPropertyType, int targetPropertyIndex)
            : base(null, targetProperty, targetPropertyType, targetPropertyIndex)
        {
            TargetObjectReference = new WeakReference(targetObject);
        }

        /// <summary>
        /// Creates a new <see cref="SafeTargetInfo"/> based on a <see cref="XAMLMarkupExtensions.Base.TargetInfo"/> template.
        /// </summary>
        /// <param name="targetInfo">The target information.</param>
        /// <returns>A new instance with safe references.</returns>
        public static SafeTargetInfo FromTargetInfo(TargetInfo targetInfo)
        {
            return new SafeTargetInfo(targetInfo.TargetObject, targetInfo.TargetProperty, targetInfo.TargetPropertyType, targetInfo.TargetPropertyIndex);
        }
    }
}


================================================
FILE: src/Engine/WeakReference.cs
================================================
#region Copyright information
// <copyright file="ParentChangedNotifierHelper.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
#endregion

#if NET35 || NET40
namespace WPFLocalizeExtension.Engine
{
#region Usings
    using System;
    using System.Runtime.Serialization;
#endregion

    /// <summary>
    /// This class implements an wrapper for .NET35, because this is starting from NET45 of <see cref="WeakReference"/>.
    /// </summary>
    /// <typeparam name="T">The reference type.</typeparam>
    public class WeakReference<T> : WeakReference
    {
        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="target">The target.</param>
		public WeakReference(T target) : base(target)
        {
        }

        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="trackResurrection">The track resurrection flag.</param>
        public WeakReference(T target, bool trackResurrection)
            : base(target, trackResurrection)
        {
        }

        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="info">The serialization info.</param>
        /// <param name="context">The streaming context.</param>
        protected WeakReference(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        /// <summary>
        /// Tries to retrieve the target object that is referenced by the current WeakReference&lt;T&gt; object.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns>true if the target was retrieved; otherwise, false.</returns>
        public bool TryGetTarget(out T target)
        {
            var baseTarget = base.Target;
            if (baseTarget != null)
            {
                target = (T)baseTarget;
                return true;
            }
            target = default;
            return false;
        }

        // / <summary>
        // / Gets or sets the target.
        // / </summary>
        //public new T Target
        //{
        //    get
        //    {
        //        var baseTarget = base.Target;
        //        if (IsAlive && baseTarget != null)
        //        {
        //            return (T)base.Target;
        //        }
        //        return default(T);
        //    }
        //    set { base.Target = value; }
        //}
    }
}
#endif


================================================
FILE: src/Extensions/BLoc.cs
================================================
#region Copyright information
// <copyright file="BLoc.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Extensions
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    using WPFLocalizeExtension.Engine;
    #endregion

    /// <summary>
    /// A localization extension based on <see cref="Binding"/>.
    /// </summary>
    public class BLoc : Binding, INotifyPropertyChanged, IDictionaryEventListener, IDisposable
    {
        #region PropertyChanged Logic
        /// <summary>
        /// Informiert über sich ändernde Eigenschaften.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notify that a property has changed
        /// </summary>
        /// <param name="property">
        /// The property that changed
        /// </param>
        internal void RaisePropertyChanged(string property)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
        }
        #endregion

        #region Variables & Properties
        private static readonly object ResourceBufferLock = new object();
        private static Dictionary<string, object> _resourceBuffer = new Dictionary<string, object>();

        private object _value;
        /// <summary>
        /// The value, the internal binding is pointing at.
        /// </summary>
        public object Value
        {
            get => _value;
            set
            {
                if (_value != value)
                {
                    _value = value;
                    RaisePropertyChanged(nameof(Value));
                }
            }
        }

        private string _key;
        /// <summary>
        /// Gets or sets the Key to a .resx object
        /// </summary>
        public string Key
        {
            get => _key;
            set
            {
                if (_key != value)
                {
                    _key = value;
                    UpdateNewValue();
                    RaisePropertyChanged(nameof(Key));
                }
            }
        }

        /// <summary>
        /// Gets or sets the culture to force a fixed localized object
        /// </summary>
        public string ForceCulture { get; set; }
        #endregion

        #region Resource buffer handling.
        /// <summary>
        /// Clears the common resource buffer.
        /// </summary>
        public static void ClearResourceBuffer()
        {
            lock (ResourceBufferLock)
            {
                _resourceBuffer?.Clear();
                _resourceBuffer = null;
            }
        }

        /// <summary>
        /// Adds an item to the resource buffer (threadsafe).
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="item">The item.</param>
        internal static void SafeAddItemToResourceBuffer(string key, object item)
        {
            lock (ResourceBufferLock)
            {
                if (!LocalizeDictionary.Instance.DisableCache && !_resourceBuffer.ContainsKey(key))
                    _resourceBuffer.Add(key, item);
            }
        }

        /// <summary>
        /// Removes an item from the resource buffer (threadsafe).
        /// </summary>
        /// <param name="key">The key.</param>
        internal static void SafeRemoveItemFromResourceBuffer(string key)
        {
            lock (ResourceBufferLock)
            {
                if (_resourceBuffer.ContainsKey(key))
                    _resourceBuffer.Remove(key);
            }
        }
        #endregion

        #region Block some Binding Parameters
        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new PropertyPath Path
        {
            get { return null; }
            set
            {
                throw new Exception(nameof(Path) + " not allowed for BLoc");
            }
        }

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new object Source
        {
            get => null;
            set => throw new Exception(nameof(Source) + " not allowed for BLoc");
        }

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new RelativeSource RelativeSource
        {
            get => null;
            set => throw new Exception(nameof(RelativeSource) + " not allowed for BLoc");
        }

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new string ElementName
        {
            get => null;
            set => throw new Exception(nameof(ElementName) + " not allowed for BLoc");
        }

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new BindingMode Mode
        {
            get => BindingMode.Default;
            set => throw new Exception(nameof(Mode) + " not allowed for BLoc");
        }

        /// <inheritdoc/>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new string XPath
        {
            get => null;
            set => throw new Exception(nameof(XPath) + " not allowed for BLoc");
        }
        #endregion

        #region Constructors & Dispose
        /// <summary>
        /// Initializes a new instance of the <see cref="BLoc"/> class.
        /// </summary>
        public BLoc()
        {
            LocalizeDictionary.DictionaryEvent.AddListener(this);
            base.Path = new PropertyPath("Value");
            base.Source = this;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BLoc"/> class.
        /// </summary>
        /// <param name="key">The resource identifier.</param>
        public BLoc(string key)
            : this()
        {
            Key = key;
        }

        /// <summary>
        /// Removes the listener from the dictionary.
        /// </summary>
        public void Dispose()
        {
            LocalizeDictionary.DictionaryEvent.RemoveListener(this);
        }

        /// <summary>
        /// The finalizer.
        /// </summary>
        ~BLoc()
        {
            Dispose();
        }
        #endregion

        #region Forced culture handling
        /// <summary>
        /// If Culture property defines a valid <see cref="CultureInfo"/>, a <see cref="CultureInfo"/> instance will get
        /// created and returned, otherwise <see cref="LocalizeDictionary"/>.Culture will get returned.
        /// </summary>
        /// <returns>The <see cref="CultureInfo"/></returns>
        /// <exception cref="System.ArgumentException">
        /// thrown if the parameter Culture don't defines a valid <see cref="CultureInfo"/>
        /// </exception>
        protected CultureInfo GetForcedCultureOrDefault()
        {
            // define a culture info
            CultureInfo cultureInfo;

            // check if the forced culture is not null or empty
            if (!string.IsNullOrEmpty(ForceCulture))
            {
                // try to create a valid cultureinfo, if defined
                try
                {
                    // try to create a specific culture from the forced one
                    // cultureInfo = CultureInfo.CreateSpecificCulture(this.ForceCulture);
                    cultureInfo = new CultureInfo(ForceCulture);
                }
                catch (ArgumentException ex)
                {
                    // on error, check if designmode is on
                    if (LocalizeDictionary.Instance.GetIsInDesignMode())
                    {
                        // cultureInfo will be set to the current specific culture
                        cultureInfo = LocalizeDictionary.Instance.SpecificCulture;
                    }
                    else
                    {
                        // tell the customer, that the forced culture cannot be converted propperly
                        throw new ArgumentException("Cannot create a CultureInfo with '" + ForceCulture + "'", ex);
                    }
                }
            }
            else
            {
                // take the current specific culture
                cultureInfo = LocalizeDictionary.Instance.SpecificCulture;
            }

            // return the evaluated culture info
            return cultureInfo;
        }
        #endregion

        /// <summary>
        /// This method is called when the resource somehow changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event arguments.</param>
        public void ResourceChanged(DependencyObject sender, DictionaryEventArgs e)
        {
            UpdateNewValue();
        }

        private void UpdateNewValue()
        {
            Value = FormatOutput();
        }

        #region Future TargetMarkupExtension implementation
        /// <summary>
        /// This function returns the properly prepared output of the markup extension.
        /// </summary>
        public object FormatOutput()
        {
            object result = null;

            // Try to get the localized input from the resource.
            string resourceKey = LocalizeDictionary.Instance.GetFullyQualifiedResourceKey(Key, null);

            var ci = GetForcedCultureOrDefault();

            var key = ci.Name + ":";

            // Check, if the key is already in our resource buffer.
            lock (ResourceBufferLock)
            {
                if (_resourceBuffer.ContainsKey(key + resourceKey))
                    result = _resourceBuffer[key + resourceKey];
            }

            if (result == null)
            {
                result = LocalizeDictionary.Instance.GetLocalizedObject(resourceKey, null, ci);

                if (result == null)
                {
                    var missingKeyEventResult = LocalizeDictionary.Instance.OnNewMissingKeyEvent(this, resourceKey);

                    if (missingKeyEventResult.Reload)
                        UpdateNewValue();

                    if (LocalizeDictionary.Instance.OutputMissingKeys
                        && !string.IsNullOrEmpty(_key))
                    {
                        if (missingKeyEventResult.MissingKeyResult != null)
                            result = missingKeyEventResult.MissingKeyResult;
                        else
                            result = "Key: " + _key;
                    }
                }
                else
                {
                    key += resourceKey;
                    SafeAddItemToResourceBuffer(key, result);
                }
            }

            return result;
        }
        #endregion
    }
}


================================================
FILE: src/Extensions/FELoc.cs
================================================
#region Copyright information
// <copyright file="FELoc.cs">
//     Licensed under Microsoft Public License (Ms-PL)
//     https://github.com/XAMLMarkupExtensions/WPFLocalizationExtension/blob/master/LICENSE
// </copyright>
// <author>Bernhard Millauer</author>
// <author>Uwe Mayer</author>
#endregion

namespace WPFLocalizeExtension.Extensions
{
    #region Usings
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Markup.Primitives;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using WPFLocalizeExtension.Engine;
    using WPFLocalizeExtension.TypeConverters;
    using XAMLMarkupExtensions.Base;
    #endregion

    /// <summary>
    /// A localization utility based on <see cref="FrameworkElement"/>.
    /// </summary>
    public class FELoc : FrameworkElement, IDictionaryEventListener, INotifyPropertyChanged, IDisposable
    {
        #region PropertyChanged Logic
        /// <summary>
        /// Informiert über sich ändernde Eigenschaften.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notify that a property has changed
        /// </summary>
        /// <param name="property">
        /// The property that changed
        /// </param>
        internal void RaisePropertyChanged(string property)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
        }
        #endregion

        #region Private variables
        private static readonly object ResourceBufferLock = new object();
        private static Dictionary<string, object> _resourceBuffer = new Dictionary<string, object>();

        private ParentChangedNotifier _parentChangedNotifier;
        private TargetInfo _targetInfo;
        #endregion

        #region Resource buffer handling.
        /// <summary>
        /// Clears the common resource buffer.
        /// </summary>
        public static void ClearResourceBuffer()
        {
            lock (ResourceBufferLock)
            {
                _resourceBuffer?.Clear();
                _resourceBuffer = null;
            }
        }

        /// <summary>
        /// Adds an item to the resource buffer (threadsafe).
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="item">The item.</param>
        internal static void SafeAddItemToResourceBuffer(string key, object item)
        {
            lock (ResourceBufferLock)
            {
                if (!LocalizeDictionary.Instance.DisableCache && !_resourceBuffer.ContainsKey(key))
                    _resourceBuffer.Add(key, item);
            }
        }

        /// <summary>
        /// Removes an item from the resource buffer (threadsafe).
        /// </summary>
        /// <param name="key">The key.</param>
        internal static void SafeRemoveItemFromResourceBuffer(string key)
        {
            lock (ResourceBufferLock)
            {
                if (_resourceBuffer.ContainsKey(key))
           
Download .txt
gitextract_vs211frg/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   ├── dependabot.yml
│   ├── release-drafter.yml
│   └── workflows/
│       ├── compile.yml
│       ├── publish.yml
│       └── release-drafter.yaml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs/
│   ├── BLoc-and-FELoc.md
│   ├── FAQ.md
│   ├── Features.md
│   ├── GapText.md
│   ├── Installation-and-dependencies.md
│   ├── Keys.md
│   ├── LocProxy-&-EnumComboBox.md
│   ├── Localization-providers.md
│   ├── Localization.md
│   ├── Localize.md
│   ├── MarkupExtension-basics.md
│   ├── Multiple-assemblies-and-dictionaries.md
│   ├── Our-first-localized-text.md
│   ├── Preparing-the-XAML-code.md
│   ├── README.md
│   ├── Resource-files.md
│   ├── Supported-platforms.md
│   └── ValueConverters.md
├── src/
│   ├── Deprecated/
│   │   ├── Engine/
│   │   │   ├── GapTextControl.cs
│   │   │   ├── LocBinding.cs
│   │   │   └── LocProxy.cs
│   │   ├── Extensions/
│   │   │   └── Compatibility.cs
│   │   └── Providers/
│   │       ├── CSVEmbeddedLocalizationProvider.cs
│   │       ├── CSVLocalizationProvider.cs
│   │       └── CSVLocalizationProviderBase.cs
│   ├── Engine/
│   │   ├── EnumComboBox.cs
│   │   ├── EnumRun.cs
│   │   ├── FallbackBehavior.cs
│   │   ├── IDictionaryEventListener.cs
│   │   ├── ListenerList.cs
│   │   ├── LocalizeDictionary.cs
│   │   ├── MissingKeyEventArgs.cs
│   │   ├── ObjectDependencyManager.cs
│   │   ├── ParentNotifiers.cs
│   │   ├── SafeTargetInfo.cs
│   │   └── WeakReference.cs
│   ├── Extensions/
│   │   ├── BLoc.cs
│   │   ├── FELoc.cs
│   │   └── LocExtension.cs
│   ├── Providers/
│   │   ├── FQAssemblyDictionaryKey.cs
│   │   ├── FullyQualifiedResourceKeyBase.cs
│   │   ├── IInheritingLocalizationProvider.cs
│   │   ├── ILocalizationProvider.cs
│   │   ├── InheritingResxLocalizationProvider.cs
│   │   ├── ParentChangedNotifierHelper.cs
│   │   ├── ProviderEventArgs.cs
│   │   ├── ResxLocalizationProvider.cs
│   │   └── ResxLocalizationProviderBase.cs
│   ├── Themes/
│   │   └── Generic.xaml
│   ├── TypeConverters/
│   │   ├── BitmapSourceTypeConverter.cs
│   │   ├── DefaultConverter.cs
│   │   ├── RegisterMissingTypeConverters.cs
│   │   └── ThicknessConverter.cs
│   ├── ValueConverters/
│   │   ├── PrependTypeConverter.cs
│   │   ├── StringFormatConverter.cs
│   │   ├── ToLowerConverter.cs
│   │   ├── ToUpperConverter.cs
│   │   ├── TranslateConverter.cs
│   │   └── TypeValueConverterBase.cs
│   ├── WPFLocalizeExtension.csproj
│   ├── WPFLocalizeExtension.sln
│   ├── XmlnsPrefix.cs
│   ├── packages.lock.json
│   └── public.snk
└── tests/
    ├── AssemblyTest/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── AssemblyTest.csproj
    │   ├── CaseConverter.cs
    │   ├── CountryRes.Designer.cs
    │   ├── CountryRes.de.resx
    │   ├── CountryRes.resx
    │   ├── Example.csv
    │   ├── Example.de.csv
    │   ├── Item.cs
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── MyViewModel.cs
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── Resource.With.Dot.Designer.cs
    │   ├── Resource.With.Dot.de.resx
    │   ├── Resource.With.Dot.en.resx
    │   ├── Resource.With.Dot.resx
    │   ├── StringFormatProxy.cs
    │   ├── Strings.Designer.cs
    │   ├── Strings.de.resx
    │   ├── Strings.resx
    │   ├── Strings2.Designer.cs
    │   ├── Strings2.de.resx
    │   ├── Strings2.resx
    │   ├── TestDataClass.cs
    │   ├── TestEnum.cs
    │   └── ViewModelBase.cs
    ├── AssemblyTestResourceLib/
    │   ├── AssemblyTest.csproj
    │   ├── AssemblyTestResourceLib.csproj
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── Strings.Designer.cs
    │   ├── Strings.de.resx
    │   ├── Strings.resx
    │   ├── Strings2.Designer.cs
    │   ├── Strings2.de.resx
    │   └── Strings2.resx
    ├── FluentLexTest/
    │   ├── Application.xaml
    │   ├── Application.xaml.cs
    │   ├── Fluent.Sample.Foundation.csproj
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.de.resx
    │   │   └── Resources.resx
    │   ├── Window.xaml
    │   ├── Window.xaml.cs
    │   └── app.config
    ├── GapTextWpfTest/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── Converters/
    │   │   └── ObjectTypeEqualsConverter.cs
    │   ├── GapTextWpfTest.csproj
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   └── Resources.resx
    │   └── packages.config
    ├── HelloWorldWPF/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── HelloWorldWPF.csproj
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── Ressourcen.Designer.cs
    │   ├── Ressourcen.ar.resx
    │   ├── Ressourcen.de.resx
    │   ├── Ressourcen.en.resx
    │   ├── Ressourcen.he.resx
    │   ├── Ressourcen.resx
    │   └── TestVM.cs
    ├── HelloWorldWPF.sln
    ├── LeakSample/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── LeakSample.csproj
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── MainWindowViewModel.cs
    │   ├── Properties/
    │   │   ├── Annotations.cs
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   └── Resources/
    │       ├── Localization.Designer.cs
    │       └── Localization.resx
    ├── LeakSample.sln
    ├── LocalizationTest/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── Loader.xaml
    │   ├── Loader.xaml.cs
    │   ├── LocalizationTest.csproj
    │   ├── Popup.xaml
    │   ├── Popup.xaml.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   ├── TestResource.Designer.cs
    │   ├── TestResource.en-GB.resx
    │   ├── TestResource.pl-PL.resx
    │   └── TestResource.resx
    ├── LocalizationTest.sln
    ├── MemoryTest/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── MemoryTest.csproj
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.de.resx
    │   │   ├── Resources.en.resx
    │   │   └── Resources.resx
    │   ├── TestWindow.xaml
    │   ├── TestWindow.xaml.cs
    │   ├── TestWindowUnlocalized.xaml
    │   └── TestWindowUnlocalized.xaml.cs
    ├── MemoryTest.sln
    ├── ProviderExample/
    │   ├── CSVLocalizationProvider.cs
    │   ├── ProviderExample.csproj
    │   └── TestProvider.cs
    ├── ResourceAssembly/
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── ResTexts.Designer.cs
    │   ├── ResTexts.resx
    │   └── ResourceAssembly.csproj
    ├── SatelliteAssemblyTest/
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.cs
    │   ├── Properties/
    │   │   └── AssemblyInfo.cs
    │   ├── SatelliteAssemblyTest.csproj
    │   ├── TestRes.Designer.cs
    │   ├── TestRes.de.resx
    │   ├── TestRes.es.resx
    │   ├── TestRes.fr.resx
    │   ├── TestRes.resx
    │   └── packages.config
    ├── SatelliteAssemblyTest.sln
    ├── Tests.sln
    ├── ThreadPerformance/
    │   ├── App.config
    │   ├── App.xaml
    │   ├── App.xaml.cs
    │   ├── MainView.xaml
    │   ├── MainView.xaml.cs
    │   ├── Properties/
    │   │   ├── AssemblyInfo.cs
    │   │   ├── Resources.Designer.cs
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.cs
    │   │   └── Settings.settings
    │   ├── Resources/
    │   │   ├── MainView.Designer.cs
    │   │   ├── MainView.de.resx
    │   │   └── MainView.resx
    │   ├── ThreadPerformance.csproj
    │   └── packages.config
    ├── ThreadPerformance.sln
    ├── VbWpfApplication/
    │   ├── Application.xaml
    │   ├── Application.xaml.vb
    │   ├── MainWindow.xaml
    │   ├── MainWindow.xaml.vb
    │   ├── My Project/
    │   │   ├── AssemblyInfo.vb
    │   │   ├── MyExtensions/
    │   │   │   └── MyWpfExtension.vb
    │   │   ├── Resources.Designer.vb
    │   │   ├── Resources.resx
    │   │   ├── Settings.Designer.vb
    │   │   └── Settings.settings
    │   ├── Strings.Designer.vb
    │   ├── Strings.en-GB.Designer.vb
    │   ├── Strings.en-GB.resx
    │   ├── Strings.resx
    │   ├── Strings.sv-SE.Designer.vb
    │   ├── Strings.sv-SE.resx
    │   ├── VbWpfApplication.vbproj
    │   └── packages.config
    ├── VbWpfApplication.sln
    ├── WPFLocalizeExtension.UnitTests/
    │   ├── ValueConvertersTests/
    │   │   ├── LocExtensionTests.cs
    │   │   └── StringFormatConverterTests.cs
    │   └── WPFLocalizeExtension.UnitTests.csproj
    └── XamlLocalizationTest.sln
Download .txt
SYMBOL INDEX (598 symbols across 96 files)

FILE: src/Deprecated/Engine/GapTextControl.cs
  class GapTextControl (line 28) | [Obsolete("GapTextControl is deprecated and will be removed in version 4...
    method OnGapsChanged (line 86) | private static void OnGapsChanged(DependencyObject dependencyObject, D...
    method GapTextControl (line 100) | static GapTextControl()
    method GapTextControl (line 108) | public GapTextControl()
    method OnFormatStringChanged (line 179) | private static void OnFormatStringChanged(DependencyObject d, Dependen...
    method DeepCopy (line 188) | private static T DeepCopy<T>(T obj)
    method OnContentChanged (line 208) | private void OnContentChanged()
    method OnApplyTemplate (line 286) | public override void OnApplyTemplate()
    method AttachToVisualTree (line 292) | private void AttachToVisualTree()

FILE: src/Deprecated/Engine/LocBinding.cs
  class LocBinding (line 22) | [Obsolete("LocBinding is deprecated and will be removed in version 4.0, ...
    method OnPropertyChanged (line 65) | private static void OnPropertyChanged(DependencyObject obj, Dependency...

FILE: src/Deprecated/Engine/LocProxy.cs
  class LocProxy (line 21) | [Obsolete("LocProxy is deprecated and will be removed in version 4.0, be...
    method PropertiesChanged (line 119) | private static void PropertiesChanged(DependencyObject d, DependencyPr...

FILE: src/Deprecated/Extensions/Compatibility.cs
  class LocBrushExtension (line 21) | [Obsolete("LocBrushExtension is deprecated and will be removed in versio...
    method LocBrushExtension (line 26) | public LocBrushExtension()
    method LocBrushExtension (line 30) | public LocBrushExtension(string key) : base(key) { }
  class LocDoubleExtension (line 34) | [Obsolete("LocDoubleExtension is deprecated and will be removed in versi...
    method LocDoubleExtension (line 39) | public LocDoubleExtension()
    method LocDoubleExtension (line 43) | public LocDoubleExtension(string key) : base(key) { }
  class LocFlowDirectionExtension (line 47) | [MarkupExtensionReturnType(typeof(System.Windows.FlowDirection))]
    method LocFlowDirectionExtension (line 52) | public LocFlowDirectionExtension()
    method LocFlowDirectionExtension (line 56) | public LocFlowDirectionExtension(string key) : base(key) { }
  class LocImageExtension (line 60) | [MarkupExtensionReturnType(typeof(System.Windows.Media.Imaging.BitmapSou...
    method LocImageExtension (line 65) | public LocImageExtension()
    method LocImageExtension (line 69) | public LocImageExtension(string key) : base(key) { }
  class LocTextExtension (line 73) | [MarkupExtensionReturnType(typeof(string))]
    method LocTextExtension (line 79) | public LocTextExtension()
    method LocTextExtension (line 83) | public LocTextExtension(string key) : base(key) { }
    type TextAppendType (line 91) | protected enum TextAppendType
    method GetAppendText (line 209) | private string GetAppendText(TextAppendType at)
    method FormatText (line 235) | protected virtual string FormatText(string target)
    method FormatOutput (line 241) | public override object FormatOutput(TargetInfo endPoint, TargetInfo info)
  class LocTextLowerExtension (line 278) | [MarkupExtensionReturnType(typeof(string))]
    method LocTextLowerExtension (line 284) | public LocTextLowerExtension()
    method LocTextLowerExtension (line 288) | public LocTextLowerExtension(string key) : base(key) { }
    method FormatText (line 293) | protected override string FormatText(string target)
  class LocTextUpperExtension (line 301) | [MarkupExtensionReturnType(typeof(string))]
    method LocTextUpperExtension (line 307) | public LocTextUpperExtension()
    method LocTextUpperExtension (line 311) | public LocTextUpperExtension(string key) : base(key) { }
    method FormatText (line 316) | protected override string FormatText(string target)
  class LocThicknessExtension (line 324) | [MarkupExtensionReturnType(typeof(System.Windows.Thickness))]
    method LocThicknessExtension (line 329) | public LocThicknessExtension()
    method LocThicknessExtension (line 333) | public LocThicknessExtension(string key) : base(key) { }

FILE: src/Deprecated/Providers/CSVEmbeddedLocalizationProvider.cs
  class CSVEmbeddedLocalizationProvider (line 30) | [Obsolete("CSVEmbeddedLocalizationProvider is deprecated and will be rem...
    method AttachedPropertyChanged (line 61) | private static void AttachedPropertyChanged(DependencyObject obj, Depe...
    method GetDefaultDictionary (line 74) | public static string GetDefaultDictionary(DependencyObject obj)
    method GetDefaultAssembly (line 84) | public static string GetDefaultAssembly(DependencyObject obj)
    method SetDefaultDictionary (line 96) | public static void SetDefaultDictionary(DependencyObject obj, string v...
    method SetDefaultAssembly (line 106) | public static void SetDefaultAssembly(DependencyObject obj, string value)
    method CSVEmbeddedLocalizationProvider (line 155) | private CSVEmbeddedLocalizationProvider()
    method ParentChangedAction (line 177) | private void ParentChangedAction(DependencyObject obj)
    method GetAssembly (line 187) | protected override string GetAssembly(DependencyObject target)
    method GetDictionary (line 197) | protected override string GetDictionary(DependencyObject target)
    method GetLocalizedObject (line 209) | public override object GetLocalizedObject(string key, DependencyObject...

FILE: src/Deprecated/Providers/CSVLocalizationProvider.cs
  class CSVLocalizationProvider (line 26) | [Obsolete("CSVLocalizationProvider is deprecated and will be removed in ...
    method AttachedPropertyChanged (line 47) | private static void AttachedPropertyChanged(DependencyObject obj, Depe...
    method GetDefaultDictionary (line 60) | public static string GetDefaultDictionary(DependencyObject obj)
    method SetDefaultDictionary (line 72) | public static void SetDefaultDictionary(DependencyObject obj, string v...
    method CSVLocalizationProvider (line 121) | private CSVLocalizationProvider()
    method ParentChangedAction (line 142) | private void ParentChangedAction(DependencyObject obj)
    method GetDictionary (line 152) | protected override string GetDictionary(DependencyObject target)
    method GetAssembly (line 162) | protected override string GetAssembly(DependencyObject target)
    method GetLocalizedObject (line 174) | public override object GetLocalizedObject(string key, DependencyObject...

FILE: src/Deprecated/Providers/CSVLocalizationProviderBase.cs
  class CSVLocalizationProviderBase (line 25) | [Obsolete("CSVLocalizationProviderBase is deprecated and will be removed...
    method GetAssemblyName (line 51) | protected string GetAssemblyName(Assembly assembly)
    method ParseKey (line 69) | public static void ParseKey(string inKey, out string outAssembly, out ...
    method GetAssembly (line 108) | protected abstract string GetAssembly(DependencyObject target);
    method GetDictionary (line 115) | protected abstract string GetDictionary(DependencyObject target);
    method AddCulture (line 123) | protected void AddCulture(CultureInfo c)
    method GetFullyQualifiedResourceKey (line 140) | public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(stri...
    method OnProviderChanged (line 178) | protected virtual void OnProviderChanged(DependencyObject target)
    method OnProviderError (line 202) | protected virtual void OnProviderError(DependencyObject target, string...
    method OnValueChanged (line 213) | protected virtual void OnValueChanged(string key, object value, object...
    method GetLocalizedObject (line 225) | public virtual object GetLocalizedObject(string key, DependencyObject ...

FILE: src/Engine/EnumComboBox.cs
  class EnumComboBox (line 25) | public class EnumComboBox : ComboBox
    method TypeChanged (line 43) | private static void TypeChanged(DependencyObject d, DependencyProperty...
    method OnItemTemplateChanged (line 113) | protected override void OnItemTemplateChanged(DataTemplate oldItemTemp...
    method ShouldSerializeProperty (line 122) | protected override bool ShouldSerializeProperty(DependencyProperty dp)
    method SetType (line 131) | private void SetType(Type type)
    method EnumComboBox (line 164) | public EnumComboBox()

FILE: src/Engine/EnumRun.cs
  class EnumRun (line 22) | public class EnumRun : Run
    method PropertiesChanged (line 103) | private static void PropertiesChanged(DependencyObject d, DependencyPr...

FILE: src/Engine/FallbackBehavior.cs
  type FallbackBehavior (line 6) | public enum FallbackBehavior

FILE: src/Engine/IDictionaryEventListener.cs
  type IDictionaryEventListener (line 19) | public interface IDictionaryEventListener
    method ResourceChanged (line 26) | void ResourceChanged(DependencyObject sender, DictionaryEventArgs e);
  type DictionaryEventType (line 32) | public enum DictionaryEventType
  class DictionaryEventArgs (line 59) | public class DictionaryEventArgs : EventArgs
    method DictionaryEventArgs (line 76) | public DictionaryEventArgs(DictionaryEventType type, object tag)
    method ToString (line 86) | public override string ToString()

FILE: src/Engine/ListenerList.cs
  class ListenersList (line 14) | internal class ListenersList
    method ListenersList (line 23) | public ListenersList()
    method AddListener (line 38) | public void AddListener(IDictionaryEventListener listener)
    method GetListeners (line 58) | public IEnumerable<IDictionaryEventListener> GetListeners()
    method RemoveListener (line 85) | public void RemoveListener(IDictionaryEventListener listener)
    method ClearDeadReferences (line 106) | private void ClearDeadReferences()

FILE: src/Engine/LocalizeDictionary.cs
  class LocalizeDictionary (line 32) | public sealed class LocalizeDictionary : DependencyObject, INotifyProper...
    method RaisePropertyChanged (line 46) | internal void RaisePropertyChanged(string property)
    method SetCultureFromDependencyProperty (line 133) | [DesignOnly(true)]
    method SetProviderFromDependencyProperty (line 162) | private static void SetProviderFromDependencyProperty(DependencyObject...
    method ProviderUpdated (line 185) | private static void ProviderUpdated(object sender, ProviderChangedEven...
    method ValueChanged (line 190) | private static void ValueChanged(object sender, ValueChangedEventArgs ...
    method SetDefaultProviderFromDependencyProperty (line 200) | private static void SetDefaultProviderFromDependencyProperty(Dependenc...
    method SetSeparationFromDependencyProperty (line 211) | private static void SetSeparationFromDependencyProperty(DependencyObje...
    method SetIncludeInvariantCultureFromDependencyProperty (line 220) | private static void SetIncludeInvariantCultureFromDependencyProperty(D...
    method SetDisableCacheFromDependencyProperty (line 231) | private static void SetDisableCacheFromDependencyProperty(DependencyOb...
    method SetOutputMissingKeysFromDependencyProperty (line 242) | private static void SetOutputMissingKeysFromDependencyProperty(Depende...
    method GetProvider (line 256) | public static ILocalizationProvider GetProvider(DependencyObject obj)
    method GetDefaultProvider (line 267) | public static ILocalizationProvider GetDefaultProvider(DependencyObjec...
    method GetSeparation (line 277) | public static string GetSeparation(DependencyObject target)
    method GetIncludeInvariantCulture (line 287) | public static bool GetIncludeInvariantCulture(DependencyObject target)
    method GetDisableCache (line 297) | public static bool GetDisableCache(DependencyObject target)
    method GetOutputMissingKeys (line 307) | public static bool GetOutputMissingKeys(DependencyObject target)
    method GetDesignCulture (line 320) | [DesignOnly(true)]
    method SetProvider (line 336) | public static void SetProvider(DependencyObject obj, ILocalizationProv...
    method SetDefaultProvider (line 347) | public static void SetDefaultProvider(DependencyObject obj, ILocalizat...
    method SetSeparation (line 357) | public static void SetSeparation(DependencyObject obj, string value)
    method SetIncludeInvariantCulture (line 367) | public static void SetIncludeInvariantCulture(DependencyObject obj, bo...
    method SetDisableCache (line 377) | public static void SetDisableCache(DependencyObject obj, bool value)
    method SetOutputMissingKeys (line 387) | public static void SetOutputMissingKeys(DependencyObject obj, bool value)
    method SetDesignCulture (line 399) | [DesignOnly(true)]
    method LocalizeDictionary (line 466) | private LocalizeDictionary()
    method AvailableCulturesCollectionChanged (line 472) | private void AvailableCulturesCollectionChanged(object sender, NotifyC...
    method GetLocalizedObject (line 781) | public object GetLocalizedObject(string source, string dictionary, str...
    method GetLocalizedObject (line 793) | public object GetLocalizedObject(string key, DependencyObject target, ...
    method GetLocalizedObject (line 814) | public object GetLocalizedObject(string key, DependencyObject target, ...
    method GetFullyQualifiedResourceKey (line 828) | public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(stri...
    method GetFullyQualifiedResourceKey (line 848) | public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(stri...
    method ResourceKeyExists (line 867) | public bool ResourceKeyExists(string resourceAssembly, string resource...
    method ResourceKeyExists (line 885) | public bool ResourceKeyExists(string resourceAssembly, string resource...
    method ResourceKeyExists (line 903) | public bool ResourceKeyExists(string key, CultureInfo cultureToUse, IL...
    method GetIsInDesignMode (line 914) | public bool GetIsInDesignMode()
    method OnNewMissingKeyEvent (line 958) | internal MissingKeyEventArgs OnNewMissingKeyEvent(object sender, strin...
    class DictionaryEvent (line 967) | internal static class DictionaryEvent
      method Invoke (line 980) | internal static void Invoke(DependencyObject sender, DictionaryEvent...
      method AddListener (line 1007) | internal static void AddListener(IDictionaryEventListener listener)
      method RemoveListener (line 1022) | internal static void RemoveListener(IDictionaryEventListener listener)
      method EnumerateListeners (line 1038) | internal static IEnumerable<T> EnumerateListeners<T>()
    method SetCulture (line 1052) | private void SetCulture(CultureInfo c)
    class CultureInfoDelegateCommand (line 1060) | internal class CultureInfoDelegateCommand : ICommand
      method CultureInfoDelegateCommand (line 1082) | public CultureInfoDelegateCommand(Action<CultureInfo> execute)
      method CultureInfoDelegateCommand (line 1097) | public CultureInfoDelegateCommand(Action<CultureInfo> execute, Predi...
      method CanExecute (line 1119) | public bool CanExecute(object parameter)
      method Execute (line 1128) | public void Execute(object parameter)

FILE: src/Engine/MissingKeyEventArgs.cs
  class MissingKeyEventArgs (line 18) | public class MissingKeyEventArgs : EventArgs
    method MissingKeyEventArgs (line 39) | public MissingKeyEventArgs(string key)

FILE: src/Engine/ObjectDependencyManager.cs
  class ObjectDependencyManager (line 20) | public static class ObjectDependencyManager
    method ObjectDependencyManager (line 32) | static ObjectDependencyManager()
    method AddObjectDependency (line 54) | [MethodImpl(MethodImplOptions.Synchronized)]
    method CleanUp (line 110) | public static void CleanUp()
    method CleanUp (line 122) | [MethodImpl(MethodImplOptions.Synchronized)]

FILE: src/Engine/ParentNotifiers.cs
  class ParentNotifiers (line 22) | public class ParentNotifiers
    method ContainsKey (line 32) | public bool ContainsKey(DependencyObject target)
    method Remove (line 41) | public void Remove(DependencyObject target)
    method Add (line 69) | public void Add(DependencyObject target, ParentChangedNotifier parentC...

FILE: src/Engine/SafeTargetInfo.cs
  class SafeTargetInfo (line 19) | public class SafeTargetInfo : TargetInfo
    method SafeTargetInfo (line 33) | public SafeTargetInfo(object targetObject, object targetProperty, Type...
    method FromTargetInfo (line 44) | public static SafeTargetInfo FromTargetInfo(TargetInfo targetInfo)

FILE: src/Engine/WeakReference.cs
  class WeakReference (line 21) | public class WeakReference<T> : WeakReference
    method WeakReference (line 27) | public WeakReference(T target) : base(target)
    method WeakReference (line 36) | public WeakReference(T target, bool trackResurrection)
    method WeakReference (line 46) | protected WeakReference(SerializationInfo info, StreamingContext context)
    method TryGetTarget (line 56) | public bool TryGetTarget(out T target)

FILE: src/Extensions/BLoc.cs
  class BLoc (line 25) | public class BLoc : Binding, INotifyPropertyChanged, IDictionaryEventLis...
    method RaisePropertyChanged (line 39) | internal void RaisePropertyChanged(string property)
    method ClearResourceBuffer (line 94) | public static void ClearResourceBuffer()
    method SafeAddItemToResourceBuffer (line 108) | internal static void SafeAddItemToResourceBuffer(string key, object item)
    method SafeRemoveItemFromResourceBuffer (line 121) | internal static void SafeRemoveItemFromResourceBuffer(string key)
    method BLoc (line 188) | public BLoc()
    method BLoc (line 199) | public BLoc(string key)
    method Dispose (line 208) | public void Dispose()
    method GetForcedCultureOrDefault (line 231) | protected CultureInfo GetForcedCultureOrDefault()
    method ResourceChanged (line 277) | public void ResourceChanged(DependencyObject sender, DictionaryEventAr...
    method UpdateNewValue (line 282) | private void UpdateNewValue()
    method FormatOutput (line 291) | public object FormatOutput()

FILE: src/Extensions/FELoc.cs
  class FELoc (line 31) | public class FELoc : FrameworkElement, IDictionaryEventListener, INotify...
    method RaisePropertyChanged (line 45) | internal void RaisePropertyChanged(string property)
    method ClearResourceBuffer (line 63) | public static void ClearResourceBuffer()
    method SafeAddItemToResourceBuffer (line 77) | internal static void SafeAddItemToResourceBuffer(string key, object item)
    method SafeRemoveItemFromResourceBuffer (line 90) | internal static void SafeRemoveItemFromResourceBuffer(string key)
    method DependencyPropertyChanged (line 226) | private static void DependencyPropertyChanged(DependencyObject obj, De...
    method GetDependencyProperties (line 238) | private IEnumerable<DependencyProperty> GetDependencyProperties(object...
    method RegisterParentNotifier (line 250) | private void RegisterParentNotifier()
    method FELoc (line 287) | public FELoc()
    method FELoc (line 297) | public FELoc(string key)
    method Dispose (line 306) | public void Dispose()
    method GetForcedCultureOrDefault (line 329) | protected CultureInfo GetForcedCultureOrDefault()
    method ResourceChanged (line 375) | public void ResourceChanged(DependencyObject sender, DictionaryEventAr...
    method UpdateNewValue (line 380) | private void UpdateNewValue()
    method FormatOutput (line 389) | public object FormatOutput()

FILE: src/Extensions/LocExtension.cs
  class LocExtension (line 36) | [ContentProperty("ResourceIdentifierKey")]
    method OnNotifyPropertyChanged (line 51) | internal void OnNotifyPropertyChanged(string property)
    method ClearResourceBuffer (line 108) | public static void ClearResourceBuffer()
    method SafeAddItemToResourceBuffer (line 122) | internal static void SafeAddItemToResourceBuffer(string key, object item)
    method SafeRemoveItemFromResourceBuffer (line 135) | internal static void SafeRemoveItemFromResourceBuffer(string key)
    method GetBoundExtension (line 153) | public static LocExtension GetBoundExtension(object target, string pro...
    method GetPropertyName (line 178) | private static string GetPropertyName(object property)
    method LocExtension (line 280) | public LocExtension()
    method LocExtension (line 288) | public LocExtension(object key)
    method OnFirstTargetAdded (line 314) | protected override void OnFirstTargetAdded()
    method OnLastTargetRemoved (line 322) | protected override void OnLastTargetRemoved()
    method ResourceChanged (line 337) | public void ResourceChanged(DependencyObject sender, DictionaryEventAr...
    method ClearItemFromResourceBuffer (line 394) | private void ClearItemFromResourceBuffer(DictionaryEventArgs dictionar...
    method GetForcedCultureOrDefault (line 427) | protected CultureInfo GetForcedCultureOrDefault()
    method FormatOutput (line 470) | public override object FormatOutput(TargetInfo endPoint, TargetInfo info)
    method UpdateOnEndpoint (line 640) | protected override bool UpdateOnEndpoint(TargetInfo endpoint)
    method GetLocalizedValue (line 656) | public static TValue GetLocalizedValue<TValue>(string key, IValueConve...
    method GetLocalizedValue (line 671) | public static TValue GetLocalizedValue<TValue>(string key, CultureInfo...
    method GetLocalizedValue (line 685) | public static TValue GetLocalizedValue<TValue>(string key, DependencyO...
    method GetLocalizedValue (line 701) | public static TValue GetLocalizedValue<TValue>(string key, CultureInfo...
    method GetLocalizedValue (line 750) | public static object GetLocalizedValue(Type t,string key, CultureInfo ...
    method ResolveLocalizedValue (line 797) | public bool ResolveLocalizedValue<TValue>(out TValue resolvedValue)
    method ResolveLocalizedValue (line 812) | public bool ResolveLocalizedValue<TValue>(out TValue resolvedValue, De...
    method ResolveLocalizedValue (line 827) | public bool ResolveLocalizedValue<TValue>(out TValue resolvedValue, Cu...
    method ResolveLocalizedValue (line 842) | public bool ResolveLocalizedValue<TValue>(out TValue resolvedValue, Cu...
    method SetBinding (line 898) | public bool SetBinding(DependencyObject targetObject, object targetPro...
    method SetBinding (line 916) | public bool SetBinding(object targetObject, object targetProperty)
    method SetBinding (line 935) | public bool SetBinding(DependencyObject targetObject, object targetPro...
    method SetBinding (line 954) | public bool SetBinding(object targetObject, object targetProperty, int...
    method ToString (line 984) | public override string ToString()

FILE: src/Providers/FQAssemblyDictionaryKey.cs
  class FQAssemblyDictionaryKey (line 19) | public class FQAssemblyDictionaryKey : FullyQualifiedResourceKeyBase
    method FQAssemblyDictionaryKey (line 45) | public FQAssemblyDictionaryKey(string key, string assembly = null, str...
    method ToString (line 56) | public

FILE: src/Providers/FullyQualifiedResourceKeyBase.cs
  class FullyQualifiedResourceKeyBase (line 15) | public abstract class FullyQualifiedResourceKeyBase

FILE: src/Providers/IInheritingLocalizationProvider.cs
  type IInheritingLocalizationProvider (line 21) | public interface IInheritingLocalizationProvider: ILocalizationProvider

FILE: src/Providers/ILocalizationProvider.cs
  type ILocalizationProvider (line 20) | public interface ILocalizationProvider
    method GetFullyQualifiedResourceKey (line 28) | FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(string key,...
    method GetLocalizedObject (line 37) | object GetLocalizedObject(string key, DependencyObject target, Culture...

FILE: src/Providers/InheritingResxLocalizationProvider.cs
  class InheritingResxLocalizationProvider (line 23) | public class InheritingResxLocalizationProvider : ResxLocalizationProvid...
    method AttachedPropertyChanged (line 53) | private static void AttachedPropertyChanged(DependencyObject obj, Depe...
    method GetDefaultDictionary (line 66) | public static string GetDefaultDictionary(DependencyObject obj)
    method GetDefaultAssembly (line 76) | public static string GetDefaultAssembly(DependencyObject obj)
    method SetDefaultDictionary (line 88) | public static void SetDefaultDictionary(DependencyObject obj, string v...
    method SetDefaultAssembly (line 98) | public static void SetDefaultAssembly(DependencyObject obj, string value)
    method InheritingResxLocalizationProvider (line 140) | private InheritingResxLocalizationProvider()
    method GetAssembly (line 149) | protected override string GetAssembly(DependencyObject target)
    method GetDictionary (line 155) | protected override string GetDictionary(DependencyObject target)

FILE: src/Providers/ParentChangedNotifierHelper.cs
  class ParentChangedNotifierHelper (line 23) | public static class ParentChangedNotifierHelper
    method GetValueOrRegisterParentNotifier (line 35) | public static T GetValueOrRegisterParentNotifier<T>(
    method GetValue (line 134) | public static T GetValue<T>(this DependencyObject target, Func<Depende...
    method GetValueOrRegisterParentNotifier (line 191) | public static T GetValueOrRegisterParentNotifier<T>(
    method GetParent (line 206) | public static DependencyObject GetParent(this DependencyObject depObj,...
    method GetParentInternal (line 214) | private static DependencyObject GetParentInternal(DependencyObject dep...

FILE: src/Providers/ProviderEventArgs.cs
  class ProviderChangedEventArgs (line 19) | public class ProviderChangedEventArgs : EventArgs
    method ProviderChangedEventArgs (line 30) | public ProviderChangedEventArgs(DependencyObject obj)
  class ProviderErrorEventArgs (line 46) | public class ProviderErrorEventArgs : EventArgs
    method ProviderErrorEventArgs (line 69) | public ProviderErrorEventArgs(DependencyObject obj, string key, string...
  class ValueChangedEventArgs (line 87) | public class ValueChangedEventArgs : EventArgs
    method ValueChangedEventArgs (line 110) | public ValueChangedEventArgs(string key, object value, object tag)

FILE: src/Providers/ResxLocalizationProvider.cs
  class ResxLocalizationProvider (line 24) | public class ResxLocalizationProvider : ResxLocalizationProviderBase
    method DefaultDictionaryChanged (line 64) | private static void DefaultDictionaryChanged(DependencyObject obj, Dep...
    method DefaultAssemblyChanged (line 75) | private static void DefaultAssemblyChanged(DependencyObject obj, Depen...
    method IgnoreCaseChanged (line 86) | private static void IgnoreCaseChanged(DependencyObject obj, Dependency...
    method GetDefaultDictionary (line 101) | public static string GetDefaultDictionary(DependencyObject obj)
    method GetDefaultAssembly (line 111) | public static string GetDefaultAssembly(DependencyObject obj)
    method GetIgnoreCase (line 121) | public static bool GetIgnoreCase(DependencyObject obj)
    method SetDefaultDictionary (line 133) | public static void SetDefaultDictionary(DependencyObject obj, string v...
    method SetDefaultAssembly (line 143) | public static void SetDefaultAssembly(DependencyObject obj, string value)
    method SetIgnoreCase (line 153) | public static void SetIgnoreCase(DependencyObject obj, bool value)
    method Reset (line 220) | public static void Reset()
    method ResxLocalizationProvider (line 228) | protected ResxLocalizationProvider()
    method ParentChangedAction (line 240) | private void ParentChangedAction(DependencyObject obj)
    method GetAssembly (line 246) | protected override string GetAssembly(DependencyObject target)
    method GetDictionary (line 256) | protected override string GetDictionary(DependencyObject target)

FILE: src/Providers/ResxLocalizationProviderBase.cs
  class ResxLocalizationProviderBase (line 29) | public abstract class ResxLocalizationProviderBase : DependencyObject, I...
    method GetAssemblyName (line 97) | protected string GetAssemblyName(Assembly assembly)
    method ParseKey (line 119) | public static void ParseKey(string inKey, out string outAssembly, out ...
    method GetAssembly (line 160) | protected abstract string GetAssembly(DependencyObject target);
    method GetDictionary (line 167) | protected abstract string GetDictionary(DependencyObject target);
    method TryGetValue (line 177) | protected bool TryGetValue(string thekey, out ResourceManager result)
    method Add (line 187) | protected void Add(string thekey, ResourceManager value)
    method TryRemove (line 196) | protected void TryRemove(string thekey)
    method ClearResourceManagerList (line 204) | public void ClearResourceManagerList()
    method AddCulture (line 213) | protected void AddCulture(CultureInfo c)
    method UpdateCultureList (line 228) | public bool UpdateCultureList(string resourceAssembly, string resource...
    method GetExecutablePath (line 244) | private static string GetExecutablePath(int processId)
    method IsFileOfInterest (line 274) | private static bool IsFileOfInterest(string f, string dir)
    method GetResourceManager (line 301) | protected ResourceManager GetResourceManager(string resourceAssembly, ...
    method GetResourceManagerFromType (line 545) | private ResourceManager GetResourceManagerFromType(IReflect type)
    method GetFullyQualifiedResourceKey (line 573) | public virtual FullyQualifiedResourceKeyBase GetFullyQualifiedResource...
    method OnProviderChanged (line 608) | protected virtual void OnProviderChanged(DependencyObject target)
    method OnProviderError (line 632) | protected virtual void OnProviderError(DependencyObject target, string...
    method OnValueChanged (line 643) | protected virtual void OnValueChanged(string key, object value, object...
    method GetLocalizedObject (line 655) | public virtual object GetLocalizedObject(string key, DependencyObject ...

FILE: src/TypeConverters/BitmapSourceTypeConverter.cs
  class BitmapSourceTypeConverter (line 25) | public class BitmapSourceTypeConverter : TypeConverter
    method CanConvertFrom (line 28) | public override bool CanConvertFrom(ITypeDescriptorContext context, Ty...
    method CanConvertTo (line 34) | public override bool CanConvertTo(ITypeDescriptorContext context, Type...
    method ConvertFrom (line 40) | public override object ConvertFrom(ITypeDescriptorContext context, Cul...
    method DeleteObject (line 69) | [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    method ConvertTo (line 73) | public override object ConvertTo(ITypeDescriptorContext context, Cultu...

FILE: src/TypeConverters/DefaultConverter.cs
  class DefaultConverter (line 23) | public class DefaultConverter : IValueConverter
    method Convert (line 35) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 90) | public object ConvertBack(object value, Type targetType, object parame...

FILE: src/TypeConverters/RegisterMissingTypeConverters.cs
  class RegisterMissingTypeConverters (line 19) | public static class RegisterMissingTypeConverters
    method Register (line 29) | public static void Register()

FILE: src/TypeConverters/ThicknessConverter.cs
  class ThicknessConverter (line 20) | public class ThicknessConverter : TypeConverter
    method CanConvertFrom (line 23) | public override bool CanConvertFrom(ITypeDescriptorContext context, Sy...
    method ConvertFrom (line 29) | public override object ConvertFrom(ITypeDescriptorContext context, Cul...

FILE: src/ValueConverters/PrependTypeConverter.cs
  class PrependTypeConverter (line 25) | public class PrependTypeConverter : TypeValueConverterBase, IValueConverter
    method Convert (line 29) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 43) | public object ConvertBack(object value, Type targetType, object parame...

FILE: src/ValueConverters/StringFormatConverter.cs
  class StringFormatConverter (line 23) | public class StringFormatConverter : TypeValueConverterBase, IMultiValue...
    method Convert (line 29) | public object Convert(object[] values, Type targetType, object paramet...
    method ConvertBack (line 68) | public object[] ConvertBack(object value, Type[] targetTypes, object p...

FILE: src/ValueConverters/ToLowerConverter.cs
  class ToLowerConverter (line 25) | public class ToLowerConverter : TypeValueConverterBase, IValueConverter
    method Convert (line 29) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 40) | public object ConvertBack(object value, Type targetType, object parame...

FILE: src/ValueConverters/ToUpperConverter.cs
  class ToUpperConverter (line 25) | public class ToUpperConverter : TypeValueConverterBase, IValueConverter
    method Convert (line 29) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 40) | public object ConvertBack(object value, Type targetType, object parame...

FILE: src/ValueConverters/TranslateConverter.cs
  class TranslateConverter (line 27) | public class TranslateConverter : TypeValueConverterBase, IValueConverte...
    method Convert (line 31) | public object Convert(object[] values, Type targetType, object paramet...
    method ConvertBack (line 40) | public object[] ConvertBack(object value, Type[] targetTypes, object p...
    method Convert (line 48) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 82) | public object ConvertBack(object value, Type targetType, object parame...

FILE: src/ValueConverters/TypeValueConverterBase.cs
  class TypeValueConverterBase (line 23) | public abstract class TypeValueConverterBase : MarkupExtension
    method ProvideValue (line 27) | public override object ProvideValue(IServiceProvider serviceProvider)

FILE: tests/AssemblyTest/App.xaml.cs
  class App (line 13) | public partial class App : Application

FILE: tests/AssemblyTest/CaseConverter.cs
  class CaseConverter (line 10) | public class CaseConverter : IValueConverter
    method Convert (line 12) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 27) | public object ConvertBack(object value, Type targetType, object parame...

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

FILE: tests/AssemblyTest/Item.cs
  class Item (line 9) | public class Item : ViewModelBase

FILE: tests/AssemblyTest/MainWindow.xaml.cs
  class MainWindow (line 16) | public partial class MainWindow : Window
    method MainWindow (line 18) | public MainWindow()
    method ButtonAssembly_Click (line 45) | private void ButtonAssembly_Click(object sender, RoutedEventArgs e)
    method Button_Click (line 50) | private void Button_Click(object sender, RoutedEventArgs e)
    method ButtonMultiThreading_Click (line 58) | private void ButtonMultiThreading_Click(object sender, RoutedEventArgs e)
    method ThreadStartingPoint (line 68) | private void ThreadStartingPoint()
    method tempWindow_Closed (line 76) | private void tempWindow_Closed(object sender, EventArgs e)

FILE: tests/AssemblyTest/MyViewModel.cs
  class MyViewModel (line 11) | public class MyViewModel : ViewModelBase
    method MyViewModel (line 47) | public MyViewModel()

FILE: tests/AssemblyTest/Resource.With.Dot.Designer.cs
  class Resource_With_Dot (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resource_With_Dot (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: tests/AssemblyTest/StringFormatProxy.cs
  class StringFormatProxy (line 6) | public class StringFormatProxy : FrameworkElement
    method DataChanged (line 46) | private static void DataChanged(DependencyObject sender, DependencyPro...

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

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

FILE: tests/AssemblyTest/TestDataClass.cs
  class Countries (line 11) | public class Countries : INotifyPropertyChanged
    method OnNotifyPropertyChanged (line 25) | internal void OnNotifyPropertyChanged(string property)

FILE: tests/AssemblyTest/TestEnum.cs
  type TestEnum (line 9) | public enum TestEnum

FILE: tests/AssemblyTest/ViewModelBase.cs
  class ViewModelBase (line 9) | public class ViewModelBase : INotifyPropertyChanged
    method RaisePropertyChanged (line 13) | protected void RaisePropertyChanged(string propertyName)

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

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

FILE: tests/FluentLexTest/Application.xaml.cs
  class Application (line 17) | public partial class Application : System.Windows.Application

FILE: tests/FluentLexTest/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: tests/FluentLexTest/Window.xaml.cs
  class Window (line 25) | public partial class Window : RibbonWindow
    method Window (line 30) | public Window()
    method buttonLanguage_Click (line 35) | private void buttonLanguage_Click(object sender, System.Windows.Routed...

FILE: tests/GapTextWpfTest/App.xaml.cs
  class App (line 14) | public partial class App : Application

FILE: tests/GapTextWpfTest/Converters/ObjectTypeEqualsConverter.cs
  class ObjectTypeEqualsConverter (line 7) | public class ObjectTypeEqualsConverter : IValueConverter
    method Convert (line 9) | public object Convert(object value, Type targetType, object parameter,...
    method ConvertBack (line 16) | public object ConvertBack(object value, Type targetType, object parame...

FILE: tests/GapTextWpfTest/MainWindow.xaml.cs
  type WeekDay (line 9) | public enum WeekDay
  class MainWindow (line 23) | public partial class MainWindow : Window, INotifyPropertyChanged
    method RaisePropertyChanged (line 35) | protected void RaisePropertyChanged(string propertyName)
    method MainWindow (line 107) | public MainWindow()
    method TestTextChanged (line 112) | private void TestTextChanged(object sender, System.Windows.Controls.Te...

FILE: tests/GapTextWpfTest/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: tests/HelloWorldWPF/App.xaml.cs
  class App (line 13) | public partial class App : Application

FILE: tests/HelloWorldWPF/MainWindow.xaml.cs
  class MainWindow (line 25) | public partial class MainWindow : Window
    method MainWindow (line 29) | public MainWindow()
    method Instance_MissingKeyEvent (line 49) | private void Instance_MissingKeyEvent(object sender, MissingKeyEventAr...
    method BindeTestButton_Click (line 58) | private void BindeTestButton_Click(object sender, RoutedEventArgs e)

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

FILE: tests/HelloWorldWPF/TestVM.cs
  class TestVM (line 11) | public class TestVM : INotifyPropertyChanged
    method RaisePropertyChanged (line 25) | internal void RaisePropertyChanged(string property)
    type TestEnum (line 31) | public enum TestEnum

FILE: tests/LeakSample/App.xaml.cs
  class App (line 14) | public partial class App : Application

FILE: tests/LeakSample/MainWindow.xaml.cs
  class MainWindow (line 9) | public partial class MainWindow : Window
    method MainWindow (line 11) | public MainWindow()
    method OnReload (line 16) | private void OnReload(object sender, RoutedEventArgs e)

FILE: tests/LeakSample/MainWindowViewModel.cs
  class MainWindowViewModel (line 12) | public class MainWindowViewModel : INotifyPropertyChanged
    method OnPropertyChanged (line 18) | [NotifyPropertyChangedInvocator]

FILE: tests/LeakSample/Properties/Annotations.cs
  class CanBeNullAttribute (line 48) | [AttributeUsage(
  class NotNullAttribute (line 62) | [AttributeUsage(
  class ItemNotNullAttribute (line 82) | [AttributeUsage(
  class ItemCanBeNullAttribute (line 102) | [AttributeUsage(
  class StringFormatMethodAttribute (line 120) | [AttributeUsage(
    method StringFormatMethodAttribute (line 128) | public StringFormatMethodAttribute([NotNull] string formatParameterName)
  class ValueProviderAttribute (line 163) | [AttributeUsage(
    method ValueProviderAttribute (line 168) | public ValueProviderAttribute([NotNull] string name)
  class InvokerParameterNameAttribute (line 187) | [AttributeUsage(AttributeTargets.Parameter)]
  class NotifyPropertyChangedInvocatorAttribute (line 228) | [AttributeUsage(AttributeTargets.Method)]
    method NotifyPropertyChangedInvocatorAttribute (line 231) | public NotifyPropertyChangedInvocatorAttribute() { }
    method NotifyPropertyChangedInvocatorAttribute (line 232) | public NotifyPropertyChangedInvocatorAttribute([NotNull] string parame...
  class ContractAnnotationAttribute (line 284) | [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    method ContractAnnotationAttribute (line 287) | public ContractAnnotationAttribute([NotNull] string contract)
    method ContractAnnotationAttribute (line 290) | public ContractAnnotationAttribute([NotNull] string contract, bool for...
  class LocalizationRequiredAttribute (line 310) | [AttributeUsage(AttributeTargets.All)]
    method LocalizationRequiredAttribute (line 313) | public LocalizationRequiredAttribute() : this(true) { }
    method LocalizationRequiredAttribute (line 315) | public LocalizationRequiredAttribute(bool required)
  class CannotApplyEqualityOperatorAttribute (line 343) | [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | At...
  class BaseTypeRequiredAttribute (line 357) | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    method BaseTypeRequiredAttribute (line 361) | public BaseTypeRequiredAttribute([NotNull] Type baseType)
  class UsedImplicitlyAttribute (line 373) | [AttributeUsage(AttributeTargets.All, Inherited = false)]
    method UsedImplicitlyAttribute (line 376) | public UsedImplicitlyAttribute()
    method UsedImplicitlyAttribute (line 379) | public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
    method UsedImplicitlyAttribute (line 382) | public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
    method UsedImplicitlyAttribute (line 385) | public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, Impl...
  class MeansImplicitUseAttribute (line 402) | [AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParamet...
    method MeansImplicitUseAttribute (line 405) | public MeansImplicitUseAttribute()
    method MeansImplicitUseAttribute (line 408) | public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
    method MeansImplicitUseAttribute (line 411) | public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
    method MeansImplicitUseAttribute (line 414) | public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, Im...
  type ImplicitUseKindFlags (line 429) | [Flags]
  type ImplicitUseTargetFlags (line 450) | [Flags]
  class PublicAPIAttribute (line 465) | [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)]
    method PublicAPIAttribute (line 469) | public PublicAPIAttribute() { }
    method PublicAPIAttribute (line 471) | public PublicAPIAttribute([NotNull] string comment)
  class InstantHandleAttribute (line 484) | [AttributeUsage(AttributeTargets.Parameter)]
  class PureAttribute (line 498) | [AttributeUsage(AttributeTargets.Method)]
  class MustUseReturnValueAttribute (line 512) | [AttributeUsage(AttributeTargets.Method)]
    method MustUseReturnValueAttribute (line 515) | public MustUseReturnValueAttribute() { }
    method MustUseReturnValueAttribute (line 517) | public MustUseReturnValueAttribute([NotNull] string justification)
  class ProvidesContextAttribute (line 540) | [AttributeUsage(
  class PathReferenceAttribute (line 549) | [AttributeUsage(AttributeTargets.Parameter)]
    method PathReferenceAttribute (line 552) | public PathReferenceAttribute() { }
    method PathReferenceAttribute (line 554) | public PathReferenceAttribute([NotNull, PathReference] string basePath)
  class SourceTemplateAttribute (line 585) | [AttributeUsage(AttributeTargets.Method)]
  class MacroAttribute (line 616) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, Al...
  class AspMvcAreaMasterLocationFormatAttribute (line 642) | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | Att...
    method AspMvcAreaMasterLocationFormatAttribute (line 645) | public AspMvcAreaMasterLocationFormatAttribute([NotNull] string format)
  class AspMvcAreaPartialViewLocationFormatAttribute (line 653) | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | Att...
    method AspMvcAreaPartialViewLocationFormatAttribute (line 656) | public AspMvcAreaPartialViewLocationFormatAttribute([NotNull] string f...
  class AspMvcAreaViewLocationFormatAttribute (line 664) | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | Att...
    method AspMvcAreaViewLocationFormatAttribute (line 667) | public AspMvcAreaViewLocationFormatAttribute([NotNull] string format)
  class AspMvcMasterLocationFormatAttribute (line 675) | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | Att...
    method AspMvcMasterLocationFormatAttribute (line 678) | public AspMvcMasterLocationFormatAttribute([NotNull] string format)
  class AspMvcPartialViewLocationFormatAttribute (line 686) | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | Att...
    method AspMvcPartialViewLocationFormatAttribute (line 689) | public AspMvcPartialViewLocationFormatAttribute([NotNull] string format)
  class AspMvcViewLocationFormatAttribute (line 697) | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | Att...
    method AspMvcViewLocationFormatAttribute (line 700) | public AspMvcViewLocationFormatAttribute([NotNull] string format)
  class AspMvcActionAttribute (line 714) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | A...
    method AspMvcActionAttribute (line 717) | public AspMvcActionAttribute() { }
    method AspMvcActionAttribute (line 719) | public AspMvcActionAttribute([NotNull] string anonymousProperty)
  class AspMvcAreaAttribute (line 732) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
    method AspMvcAreaAttribute (line 735) | public AspMvcAreaAttribute() { }
    method AspMvcAreaAttribute (line 737) | public AspMvcAreaAttribute([NotNull] string anonymousProperty)
  class AspMvcControllerAttribute (line 751) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | A...
    method AspMvcControllerAttribute (line 754) | public AspMvcControllerAttribute() { }
    method AspMvcControllerAttribute (line 756) | public AspMvcControllerAttribute([NotNull] string anonymousProperty)
  class AspMvcMasterAttribute (line 768) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
  class AspMvcModelTypeAttribute (line 775) | [AttributeUsage(AttributeTargets.Parameter)]
  class AspMvcPartialViewAttribute (line 784) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | A...
  class AspMvcSuppressViewErrorAttribute (line 790) | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
  class AspMvcDisplayTemplateAttribute (line 798) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
  class AspMvcEditorTemplateAttribute (line 806) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
  class AspMvcTemplateAttribute (line 814) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
  class AspMvcViewAttribute (line 823) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | A...
  class AspMvcViewComponentAttribute (line 830) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
  class AspMvcViewComponentViewAttribute (line 837) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | A...
  class AspMvcActionSelectorAttribute (line 851) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
  class HtmlElementAttributesAttribute (line 854) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property |...
    method HtmlElementAttributesAttribute (line 857) | public HtmlElementAttributesAttribute() { }
    method HtmlElementAttributesAttribute (line 859) | public HtmlElementAttributesAttribute([NotNull] string name)
  class HtmlAttributeValueAttribute (line 867) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | At...
    method HtmlAttributeValueAttribute (line 870) | public HtmlAttributeValueAttribute([NotNull] string name)
  class RazorSectionAttribute (line 883) | [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
  class CollectionAccessAttribute (line 913) | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor |...
    method CollectionAccessAttribute (line 916) | public CollectionAccessAttribute(CollectionAccessType collectionAccess...
  type CollectionAccessType (line 928) | [Flags]
  class AssertionMethodAttribute (line 946) | [AttributeUsage(AttributeTargets.Method)]
  class AssertionConditionAttribute (line 954) | [AttributeUsage(AttributeTargets.Parameter)]
    method AssertionConditionAttribute (line 957) | public AssertionConditionAttribute(AssertionConditionType conditionType)
  type AssertionConditionType (line 969) | public enum AssertionConditionType
  class TerminatesProgramAttribute (line 985) | [Obsolete("Use [ContractAnnotation('=> halt')] instead")]
  class LinqTunnelAttribute (line 994) | [AttributeUsage(AttributeTargets.Method)]
  class NoEnumerationAttribute (line 1013) | [AttributeUsage(AttributeTargets.Parameter)]
  class RegexPatternAttribute (line 1019) | [AttributeUsage(AttributeTargets.Parameter)]
  class NoReorderAttribute (line 1028) | [AttributeUsage(
  class XamlItemsControlAttribute (line 1036) | [AttributeUsage(AttributeTargets.Class)]
  class XamlItemBindingOfItemsControlAttribute (line 1048) | [AttributeUsage(AttributeTargets.Property)]
  class AspChildControlTypeAttribute (line 1051) | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    method AspChildControlTypeAttribute (line 1054) | public AspChildControlTypeAttribute([NotNull] string tagName, [NotNull...
  class AspDataFieldAttribute (line 1065) | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]
  class AspDataFieldsAttribute (line 1068) | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]
  class AspMethodPropertyAttribute (line 1071) | [AttributeUsage(AttributeTargets.Property)]
  class AspRequiredAttributeAttribute (line 1074) | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    method AspRequiredAttributeAttribute (line 1077) | public AspRequiredAttributeAttribute([NotNull] string attribute)
  class AspTypePropertyAttribute (line 1085) | [AttributeUsage(AttributeTargets.Property)]
    method AspTypePropertyAttribute (line 1090) | public AspTypePropertyAttribute(bool createConstructorReferences)
  class RazorImportNamespaceAttribute (line 1096) | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    method RazorImportNamespaceAttribute (line 1099) | public RazorImportNamespaceAttribute([NotNull] string name)
  class RazorInjectionAttribute (line 1107) | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    method RazorInjectionAttribute (line 1110) | public RazorInjectionAttribute([NotNull] string type, [NotNull] string...
  class RazorDirectiveAttribute (line 1121) | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    method RazorDirectiveAttribute (line 1124) | public RazorDirectiveAttribute([NotNull] string directive)
  class RazorPageBaseTypeAttribute (line 1132) | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    method RazorPageBaseTypeAttribute (line 1135) | public RazorPageBaseTypeAttribute([NotNull] string baseType)
    method RazorPageBaseTypeAttribute (line 1139) | public RazorPageBaseTypeAttribute([NotNull] string baseType, string pa...
  class RazorHelperCommonAttribute (line 1149) | [AttributeUsage(AttributeTargets.Method)]
  class RazorLayoutAttribute (line 1152) | [AttributeUsage(AttributeTargets.Property)]
  class RazorWriteLiteralMethodAttribute (line 1155) | [AttributeUsage(AttributeTargets.Method)]
  class RazorWriteMethodAttribute (line 1158) | [AttributeUsage(AttributeTargets.Method)]
  class RazorWriteMethodParameterAttribute (line 1161) | [AttributeUsage(AttributeTargets.Parameter)]

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

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

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

FILE: tests/LocalizationTest/App.xaml.cs
  class App (line 13) | public partial class App : Application
    method App (line 15) | public App()
    method InitialiseCultures (line 20) | private static void InitialiseCultures()

FILE: tests/LocalizationTest/Loader.xaml.cs
  class Loader (line 8) | public partial class Loader : Window
    method Loader (line 10) | public Loader()
    method Button_Click_1 (line 15) | private void Button_Click_1(object sender, RoutedEventArgs e)

FILE: tests/LocalizationTest/Popup.xaml.cs
  class Popup (line 9) | public partial class Popup : Window
    method Popup (line 15) | public Popup()

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

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

FILE: tests/MemoryTest/App.xaml.cs
  class App (line 13) | public partial class App : Application

FILE: tests/MemoryTest/MainWindow.xaml.cs
  class MainWindow (line 20) | public partial class MainWindow : Window
    method MainWindow (line 22) | public MainWindow()
    method OpenWindow_Click (line 31) | private void OpenWindow_Click(object sender, RoutedEventArgs e)
    method CloseWindows_Click (line 39) | private void CloseWindows_Click(object sender, RoutedEventArgs e)
    method OpenWindowUnlocalized_Click (line 47) | private void OpenWindowUnlocalized_Click(object sender, RoutedEventArg...
    method GCCollect_Click (line 55) | private void GCCollect_Click(object sender, RoutedEventArgs e)

FILE: tests/MemoryTest/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: tests/MemoryTest/TestWindow.xaml.cs
  class TestWindow (line 20) | public partial class TestWindow : Window
    method TestWindow (line 26) | public TestWindow()

FILE: tests/MemoryTest/TestWindowUnlocalized.xaml.cs
  class TestWindowUnlocalized (line 20) | public partial class TestWindowUnlocalized : Window
    method TestWindowUnlocalized (line 26) | public TestWindowUnlocalized()

FILE: tests/ProviderExample/CSVLocalizationProvider.cs
  class CSVLocalizationProvider (line 29) | public class CSVLocalizationProvider : FrameworkElement, ILocalizationPr...
    method OnProviderChanged (line 78) | private void OnProviderChanged()
    method OnProviderError (line 89) | private void OnProviderError(DependencyObject target, string key, stri...
    method GetWorkingDirectory (line 98) | private string GetWorkingDirectory()
    method GetExecutablePath (line 142) | private static string GetExecutablePath(int processId)
    method ParseKey (line 178) | public static void ParseKey(string inKey, out string outAssembly, out ...
    method GetFullyQualifiedResourceKey (line 212) | public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(stri...
    method ParentChangedAction (line 239) | private void ParentChangedAction(DependencyObject obj)
    method OnProviderChanged (line 248) | protected virtual void OnProviderChanged(DependencyObject target)
    method GetAssembly (line 270) | protected string GetAssembly(DependencyObject target)
    method GetDictionary (line 283) | protected string GetDictionary(DependencyObject target)
    method GetLocalizedObject (line 298) | public object GetLocalizedObject(string key, DependencyObject target, ...

FILE: tests/ProviderExample/TestProvider.cs
  class CSVLocalizationProvider (line 29) | public class CSVLocalizationProvider : FrameworkElement, ILocalizationPr...
    method OnProviderChanged (line 78) | private void OnProviderChanged()
    method OnProviderError (line 90) | private void OnProviderError(DependencyObject target, string key, stri...
    method GetWorkingDirectory (line 100) | private string GetWorkingDirectory()
    method ParseKey (line 128) | public static void ParseKey(string inKey, out string outAssembly, out ...
    method GetFullyQualifiedResourceKey (line 162) | public FullyQualifiedResourceKeyBase GetFullyQualifiedResourceKey(stri...
    method ParentChangedAction (line 190) | private void ParentChangedAction(DependencyObject obj)
    method OnProviderChanged (line 199) | protected virtual void OnProviderChanged(DependencyObject target)
    method GetAssembly (line 222) | protected string GetAssembly(DependencyObject target)
    method GetDictionary (line 235) | protected string GetDictionary(DependencyObject target)
    method GetLocalizedObject (line 250) | public object GetLocalizedObject(string key, DependencyObject target, ...

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

FILE: tests/SatelliteAssemblyTest/App.xaml.cs
  class App (line 13) | public partial class App : Application

FILE: tests/SatelliteAssemblyTest/MainWindow.xaml.cs
  class MainWindow (line 20) | public partial class MainWindow : Window
    method MainWindow (line 22) | public MainWindow()

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

FILE: tests/ThreadPerformance/App.xaml.cs
  class App (line 14) | public partial class App : Application

FILE: tests/ThreadPerformance/MainView.xaml.cs
  class MainView (line 25) | public partial class MainView : Window
    method MainView (line 27) | public MainView()
    method BtnOpenWindow_Click (line 33) | private void BtnOpenWindow_Click(object sender, RoutedEventArgs e)
    method threadStart (line 40) | private void threadStart()
    method Window_Closed (line 48) | private void Window_Closed(object sender, EventArgs e)
    method BtnOpenWindow2_Click (line 53) | private void BtnOpenWindow2_Click(object sender, RoutedEventArgs e)
    method BtnGC_Click (line 59) | private void BtnGC_Click(object sender, RoutedEventArgs e)
  class ViewModelBase (line 65) | public class ViewModelBase : INotifyPropertyChanged
    method RaisePropertyChanged (line 69) | protected void RaisePropertyChanged(string propertyName)
  class MainViewModel (line 75) | public class MainViewModel : ViewModelBase
    method MainViewModel (line 77) | public MainViewModel()
    class TabModel (line 105) | public class TabModel : ViewModelBase
      method TabModel (line 124) | public TabModel()
      class ItemModel (line 134) | public class ItemModel : ViewModelBase
        method ItemModel (line 152) | public ItemModel()
        class EntrieModel (line 161) | public class EntrieModel : ViewModelBase

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

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

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

FILE: tests/WPFLocalizeExtension.UnitTests/ValueConvertersTests/LocExtensionTests.cs
  class LocExtensionTests (line 13) | public class LocExtensionTests
    method FormatOutput_SpecifiedFallbackBehavior_SpecifiedOutput (line 22) | [Theory]
    method FormatOutput_MissingKeyEventHandling_FallbackBehaviorNotUsed (line 46) | [Theory]
    method OnMissingKeyEvent (line 80) | private static void OnMissingKeyEvent(object sender, MissingKeyEventAr...

FILE: tests/WPFLocalizeExtension.UnitTests/ValueConvertersTests/StringFormatConverterTests.cs
  class StringFormatConverterTests (line 16) | public class StringFormatConverterTests
    method Convert_SupportedTargetType_ValueConverted (line 38) | [Theory]
    method Convert_UnsupportableTargetTypes_ExceptionThrown (line 56) | [Theory]
    method Convert_ValuesIsNull_ExceptionThrown (line 73) | [Fact]
    method Convert_ValuesIsEmpty_ExceptionThrown (line 87) | [Fact]
    method Convert_FormatStringIsNull_ReturnsNull (line 101) | [Fact]
    method Convert_SecondValueIsUnsetValue_ReturnsNull (line 117) | [Fact]
    method Convert_SpecifiedValues_ValueConverted (line 133) | [Theory]
    method ConvertBack_AnyValue_ReturnsNull (line 150) | [Fact]
Condensed preview — 254 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (987K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 73,
    "preview": "# These are supported funding model platforms\n\ngithub: [konne, seriousm]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 619,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 320,
    "preview": "version: 2\nupdates:\n- package-ecosystem: nuget\n  directory: \"/src\"\n  schedule:\n    interval: daily\n    time: \"08:00\"\n   "
  },
  {
    "path": ".github/release-drafter.yml",
    "chars": 327,
    "preview": "categories:\n  - title: 'Features'\n    labels:\n      - 'feature'\n      - 'enhancement'\n  - title: 'Bug Fixes'\n    labels:"
  },
  {
    "path": ".github/workflows/compile.yml",
    "chars": 1583,
    "preview": "name: .NET\n\non:\n  push:\n    branches: [ master, development ]\n    paths-ignore:\n      - '*.md'\n      - 'docs/**'\n\n  pull"
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 1541,
    "preview": "name: Publish\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  build:\n    runs-on: windows-latest\n\n    steps:\n    - nam"
  },
  {
    "path": ".github/workflows/release-drafter.yaml",
    "chars": 890,
    "preview": "name: Release\n\non:\n  push:\n    branches: [ master ]\n    paths:\n      - 'src/**'\n      - '.github/workflows/release-draft"
  },
  {
    "path": ".gitignore",
    "chars": 405,
    "preview": "#ignore thumbnails created by windows\nThumbs.db\n#Ignore files build by Visual Studio\n*.obj\n*.exe\n*.pdb\n*.user\n*.aps\n*.pc"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 479,
    "preview": "Thanks for reporting an issue!\n\nPlease keep in mind that this project is not actively developed and that @MrCircuit and "
  },
  {
    "path": "LICENSE",
    "chars": 2630,
    "preview": "Microsoft Public License (Ms-PL)\n\nThis license governs use of the accompanying software. If you use the software, you ac"
  },
  {
    "path": "README.md",
    "chars": 1637,
    "preview": "# WPFLocalizeExtension\n[![CodeFactor](https://www.codefactor.io/repository/github/xamlmarkupextensions/WPFLocalizeExtens"
  },
  {
    "path": "docs/BLoc-and-FELoc.md",
    "chars": 38,
    "preview": "# BLoc\n\nThis Extensions is a \n\n# FELoc"
  },
  {
    "path": "docs/FAQ.md",
    "chars": 3440,
    "preview": "# FAQ\n\n## Strong Name and signing\n\nThe current nuget is public signed, this is in general a good compromise, but there a"
  },
  {
    "path": "docs/Features.md",
    "chars": 3695,
    "preview": "# Features:\n\n* First of all: ITS FREE (and will stay free - refer to license section below)\n* Obtain stable results in\n\t"
  },
  {
    "path": "docs/GapText.md",
    "chars": 542,
    "preview": "# Gap Text\n\nUse a multibinding with the [StringFormatConverter](ValueConverters.md).\nThe first **parameter** is the Stri"
  },
  {
    "path": "docs/Installation-and-dependencies.md",
    "chars": 806,
    "preview": "### Installation\n\nThe library itself can be obtained by two ways: \n\n* If you just want to use it without the need of com"
  },
  {
    "path": "docs/Keys.md",
    "chars": 1045,
    "preview": "Keys are entered either directly after the extension name or using the Key property of the LocExtension class. Both will"
  },
  {
    "path": "docs/LocProxy-&-EnumComboBox.md",
    "chars": 1504,
    "preview": "Beginning with v2.1.3 the extension also features an Enum value localization technique. To achieve this one has to emplo"
  },
  {
    "path": "docs/Localization-providers.md",
    "chars": 2488,
    "preview": "The project was restructured to separate the target identification and value conversion in the markup extension from the"
  },
  {
    "path": "docs/Localization.md",
    "chars": 969,
    "preview": "Localization is the task to adapt values such as strings, colors or the text flow direction to the specific language and"
  },
  {
    "path": "docs/Localize.md",
    "chars": 4706,
    "preview": "# Localize Resources\n\nThe main Extension that will be used is `{lex:Loc}` and is a Markupextension with a wide range usa"
  },
  {
    "path": "docs/MarkupExtension-basics.md",
    "chars": 900,
    "preview": "The project is based on the MarkupExtension class of the .NET framework. All classes that derive from this class are ask"
  },
  {
    "path": "docs/Multiple-assemblies-and-dictionaries.md",
    "chars": 1749,
    "preview": "In the previous sections we presumed that a default assembly and dictionary indicating the location of the resource file"
  },
  {
    "path": "docs/Our-first-localized-text.md",
    "chars": 1070,
    "preview": "With the window or control control properly prepared in the previous section, we can now create our first localized text"
  },
  {
    "path": "docs/Preparing-the-XAML-code.md",
    "chars": 1116,
    "preview": "You have to initialize the localization engine in order to get values at design-time and to set up default dictionaries "
  },
  {
    "path": "docs/README.md",
    "chars": 709,
    "preview": "### Introduction\n* [Localization](Localization.md) \n* [MarkupExtension basics](MarkupExtension-basics.md)\n* [Supported p"
  },
  {
    "path": "docs/Resource-files.md",
    "chars": 1935,
    "preview": "### General instructions\n\nAs explained in the section [Supported platforms](Supported-platform.md), the LocalizationExte"
  },
  {
    "path": "docs/Supported-platforms.md",
    "chars": 584,
    "preview": "The LocalizationExtension is designed for and tested under the following frameworks: \n\n* WPF with .NET 4.0+\n\nThe project"
  },
  {
    "path": "docs/ValueConverters.md",
    "chars": 1627,
    "preview": "# Value Converters\n\nThe library delivers some very usefull ValueConverts. All Valueconverters can be used with the stand"
  },
  {
    "path": "src/Deprecated/Engine/GapTextControl.cs",
    "chars": 11880,
    "preview": "#region Copyright information\n// <copyright file=\"GapTextControl.cs\">\n//     Licensed under Microsoft Public License (M"
  },
  {
    "path": "src/Deprecated/Engine/LocBinding.cs",
    "chars": 2629,
    "preview": "#region Copyright information\n// <copyright file=\"LocBinding.cs\">\n//     Licensed under Microsoft Public License (Ms-PL"
  },
  {
    "path": "src/Deprecated/Engine/LocProxy.cs",
    "chars": 5184,
    "preview": "#region Copyright information\n// <copyright file=\"LocBinding.cs\">\n//     Licensed under Microsoft Public License (Ms-PL"
  },
  {
    "path": "src/Deprecated/Extensions/Compatibility.cs",
    "chars": 11785,
    "preview": "#region Copyright information\n// <copyright file=\"Compatibility.cs\">\n//     Licensed under Microsoft Public License (Ms"
  },
  {
    "path": "src/Deprecated/Providers/CSVEmbeddedLocalizationProvider.cs",
    "chars": 11059,
    "preview": "#region Copyright information\n// <copyright file=\"CSVEmbeddedLocalizationProvider.cs\">\n//     Licensed under Microsoft P"
  },
  {
    "path": "src/Deprecated/Providers/CSVLocalizationProvider.cs",
    "chars": 9187,
    "preview": "#region Copyright information\n// <copyright file=\"CSVLocalizationProvider.cs\">\n//     Licensed under Microsoft Public Li"
  },
  {
    "path": "src/Deprecated/Providers/CSVLocalizationProviderBase.cs",
    "chars": 9041,
    "preview": "#region Copyright information\n// <copyright file=\"CSVLocalizationProviderBase.cs\">\n//     Licensed under Microsoft Publi"
  },
  {
    "path": "src/Engine/EnumComboBox.cs",
    "chars": 6373,
    "preview": "#region Copyright information\n// <copyright file=\"EnumComboBox.cs\">\n//     Licensed under Microsoft Public License (Ms-"
  },
  {
    "path": "src/Engine/EnumRun.cs",
    "chars": 4513,
    "preview": "#region Copyright information\n// <copyright file=\"EnumRun.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n/"
  },
  {
    "path": "src/Engine/FallbackBehavior.cs",
    "chars": 513,
    "preview": "namespace WPFLocalizeExtension.Engine\n{\n    /// <summary>\n    /// Behavior when key is not found at the localization pr"
  },
  {
    "path": "src/Engine/IDictionaryEventListener.cs",
    "chars": 2554,
    "preview": "#region Copyright information\n// <copyright file=\"IDictionaryEventListener.cs\">\n//     Licensed under Microsoft Public "
  },
  {
    "path": "src/Engine/ListenerList.cs",
    "chars": 3988,
    "preview": "namespace WPFLocalizeExtension.Engine\n{\n    #region Usings\n    \n    using System;\n    using System.Collections.Generic;"
  },
  {
    "path": "src/Engine/LocalizeDictionary.cs",
    "chars": 45574,
    "preview": "#region Copyright information\n// <copyright file=\"LocalizeDictionary.cs\">\n//     Licensed under Microsoft Public Licens"
  },
  {
    "path": "src/Engine/MissingKeyEventArgs.cs",
    "chars": 1290,
    "preview": "#region Copyright information\n// <copyright file=\"MissingKeyEventArgs.cs\">\n//     Licensed under Microsoft Public Licen"
  },
  {
    "path": "src/Engine/ObjectDependencyManager.cs",
    "chars": 6809,
    "preview": "#region Copyright information\n// <copyright file=\"ObjectDependencyManager.cs\">\n//     Licensed under Microsoft Public L"
  },
  {
    "path": "src/Engine/ParentNotifiers.cs",
    "chars": 2618,
    "preview": "#region Copyright information\n// <copyright file=\"ParentChangedNotifierHelper.cs\">\n//     Licensed under Microsoft Publ"
  },
  {
    "path": "src/Engine/SafeTargetInfo.cs",
    "chars": 2037,
    "preview": "#region Copyright information\n// <copyright file=\"SafeTargetInfo.cs\">\n//     Licensed under Microsoft Public License (M"
  },
  {
    "path": "src/Engine/WeakReference.cs",
    "chars": 2672,
    "preview": "#region Copyright information\n// <copyright file=\"ParentChangedNotifierHelper.cs\">\n//     Licensed under Microsoft Publ"
  },
  {
    "path": "src/Extensions/BLoc.cs",
    "chars": 11070,
    "preview": "#region Copyright information\n// <copyright file=\"BLoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n//  "
  },
  {
    "path": "src/Extensions/FELoc.cs",
    "chars": 18500,
    "preview": "#region Copyright information\n// <copyright file=\"FELoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n// "
  },
  {
    "path": "src/Extensions/LocExtension.cs",
    "chars": 40612,
    "preview": "#region Copyright information\n// <copyright file=\"LocExtension.cs\">\n//     Licensed under Microsoft Public License (Ms-"
  },
  {
    "path": "src/Providers/FQAssemblyDictionaryKey.cs",
    "chars": 2031,
    "preview": "#region Copyright information\n// <copyright file=\"FullyQualifiedResourceKeyBase.cs\">\n//     Licensed under Microsoft Pu"
  },
  {
    "path": "src/Providers/FullyQualifiedResourceKeyBase.cs",
    "chars": 948,
    "preview": "#region Copyright information\n// <copyright file=\"FullyQualifiedResourceKeyBase.cs\">\n//     Licensed under Microsoft Pu"
  },
  {
    "path": "src/Providers/IInheritingLocalizationProvider.cs",
    "chars": 797,
    "preview": "#region Copyright information\n// <copyright file=\"ILocalizationProvider.cs\">\n//     Licensed under Microsoft Public Lic"
  },
  {
    "path": "src/Providers/ILocalizationProvider.cs",
    "chars": 2373,
    "preview": "#region Copyright information\n// <copyright file=\"ILocalizationProvider.cs\">\n//     Licensed under Microsoft Public Lic"
  },
  {
    "path": "src/Providers/InheritingResxLocalizationProvider.cs",
    "chars": 6110,
    "preview": "#region Copyright information\n// <copyright file=\"InheritingResxLocalizationProvider.cs\">\n//     Licensed under Microso"
  },
  {
    "path": "src/Providers/ParentChangedNotifierHelper.cs",
    "chars": 9457,
    "preview": "#region Copyright information\n// <copyright file=\"ParentChangedNotifierHelper.cs\">\n//     Licensed under Microsoft Publ"
  },
  {
    "path": "src/Providers/ProviderEventArgs.cs",
    "chars": 3828,
    "preview": "#region Copyright information\n// <copyright file=\"ProviderEventArgs.cs\">\n//     Licensed under Microsoft Public License"
  },
  {
    "path": "src/Providers/ResxLocalizationProvider.cs",
    "chars": 10059,
    "preview": "#region Copyright information\n// <copyright file=\"ResxLocalizationProvider.cs\">\n//     Licensed under Microsoft Public "
  },
  {
    "path": "src/Providers/ResxLocalizationProviderBase.cs",
    "chars": 28563,
    "preview": "#region Copyright information\n// <copyright file=\"ResxLocalizationProviderBase.cs\">\n//     Licensed under Microsoft Pub"
  },
  {
    "path": "src/Themes/Generic.xaml",
    "chars": 875,
    "preview": "<ResourceDictionary\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x"
  },
  {
    "path": "src/TypeConverters/BitmapSourceTypeConverter.cs",
    "chars": 3191,
    "preview": "#region Copyright information\n// <copyright file=\"BitmapSourceTypeConverter.cs\">\n//     Licensed under Microsoft Public"
  },
  {
    "path": "src/TypeConverters/DefaultConverter.cs",
    "chars": 3733,
    "preview": "#region Copyright information\n// <copyright file=\"StandardLocConverter.cs\">\n//     Licensed under Microsoft Public Lice"
  },
  {
    "path": "src/TypeConverters/RegisterMissingTypeConverters.cs",
    "chars": 1120,
    "preview": "#region Copyright information\n// <copyright file=\"RegisterMissingTypeConverters.cs\">\n//     Licensed under Microsoft Pu"
  },
  {
    "path": "src/TypeConverters/ThicknessConverter.cs",
    "chars": 2227,
    "preview": "#region Copyright information\n// <copyright file=\"ThicknessConverter.cs\">\n//     Licensed under Microsoft Public Licens"
  },
  {
    "path": "src/ValueConverters/PrependTypeConverter.cs",
    "chars": 1621,
    "preview": "#region Copyright information\n// <copyright file=\"BLoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n//  "
  },
  {
    "path": "src/ValueConverters/StringFormatConverter.cs",
    "chars": 2651,
    "preview": "#region Copyright information\n// <copyright file=\"BitmapSourceTypeConverter.cs\">\n//     Licensed under Microsoft Public"
  },
  {
    "path": "src/ValueConverters/ToLowerConverter.cs",
    "chars": 1310,
    "preview": "#region Copyright information\n// <copyright file=\"BLoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n//  "
  },
  {
    "path": "src/ValueConverters/ToUpperConverter.cs",
    "chars": 1310,
    "preview": "#region Copyright information\n// <copyright file=\"BLoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n//  "
  },
  {
    "path": "src/ValueConverters/TranslateConverter.cs",
    "chars": 3044,
    "preview": "#region Copyright information\n// <copyright file=\"BLoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n//  "
  },
  {
    "path": "src/ValueConverters/TypeValueConverterBase.cs",
    "chars": 932,
    "preview": "#region Copyright information\n// <copyright file=\"BLoc.cs\">\n//     Licensed under Microsoft Public License (Ms-PL)\n//  "
  },
  {
    "path": "src/WPFLocalizeExtension.csproj",
    "chars": 4796,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n\t\t<TargetFrameworks>net452;net40;netcoreapp3.1</Targ"
  },
  {
    "path": "src/WPFLocalizeExtension.sln",
    "chars": 1028,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.28010.2019\nM"
  },
  {
    "path": "src/XmlnsPrefix.cs",
    "chars": 2028,
    "preview": "#region Copyright information\n// <copyright file=\"XmlnsDefinitions.cs\">\n//     Licensed under Microsoft Public License "
  },
  {
    "path": "src/packages.lock.json",
    "chars": 6535,
    "preview": "{\n  \"version\": 1,\n  \"dependencies\": {\n    \".NETCoreApp,Version=v3.1\": {\n      \"GitVersion.MsBuild\": {\n        \"type\": \"D"
  },
  {
    "path": "tests/AssemblyTest/App.xaml",
    "chars": 304,
    "preview": "<Application x:Class=\"AssemblyTest.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n"
  },
  {
    "path": "tests/AssemblyTest/App.xaml.cs",
    "chars": 296,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing"
  },
  {
    "path": "tests/AssemblyTest/AssemblyTest.csproj",
    "chars": 1957,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n  <PropertyGroup>\n    <TargetFrameworks>net452;netcoreapp3.1</TargetF"
  },
  {
    "path": "tests/AssemblyTest/CaseConverter.cs",
    "chars": 894,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing"
  },
  {
    "path": "tests/AssemblyTest/CountryRes.Designer.cs",
    "chars": 4875,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/AssemblyTest/CountryRes.de.resx",
    "chars": 6024,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prima"
  },
  {
    "path": "tests/AssemblyTest/CountryRes.resx",
    "chars": 7127,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prima"
  },
  {
    "path": "tests/AssemblyTest/Example.csv",
    "chars": 439,
    "preview": "Key;Value\nButtonAssembly_Background;Aqua\nButtonAssembly_Content;Change Assembly!\nButtonAssembly_FlowDirection;LeftToRig"
  },
  {
    "path": "tests/AssemblyTest/Example.de.csv",
    "chars": 439,
    "preview": "Key;Value\nButtonAssembly_Background;Yellow\nButtonAssembly_Content;Assembly ändern!\nButtonAssembly_FlowDirection;RightTo"
  },
  {
    "path": "tests/AssemblyTest/Item.cs",
    "chars": 362,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nna"
  },
  {
    "path": "tests/AssemblyTest/MainWindow.xaml",
    "chars": 10905,
    "preview": "<Window x:Class=\"AssemblyTest.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n   "
  },
  {
    "path": "tests/AssemblyTest/MainWindow.xaml.cs",
    "chars": 2821,
    "preview": "namespace AssemblyTest\n{\n    using System;\n    using System.Diagnostics;\n    using System.Globalization;\n    using Syst"
  },
  {
    "path": "tests/AssemblyTest/MyViewModel.cs",
    "chars": 1478,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.ComponentModel;\nusin"
  },
  {
    "path": "tests/AssemblyTest/Properties/AssemblyInfo.cs",
    "chars": 1313,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/AssemblyTest/Resource.With.Dot.Designer.cs",
    "chars": 3057,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/AssemblyTest/Resource.With.Dot.de.resx",
    "chars": 5786,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/Resource.With.Dot.en.resx",
    "chars": 5783,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/Resource.With.Dot.resx",
    "chars": 5772,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/StringFormatProxy.cs",
    "chars": 2302,
    "preview": "namespace AssemblyTest\n{\n    using System;\n    using System.Windows;\n\n    public class StringFormatProxy : FrameworkEle"
  },
  {
    "path": "tests/AssemblyTest/Strings.Designer.cs",
    "chars": 7434,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/AssemblyTest/Strings.de.resx",
    "chars": 7261,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/Strings.resx",
    "chars": 7392,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/Strings2.Designer.cs",
    "chars": 5521,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/AssemblyTest/Strings2.de.resx",
    "chars": 6847,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/Strings2.resx",
    "chars": 6844,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTest/TestDataClass.cs",
    "chars": 1826,
    "preview": "namespace AssemblyTest\n{\n    #region Uses\n    using System;\n    using System.Collections.Generic;\n    using System.Comp"
  },
  {
    "path": "tests/AssemblyTest/TestEnum.cs",
    "chars": 287,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\n\nnam"
  },
  {
    "path": "tests/AssemblyTest/ViewModelBase.cs",
    "chars": 488,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\n\nnam"
  },
  {
    "path": "tests/AssemblyTestResourceLib/AssemblyTest.csproj",
    "chars": 7904,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n\t<PropertyGroup>\n\t\t<TargetFramework>net452</TargetFramework>\n\t\t<RootNamespace>Assemb"
  },
  {
    "path": "tests/AssemblyTestResourceLib/AssemblyTestResourceLib.csproj",
    "chars": 2088,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n\t\t<TargetFrameworks>net452;netcoreapp3.1</TargetFram"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Properties/AssemblyInfo.cs",
    "chars": 485,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// Setting ComVi"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Strings.Designer.cs",
    "chars": 6799,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     Dieser Code"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Strings.de.resx",
    "chars": 7138,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Strings.resx",
    "chars": 7136,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Strings2.Designer.cs",
    "chars": 5836,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Strings2.de.resx",
    "chars": 6937,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/AssemblyTestResourceLib/Strings2.resx",
    "chars": 6938,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/FluentLexTest/Application.xaml",
    "chars": 602,
    "preview": "<Application x:Class=\"Fluent.Sample.Foundation.Application\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006"
  },
  {
    "path": "tests/FluentLexTest/Application.xaml.cs",
    "chars": 554,
    "preview": "#region Copyright and License Information\n\n// Fluent Ribbon Control Suite\n// http://fluent.codeplex.com/\n// Copyright ©"
  },
  {
    "path": "tests/FluentLexTest/Fluent.Sample.Foundation.csproj",
    "chars": 2099,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n  <PropertyGroup>\n    <TargetF"
  },
  {
    "path": "tests/FluentLexTest/Properties/AssemblyInfo.cs",
    "chars": 1272,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/FluentLexTest/Properties/Resources.Designer.cs",
    "chars": 4066,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/FluentLexTest/Properties/Resources.de.resx",
    "chars": 6132,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/FluentLexTest/Properties/Resources.resx",
    "chars": 6125,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/FluentLexTest/Window.xaml",
    "chars": 2144,
    "preview": "<Fluent:RibbonWindow x:Class=\"Fluent.Sample.Foundation.Window\"\n\t                 xmlns=\"http://schemas.microsoft.com/wi"
  },
  {
    "path": "tests/FluentLexTest/Window.xaml.cs",
    "chars": 1645,
    "preview": "#region Copyright and License Information\n\n// Fluent Ribbon Control Suite\n// http://fluent.codeplex.com/\n// Copyright ©"
  },
  {
    "path": "tests/FluentLexTest/app.config",
    "chars": 166,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n\t<startup>\n\t\t<supportedRuntime version=\"v4.0\" sku=\".NETFramework"
  },
  {
    "path": "tests/GapTextWpfTest/App.config",
    "chars": 182,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "tests/GapTextWpfTest/App.xaml",
    "chars": 362,
    "preview": "<Application x:Class=\"GapTextWpfTest.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  },
  {
    "path": "tests/GapTextWpfTest/App.xaml.cs",
    "chars": 330,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing"
  },
  {
    "path": "tests/GapTextWpfTest/Converters/ObjectTypeEqualsConverter.cs",
    "chars": 677,
    "preview": "using System;\nusing System.Globalization;\nusing System.Windows.Data;\n\nnamespace GapTextWpfTest.Converters\n{\n    public "
  },
  {
    "path": "tests/GapTextWpfTest/GapTextWpfTest.csproj",
    "chars": 1880,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n\t\t<TargetFram"
  },
  {
    "path": "tests/GapTextWpfTest/MainWindow.xaml",
    "chars": 4481,
    "preview": "<Window x:Class=\"GapTextWpfTest.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n "
  },
  {
    "path": "tests/GapTextWpfTest/MainWindow.xaml.cs",
    "chars": 3223,
    "preview": "namespace GapTextWpfTest\n{\n    using System;\n    using System.Collections.ObjectModel;\n    using System.ComponentModel;"
  },
  {
    "path": "tests/GapTextWpfTest/Properties/AssemblyInfo.cs",
    "chars": 1738,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/GapTextWpfTest/Properties/Resources.Designer.cs",
    "chars": 4739,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/GapTextWpfTest/Properties/Resources.resx",
    "chars": 6277,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/GapTextWpfTest/packages.config",
    "chars": 526,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"xunit\" version=\"2.2.0\" targetFramework=\"net452\" />\n  <"
  },
  {
    "path": "tests/HelloWorldWPF/App.xaml",
    "chars": 313,
    "preview": "<Application x:Class=\"HalloWeltWPF.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n"
  },
  {
    "path": "tests/HelloWorldWPF/App.xaml.cs",
    "chars": 296,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing"
  },
  {
    "path": "tests/HelloWorldWPF/HelloWorldWPF.csproj",
    "chars": 1892,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n    <TargetFr"
  },
  {
    "path": "tests/HelloWorldWPF/MainWindow.xaml",
    "chars": 6159,
    "preview": "<Window x:Class=\"HalloWeltWPF.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n   "
  },
  {
    "path": "tests/HelloWorldWPF/MainWindow.xaml.cs",
    "chars": 2393,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Globalization;\nusing System.L"
  },
  {
    "path": "tests/HelloWorldWPF/Properties/AssemblyInfo.cs",
    "chars": 1464,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/HelloWorldWPF/Ressourcen.Designer.cs",
    "chars": 4962,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/HelloWorldWPF/Ressourcen.ar.resx",
    "chars": 6352,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/HelloWorldWPF/Ressourcen.de.resx",
    "chars": 6355,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/HelloWorldWPF/Ressourcen.en.resx",
    "chars": 6833,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/HelloWorldWPF/Ressourcen.he.resx",
    "chars": 6340,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/HelloWorldWPF/Ressourcen.resx",
    "chars": 6336,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/HelloWorldWPF/TestVM.cs",
    "chars": 1864,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\nusin"
  },
  {
    "path": "tests/HelloWorldWPF.sln",
    "chars": 3107,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3001"
  },
  {
    "path": "tests/LeakSample/App.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".N"
  },
  {
    "path": "tests/LeakSample/App.xaml",
    "chars": 363,
    "preview": "<Application x:Class=\"LeakSample.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n  "
  },
  {
    "path": "tests/LeakSample/App.xaml.cs",
    "chars": 324,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing"
  },
  {
    "path": "tests/LeakSample/LeakSample.csproj",
    "chars": 1682,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n    <TargetFr"
  },
  {
    "path": "tests/LeakSample/MainWindow.xaml",
    "chars": 1619,
    "preview": "<Window x:Class=\"LeakSample.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n     "
  },
  {
    "path": "tests/LeakSample/MainWindow.xaml.cs",
    "chars": 449,
    "preview": "using System;\nusing System.Windows;\n\nnamespace LeakSample\n{\n    /// <summary>\n    /// Interaction logic for MainWindow."
  },
  {
    "path": "tests/LeakSample/MainWindowViewModel.cs",
    "chars": 694,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.Co"
  },
  {
    "path": "tests/LeakSample/Properties/Annotations.cs",
    "chars": 45644,
    "preview": "/* MIT License\n\nCopyright (c) 2016 JetBrains http://www.jetbrains.com\n\nPermission is hereby granted, free of charge, to"
  },
  {
    "path": "tests/LeakSample/Properties/AssemblyInfo.cs",
    "chars": 1224,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/LeakSample/Properties/Resources.Designer.cs",
    "chars": 2777,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/LeakSample/Properties/Resources.resx",
    "chars": 5494,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/LeakSample/Properties/Settings.Designer.cs",
    "chars": 1065,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/LeakSample/Properties/Settings.settings",
    "chars": 193,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"uri:settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    "
  },
  {
    "path": "tests/LeakSample/Resources/Localization.Designer.cs",
    "chars": 3619,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/LeakSample/Resources/Localization.resx",
    "chars": 5938,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/LeakSample.sln",
    "chars": 1603,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.2992"
  },
  {
    "path": "tests/LocalizationTest/App.config",
    "chars": 1043,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <configSections>\n        <sectionGroup name=\"userSettings\" "
  },
  {
    "path": "tests/LocalizationTest/App.xaml",
    "chars": 313,
    "preview": "<Application x:Class=\"LocalizationTest.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentati"
  },
  {
    "path": "tests/LocalizationTest/App.xaml.cs",
    "chars": 995,
    "preview": "using System.Globalization;\nusing System.Threading;\nusing System.Windows;\nusing System.Windows.Markup;\nusing Localizati"
  },
  {
    "path": "tests/LocalizationTest/Loader.xaml",
    "chars": 400,
    "preview": "<Window x:Class=\"LocalizationTest.Loader\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n   "
  },
  {
    "path": "tests/LocalizationTest/Loader.xaml.cs",
    "chars": 343,
    "preview": "using System.Windows;\n\nnamespace LocalizationTest\n{\n\t/// <summary>\n\t/// Interaction logic for Loader.xaml\n\t/// </summar"
  },
  {
    "path": "tests/LocalizationTest/LocalizationTest.csproj",
    "chars": 2493,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n    <TargetFr"
  },
  {
    "path": "tests/LocalizationTest/Popup.xaml",
    "chars": 659,
    "preview": "<Window x:Class=\"LocalizationTest.Popup\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    "
  },
  {
    "path": "tests/LocalizationTest/Popup.xaml.cs",
    "chars": 575,
    "preview": "using System.Diagnostics;\nusing System.Windows;\n\nnamespace LocalizationTest\n{\n\t/// <summary>\n\t/// Interaction logic for"
  },
  {
    "path": "tests/LocalizationTest/Properties/AssemblyInfo.cs",
    "chars": 1296,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/LocalizationTest/Properties/Settings.Designer.cs",
    "chars": 1919,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/LocalizationTest/Properties/Settings.settings",
    "chars": 542,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\""
  },
  {
    "path": "tests/LocalizationTest/TestResource.Designer.cs",
    "chars": 3073,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/LocalizationTest/TestResource.en-GB.resx",
    "chars": 5790,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/LocalizationTest/TestResource.pl-PL.resx",
    "chars": 5790,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/LocalizationTest/TestResource.resx",
    "chars": 5785,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/LocalizationTest.sln",
    "chars": 1613,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.28307.421\nMi"
  },
  {
    "path": "tests/MemoryTest/App.xaml",
    "chars": 302,
    "preview": "<Application x:Class=\"MemoryTest.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n  "
  },
  {
    "path": "tests/MemoryTest/App.xaml.cs",
    "chars": 294,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing"
  },
  {
    "path": "tests/MemoryTest/MainWindow.xaml",
    "chars": 1012,
    "preview": "<Window x:Class=\"MemoryTest.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n     "
  },
  {
    "path": "tests/MemoryTest/MainWindow.xaml.cs",
    "chars": 1503,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows;\nusing Syste"
  },
  {
    "path": "tests/MemoryTest/MemoryTest.csproj",
    "chars": 1889,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n\t\t<TargetFram"
  },
  {
    "path": "tests/MemoryTest/Properties/AssemblyInfo.cs",
    "chars": 1467,
    "preview": "using System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "tests/MemoryTest/Properties/Resources.Designer.cs",
    "chars": 3055,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/MemoryTest/Properties/Resources.de.resx",
    "chars": 5790,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/MemoryTest/Properties/Resources.en.resx",
    "chars": 5787,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/MemoryTest/Properties/Resources.resx",
    "chars": 5780,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/MemoryTest/TestWindow.xaml",
    "chars": 542,
    "preview": "<Window x:Class=\"MemoryTest.TestWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n     "
  },
  {
    "path": "tests/MemoryTest/TestWindow.xaml.cs",
    "chars": 1012,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing S"
  },
  {
    "path": "tests/MemoryTest/TestWindowUnlocalized.xaml",
    "chars": 317,
    "preview": "<Window x:Class=\"MemoryTest.TestWindowUnlocalized\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presenta"
  },
  {
    "path": "tests/MemoryTest/TestWindowUnlocalized.xaml.cs",
    "chars": 1060,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing S"
  },
  {
    "path": "tests/MemoryTest.sln",
    "chars": 1440,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3001"
  },
  {
    "path": "tests/ProviderExample/CSVLocalizationProvider.cs",
    "chars": 13918,
    "preview": "#region Copyright information\n// <copyright file=\"CSVLocalizationProvider.cs\">\n//     Licensed under Microsoft Public L"
  },
  {
    "path": "tests/ProviderExample/ProviderExample.csproj",
    "chars": 1697,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n  <PropertyGroup>\n    <TargetFrameworks>net452;netcoreapp3.1</TargetF"
  },
  {
    "path": "tests/ProviderExample/TestProvider.cs",
    "chars": 12020,
    "preview": "#region Copyright information\n// <copyright file=\"CSVLocalizationProvider.cs\">\n//     Licensed under Microsoft Public L"
  },
  {
    "path": "tests/ResourceAssembly/Properties/AssemblyInfo.cs",
    "chars": 486,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// Setting ComVi"
  },
  {
    "path": "tests/ResourceAssembly/ResTexts.Designer.cs",
    "chars": 3057,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "tests/ResourceAssembly/ResTexts.resx",
    "chars": 5788,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "tests/ResourceAssembly/ResourceAssembly.csproj",
    "chars": 1409,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n\t<PropertyGroup>\n\t\t<TargetFram"
  }
]

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

About this extraction

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