Repository: open-feature/java-sdk
Pull request #655 (2023-10-13 20:23:21)

feat: implement spec 0.7.0 changes
* run any event handler immediately if the provider is in the associated state, not just ready
* add providerName to event details
* add STALE provider state
* update/add associated tests
* also fixed spec/test associations mismatches from previous changes

fixes: https://github.com/open-feature/java-sdk/issues/599

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) Report
> Merging [#655](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) (7fc0bda) into [main](https://app.codecov.io/gh/open-feature/java-sdk/commit/1a7f7de6e4ab0971acd574c91ac196960df37391?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) (1a7f7de) will **increase** coverage by `0.16%`.
> The diff coverage is `94.73%`.

> :exclamation: Current head 7fc0bda differs from pull request most recent head d7876df. Consider uploading reports for the commit d7876df to get more accurate results

```diff
@@             Coverage Diff              @@
##               main     #655      +/-   ##
============================================
+ Coverage     94.54%   94.70%   +0.16%     
- Complexity      357      363       +6     
============================================
  Files            32       32              
  Lines           843      850       +7     
  Branches         52       51       -1     
============================================
+ Hits            797      805       +8     
+ Misses           24       23       -1     
  Partials         22       22              
```

| [Flag](https://app.codecov.io/gh/open-feature/java-sdk/pull/655/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/open-feature/java-sdk/pull/655/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) | `94.70% <94.73%> (+0.16%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Files](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) | Coverage Δ | |
|---|---|---|
| [...rc/main/java/dev/openfeature/sdk/EventDetails.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL0V2ZW50RGV0YWlscy5qYXZh) | `100.00% <100.00%> (ø)` | |
| [...ava/dev/openfeature/sdk/FlagEvaluationDetails.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL0ZsYWdFdmFsdWF0aW9uRGV0YWlscy5qYXZh) | `100.00% <100.00%> (ø)` | |
| [.../main/java/dev/openfeature/sdk/OpenFeatureAPI.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL09wZW5GZWF0dXJlQVBJLmphdmE=) | `100.00% <100.00%> (ø)` | |
| [...c/main/java/dev/openfeature/sdk/ProviderState.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/655?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL1Byb3ZpZGVyU3RhdGUuamF2YQ==) | `66.66% <50.00%> (-33.34%)` | :arrow_down: |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/open-feature/java-sdk/pull/655/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature)

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature)

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


beeme1mr: Let's try and merge this tomorrow unless someone identifies a blocker.
toddbaert: @thiyagu06 I've accepted the change you proposed. Can you re-review?
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=open-feature_java-sdk&pullRequest=655)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=655&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=655&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/README.md b/README.md
index ebfa92c..2bb3b78 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,8 @@
 <!-- x-hide-in-docs-end -->
 <!-- The 'github-badges' class is used in the docs -->
 <p align="center" class="github-badges">
-  <a href="https://github.com/open-feature/spec/tree/v0.6.0">
-    <img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.6.0&color=yellow&style=for-the-badge" />
+  <a href="https://github.com/open-feature/spec/tree/v0.7.0">
+    <img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.7.0&color=yellow&style=for-the-badge" />
   </a>
   <!-- x-release-please-start-version -->
 
diff --git a/src/main/java/dev/openfeature/sdk/EventDetails.java b/src/main/java/dev/openfeature/sdk/EventDetails.java
index 3f6db15..d4ecac9 100644
--- a/src/main/java/dev/openfeature/sdk/EventDetails.java
+++ b/src/main/java/dev/openfeature/sdk/EventDetails.java
@@ -7,19 +7,23 @@ import lombok.experimental.SuperBuilder;
 /**
  * The details of a particular event.
  */
-@Data @SuperBuilder(toBuilder = true)
+@Data
+@SuperBuilder(toBuilder = true)
 public class EventDetails extends ProviderEventDetails {
     private String clientName;
+    private String providerName;
 
-    static EventDetails fromProviderEventDetails(ProviderEventDetails providerEventDetails) {
-        return EventDetails.fromProviderEventDetails(providerEventDetails, null);
+    static EventDetails fromProviderEventDetails(ProviderEventDetails providerEventDetails, String providerName) {
+        return EventDetails.fromProviderEventDetails(providerEventDetails, providerName, null);
     }
 
     static EventDetails fromProviderEventDetails(
             ProviderEventDetails providerEventDetails,
+            @Nullable String providerName,
             @Nullable String clientName) {
         return EventDetails.builder()
                 .clientName(clientName)
+                .providerName(providerName)
                 .flagsChanged(providerEventDetails.getFlagsChanged())
                 .eventMetadata(providerEventDetails.getEventMetadata())
                 .message(providerEventDetails.getMessage())
diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java
index b324c07..af48d87 100644
--- a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java
+++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java
@@ -1,5 +1,7 @@
 package dev.openfeature.sdk;
 
+import java.util.Optional;
+
 import javax.annotation.Nullable;
 
 import lombok.AllArgsConstructor;
@@ -8,7 +10,8 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * Contains information about how the provider resolved a flag, including the resolved value.
+ * Contains information about how the provider resolved a flag, including the
+ * resolved value.
  *
  * @param <T> the type of the flag being evaluated.
  */
@@ -20,11 +23,15 @@ public class FlagEvaluationDetails<T> implements BaseEvaluation<T> {
 
     private String flagKey;
     private T value;
-    @Nullable private String variant;
-    @Nullable private String reason;
+    @Nullable
+    private String variant;
+    @Nullable
+    private String reason;
     private ErrorCode errorCode;
-    @Nullable private String errorMessage;
-    @Builder.Default private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
+    @Nullable
+    private String errorMessage;
+    @Builder.Default
+    private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
 
     /**
      * Generate detail payload from the provider response.
@@ -42,7 +49,8 @@ public class FlagEvaluationDetails<T> implements BaseEvaluation<T> {
                 .reason(providerEval.getReason())
                 .errorMessage(providerEval.getErrorMessage())
                 .errorCode(providerEval.getErrorCode())
-                .flagMetadata(providerEval.getFlagMetadata())
+                .flagMetadata(
+                        Optional.ofNullable(providerEval.getFlagMetadata()).orElse(ImmutableMetadata.builder().build()))
                 .build();
     }
 }
diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java
index 47c0938..7448ad7 100644
--- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java
+++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java
@@ -3,6 +3,7 @@ package dev.openfeature.sdk;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.function.Consumer;
 
@@ -100,12 +101,12 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
     public void setProvider(FeatureProvider provider) {
         try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
             providerRepository.setProvider(
-                provider,
+                    provider,
                     this::attachEventProvider,
                     this::emitReady,
                     this::detachEventProvider,
                     this::emitError,
-                false);
+                    false);
         }
     }
 
@@ -118,12 +119,12 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
     public void setProvider(String clientName, FeatureProvider provider) {
         try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
             providerRepository.setProvider(clientName,
-                provider,
-                this::attachEventProvider,
-                this::emitReady,
-                this::detachEventProvider,
-                this::emitError,
-                false);
+                    provider,
+                    this::attachEventProvider,
+                    this::emitReady,
+                    this::detachEventProvider,
+                    this::emitError,
+                    false);
         }
     }
 
@@ -133,12 +134,12 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
     public void setProviderAndWait(FeatureProvider provider) {
         try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
             providerRepository.setProvider(
-                provider,
-                this::attachEventProvider,
-                this::emitReady,
-                this::detachEventProvider,
-                this::emitError,
-                true);
+                    provider,
+                    this::attachEventProvider,
+                    this::emitReady,
+                    this::detachEventProvider,
+                    this::emitError,
+                    true);
         }
     }
 
@@ -151,18 +152,18 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
     public void setProviderAndWait(String clientName, FeatureProvider provider) {
         try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
             providerRepository.setProvider(clientName,
-                provider,
-                this::attachEventProvider,
-                this::emitReady,
-                this::detachEventProvider,
-                this::emitError,
-                true);
+                    provider,
+                    this::attachEventProvider,
+                    this::emitReady,
+                    this::detachEventProvider,
+                    this::emitError,
+                    true);
         }
     }
 
     private void attachEventProvider(FeatureProvider provider) {
         if (provider instanceof EventProvider) {
-            ((EventProvider)provider).attach((p, event, details) -> {
+            ((EventProvider) provider).attach((p, event, details) -> {
                 runHandlersForProvider(p, event, details);
             });
         }
@@ -174,7 +175,7 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
 
     private void detachEventProvider(FeatureProvider provider) {
         if (provider instanceof EventProvider) {
-            ((EventProvider)provider).detach();
+            ((EventProvider) provider).detach();
         }
     }
 
@@ -229,9 +230,10 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
 
     /**
      * Shut down and reset the current status of OpenFeature API.
-     * This call cleans up all active providers and attempts to shut down internal event handling mechanisms.
+     * This call cleans up all active providers and attempts to shut down internal
+     * event handling mechanisms.
      * Once shut down is complete, API is reset and ready to use again.
-     * */
+     */
     public void shutdown() {
         try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
             providerRepository.shutdown();
@@ -302,9 +304,9 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
 
     void addHandler(String clientName, ProviderEvent event, Consumer<EventDetails> handler) {
         try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
-            // if the provider is READY, run immediately
-            if (ProviderEvent.PROVIDER_READY.equals(event)
-                    && ProviderState.READY.equals(this.providerRepository.getProvider(clientName).getState())) {
+            // if the provider is in the state associated with event, run immediately
+            if (Optional.ofNullable(this.providerRepository.getProvider(clientName).getState())
+                    .orElse(ProviderState.READY).matchesEvent(event)) {
                 eventSupport.runHandler(handler, EventDetails.builder().clientName(clientName).build());
             }
             eventSupport.addClientHandler(clientName, event, handler);
@@ -315,30 +317,36 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {
      * Runs the handlers associated with a particular provider.
      * 
      * @param provider the provider from where this event originated
-     * @param event the event type
-     * @param details the event details
+     * @param event    the event type
+     * @param details  the event details
      */
     private void runHandlersForProvider(FeatureProvider provider, ProviderEvent event, ProviderEventDetails details) {
         try (AutoCloseableLock __ = lock.readLockAutoCloseable()) {
-    
+
             List<String> clientNamesForProvider = providerRepository
-                .getClientNamesForProvider(provider);
-    
+                    .getClientNamesForProvider(provider);
+
+            final String providerName = Optional.ofNullable(provider.getMetadata())
+                    .map(metadata -> metadata.getName())
+                    .orElse(null);
+
             // run the global handlers
-            eventSupport.runGlobalHandlers(event, EventDetails.fromProviderEventDetails(details));
+            eventSupport.runGlobalHandlers(event, EventDetails.fromProviderEventDetails(details, providerName));
 
             // run the handlers associated with named clients for this provider
-            clientNamesForProvider.forEach(name -> {   
-                eventSupport.runClientHandlers(name, event, EventDetails.fromProviderEventDetails(details, name));
+            clientNamesForProvider.forEach(name -> {
+                eventSupport.runClientHandlers(name, event,
+                        EventDetails.fromProviderEventDetails(details, providerName, name));
             });
-    
+
             if (providerRepository.isDefaultProvider(provider)) {
                 // run handlers for clients that have no bound providers (since this is the default)
                 Set<String> allClientNames = eventSupport.getAllClientNames();
                 Set<String> boundClientNames = providerRepository.getAllBoundClientNames();
                 allClientNames.removeAll(boundClientNames);
                 allClientNames.forEach(name -> {
-                    eventSupport.runClientHandlers(name, event, EventDetails.fromProviderEventDetails(details, name));
+                    eventSupport.runClientHandlers(name, event,
+                            EventDetails.fromProviderEventDetails(details, providerName, name));
                 });
             }
         }
diff --git a/src/main/java/dev/openfeature/sdk/ProviderState.java b/src/main/java/dev/openfeature/sdk/ProviderState.java
index 6685f8f..a66d4e9 100644
--- a/src/main/java/dev/openfeature/sdk/ProviderState.java
+++ b/src/main/java/dev/openfeature/sdk/ProviderState.java
@@ -4,5 +4,17 @@ package dev.openfeature.sdk;
  * Indicates the state of the provider.
  */
 public enum ProviderState {
-    READY, NOT_READY, ERROR;
+    READY, NOT_READY, ERROR, STALE;
+
+    /**
+     * Returns true if the passed ProviderEvent maps to this ProviderState.
+     * 
+     * @param event event to compare
+     * @return boolean if matches.
+     */
+    boolean matchesEvent(ProviderEvent event) {
+        return this == READY && event == ProviderEvent.PROVIDER_READY
+                || this == STALE && event == ProviderEvent.PROVIDER_STALE
+                || this == ERROR && event == ProviderEvent.PROVIDER_ERROR;
+    }
 }


Test patch:
diff --git a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java
index 8d1c451..4fdc433 100644
--- a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java
+++ b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java
@@ -4,10 +4,19 @@ class DoSomethingProvider implements FeatureProvider {
 
     static final String name = "Something";
     // Flag evaluation metadata
-    static final ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
+    static final ImmutableMetadata DEFAULT_METADATA = ImmutableMetadata.builder().build();
+    private ImmutableMetadata flagMetadata;
 
     private EvaluationContext savedContext;
 
+    public DoSomethingProvider() {
+        this.flagMetadata = DEFAULT_METADATA;
+    }
+
+    public DoSomethingProvider(ImmutableMetadata flagMetadata) {
+        this.flagMetadata = flagMetadata;
+    }
+
     EvaluationContext getMergedContext() {
         return savedContext;
     }
diff --git a/src/test/java/dev/openfeature/sdk/EventsTest.java b/src/test/java/dev/openfeature/sdk/EventsTest.java
index 70f8165..f9f8e4b 100644
--- a/src/test/java/dev/openfeature/sdk/EventsTest.java
+++ b/src/test/java/dev/openfeature/sdk/EventsTest.java
@@ -24,7 +24,7 @@ import io.cucumber.java.AfterAll;
 
 class EventsTest {
 
-    private static final int TIMEOUT = 200;
+    private static final int TIMEOUT = 300;
     private static final int INIT_DELAY = TIMEOUT / 2;
 
     @AfterAll
@@ -470,7 +470,7 @@ class EventsTest {
     @Test
     @DisplayName("should have all properties")
     @Specification(number = "5.2.4", text = "The handler function MUST accept a event details parameter.")
-    @Specification(number = "5.2.3", text = "The event details MUST contain the client name associated with the event.")
+    @Specification(number = "5.2.3", text = "The `event details` MUST contain the `provider name` associated with the event.")
     void shouldHaveAllProperties() throws Exception {
         final Consumer<EventDetails> handler1 = mockHandler();
         final Consumer<EventDetails> handler2 = mockHandler();
@@ -514,9 +514,9 @@ class EventsTest {
 
     @Test
     @DisplayName("if the provider is ready handlers must run immediately")
-    @Specification(number = "5.3.3", text = "PROVIDER_READY handlers attached after the provider is already in a ready state MUST run immediately.")
-    void readyMustRunImmediately() throws Exception {
-        final String name = "readyMustRunImmediately";
+    @Specification(number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.")
+    void matchingReadyEventsMustRunImmediately() throws Exception {
+        final String name = "matchingEventsMustRunImmediately";
         final Consumer<EventDetails> handler = mockHandler();
 
         // provider which is already ready
@@ -529,6 +529,40 @@ class EventsTest {
         verify(handler, timeout(TIMEOUT)).accept(any());
     }
 
+    @Test
+    @DisplayName("if the provider is ready handlers must run immediately")
+    @Specification(number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.")
+    void matchingStaleEventsMustRunImmediately() throws Exception {
+        final String name = "matchingEventsMustRunImmediately";
+        final Consumer<EventDetails> handler = mockHandler();
+
+        // provider which is already stale
+        TestEventsProvider provider = new TestEventsProvider(ProviderState.STALE);
+        OpenFeatureAPI.getInstance().setProvider(name, provider);
+
+        // should run even thought handler was added after stale
+        Client client = OpenFeatureAPI.getInstance().getClient(name);
+        client.onProviderStale(handler);
+        verify(handler, timeout(TIMEOUT)).accept(any());
+    }
+
+    @Test
+    @DisplayName("if the provider is ready handlers must run immediately")
+    @Specification(number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.")
+    void matchingErrorEventsMustRunImmediately() throws Exception {
+        final String name = "matchingEventsMustRunImmediately";
+        final Consumer<EventDetails> handler = mockHandler();
+
+        // provider which is already in error
+        TestEventsProvider provider = new TestEventsProvider(ProviderState.ERROR);
+        OpenFeatureAPI.getInstance().setProvider(name, provider);
+
+        // should run even thought handler was added after error
+        Client client = OpenFeatureAPI.getInstance().getClient(name);
+        client.onProviderError(handler);
+        verify(handler, timeout(TIMEOUT)).accept(any());
+    }
+
     @Test
     @DisplayName("must persist across changes")
     @Specification(number = "5.2.6", text = "Event handlers MUST persist across provider changes.")
@@ -560,6 +594,7 @@ class EventsTest {
 
     @Nested
     class HandlerRemoval {
+        @Specification(number="5.2.7", text="The API and client MUST provide a function allowing the removal of event handlers.")
         @Test
         @DisplayName("should not run removed events")
         void removedEventsShouldNotRun() {
diff --git a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java
index 35eb076..52c36dc 100644
--- a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java
+++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java
@@ -1,10 +1,11 @@
 package dev.openfeature.sdk;
 
-import static dev.openfeature.sdk.DoSomethingProvider.flagMetadata;
+import static dev.openfeature.sdk.DoSomethingProvider.DEFAULT_METADATA;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertSame;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -140,8 +141,8 @@ class FlagEvaluationSpecTest implements HookFixtures {
         assertTrue(hooks.contains(m2));
     }
 
-    @Specification(number="1.3.1", text="The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns the flag value.")
-    @Specification(number="1.3.2.1", text="The client SHOULD provide functions for floating-point numbers and integers, consistent with language idioms.")
+    @Specification(number="1.3.1.1", text="The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns the flag value.")
+    @Specification(number="1.3.3.1", text="The client SHOULD provide functions for floating-point numbers and integers, consistent with language idioms.")
     @Test void value_flags() {
         FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider());
 
@@ -169,12 +170,12 @@ class FlagEvaluationSpecTest implements HookFixtures {
         assertEquals(null, c.getObjectValue(key, new Value(), new ImmutableContext(), FlagEvaluationOptions.builder().build()));
     }
 
-    @Specification(number="1.4.1", text="The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns an evaluation details structure.")
-    @Specification(number="1.4.2", text="The evaluation details structure's value field MUST contain the evaluated flag value.")
-    @Specification(number="1.4.3.1", text="The evaluation details structure SHOULD accept a generic argument (or use an equivalent language feature) which indicates the type of the wrapped value field.")
-    @Specification(number="1.4.4", text="The evaluation details structure's flag key field MUST contain the flag key argument passed to the detailed flag evaluation method.")
-    @Specification(number="1.4.5", text="In cases of normal execution, the evaluation details structure's variant field MUST contain the value of the variant field in the flag resolution structure returned by the configured provider, if the field is set.")
-    @Specification(number="1.4.6", text="In cases of normal execution, the evaluation details structure's reason field MUST contain the value of the reason field in the flag resolution structure returned by the configured provider, if the field is set.")
+    @Specification(number="1.4.1.1", text="The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns an evaluation details structure.")
+    @Specification(number="1.4.3", text="The evaluation details structure's value field MUST contain the evaluated flag value.")
+    @Specification(number="1.4.4.1", text="The evaluation details structure SHOULD accept a generic argument (or use an equivalent language feature) which indicates the type of the wrapped value field.")
+    @Specification(number="1.4.5", text="The evaluation details structure's flag key field MUST contain the flag key argument passed to the detailed flag evaluation method.")
+    @Specification(number="1.4.6", text="In cases of normal execution, the evaluation details structure's variant field MUST contain the value of the variant field in the flag resolution structure returned by the configured provider, if the field is set.")
+    @Specification(number="1.4.7", text="In cases of normal execution, the `evaluation details` structure's `reason` field MUST contain the value of the `reason` field in the `flag resolution` structure returned by the configured `provider`, if the field is set.")
     @Test void detail_flags() {
         FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider());
         Client c = api.getClient();
@@ -184,7 +185,7 @@ class FlagEvaluationSpecTest implements HookFixtures {
                 .flagKey(key)
                 .value(false)
                 .variant(null)
-                .flagMetadata(flagMetadata)
+                .flagMetadata(DEFAULT_METADATA)
                 .build();
         assertEquals(bd, c.getBooleanDetails(key, true));
         assertEquals(bd, c.getBooleanDetails(key, true, new ImmutableContext()));
@@ -194,7 +195,7 @@ class FlagEvaluationSpecTest implements HookFixtures {
                 .flagKey(key)
                 .value("tset")
                 .variant(null)
-                .flagMetadata(flagMetadata)
+                .flagMetadata(DEFAULT_METADATA)
                 .build();
         assertEquals(sd, c.getStringDetails(key, "test"));
         assertEquals(sd, c.getStringDetails(key, "test", new ImmutableContext()));
@@ -203,7 +204,7 @@ class FlagEvaluationSpecTest implements HookFixtures {
         FlagEvaluationDetails<Integer> id = FlagEvaluationDetails.<Integer>builder()
                 .flagKey(key)
                 .value(400)
-                .flagMetadata(flagMetadata)
+                .flagMetadata(DEFAULT_METADATA)
                 .build();
         assertEquals(id, c.getIntegerDetails(key, 4));
         assertEquals(id, c.getIntegerDetails(key, 4, new ImmutableContext()));
@@ -212,7 +213,7 @@ class FlagEvaluationSpecTest implements HookFixtures {
         FlagEvaluationDetails<Double> dd = FlagEvaluationDetails.<Double>builder()
                 .flagKey(key)
                 .value(40.0)
-                .flagMetadata(flagMetadata)
+                .flagMetadata(DEFAULT_METADATA)
                 .build();
         assertEquals(dd, c.getDoubleDetails(key, .4));
         assertEquals(dd, c.getDoubleDetails(key, .4, new ImmutableContext()));
@@ -234,9 +235,10 @@ class FlagEvaluationSpecTest implements HookFixtures {
         verify(invocationHook, times(1)).before(any(), any());
     }
 
-    @Specification(number="1.4.9", text="Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the default value in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.")
-    @Specification(number="1.4.7", text="In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.")
-    @Specification(number="1.4.12", text="In cases of abnormal execution, the `evaluation details` structure's `error message` field **MAY** contain a string containing additional details about the nature of the error.")
+    @Specification(number="1.4.8", text="In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.")
+    @Specification(number="1.4.9", text="In cases of abnormal execution (network failure, unhandled error, etc) the `reason` field in the `evaluation details` SHOULD indicate an error.")
+    @Specification(number="1.4.10", text="Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the `default value` in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.")
+    @Specification(number="1.4.13", text="In cases of abnormal execution, the `evaluation details` structure's `error message` field **MAY** contain a string containing additional details about the nature of the error.")
     @Test void broken_provider() {
         FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider());
         Client c = api.getClient();
@@ -246,7 +248,7 @@ class FlagEvaluationSpecTest implements HookFixtures {
         assertEquals(TestConstants.BROKEN_MESSAGE, details.getErrorMessage());
     }
 
-    @Specification(number="1.4.10", text="In the case of abnormal execution, the client SHOULD log an informative error message.")
+    @Specification(number="1.4.11", text="In the case of abnormal execution, the client SHOULD log an informative error message.")
     @Test void log_on_error() throws NotImplementedException {
         FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider());
         Client c = api.getClient();
@@ -269,7 +271,7 @@ class FlagEvaluationSpecTest implements HookFixtures {
         assertEquals("test", c2.getMetadata().getName());
     }
 
-    @Specification(number="1.4.8", text="In cases of abnormal execution (network failure, unhandled error, etc) the reason field in the evaluation details SHOULD indicate an error.")
+    @Specification(number="1.4.9", text="In cases of abnormal execution (network failure, unhandled error, etc) the reason field in the evaluation details SHOULD indicate an error.")
     @Test void reason_is_error_when_there_are_errors() {
         FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider());
         Client c = api.getClient();
@@ -277,8 +279,17 @@ class FlagEvaluationSpecTest implements HookFixtures {
         assertEquals(Reason.ERROR.toString(), result.getReason());
     }
 
-    @Specification(number="3.2.1", text="The API, Client and invocation MUST have a method for supplying evaluation context.")
-    @Specification(number="3.2.2", text="Evaluation context MUST be merged in the order: API (global; lowest precedence) - client - invocation - before hooks (highest precedence), with duplicate values being overwritten.")
+    @Specification(number="1.4.14", text="If the flag metadata field in the flag resolution structure returned by the configured provider is set, the evaluation details structure's flag metadata field MUST contain that value. Otherwise, it MUST contain an empty record.")
+    @Test void flag_metadata_passed() {
+        FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider(null));
+        Client c = api.getClient();
+        FlagEvaluationDetails<Boolean> result = c.getBooleanDetails("test", false);
+        assertNotNull(result.getFlagMetadata());
+    }
+
+    @Specification(number="3.2.1.1", text="The API, Client and invocation MUST have a method for supplying evaluation context.")
+    @Specification(number="3.2.2.1", text="The API MUST have a method for setting the global evaluation context.")
+    @Specification(number="3.2.3", text="Evaluation context MUST be merged in the order: API (global; lowest precedence) - client - invocation - before hooks (highest precedence), with duplicate values being overwritten.")
     @Test void multi_layer_context_merges_correctly() {
         DoSomethingProvider provider = new DoSomethingProvider();
         FeatureProviderTestUtils.setFeatureProvider(provider);
@@ -315,13 +326,22 @@ class FlagEvaluationSpecTest implements HookFixtures {
 
     }
 
-    @Specification(number="1.3.3", text="The client SHOULD guarantee the returned value of any typed flag evaluation method is of the expected type. If the value returned by the underlying provider implementation does not match the expected type, it's to be considered abnormal execution, and the supplied default value should be returned.")
+    @Specification(number="1.3.4", text="The client SHOULD guarantee the returned value of any typed flag evaluation method is of the expected type. If the value returned by the underlying provider implementation does not match the expected type, it's to be considered abnormal execution, and the supplied default value should be returned.")
     @Test void type_system_prevents_this() {}
 
     @Specification(number="1.1.7", text="The client creation function MUST NOT throw, or otherwise abnormally terminate.")
     @Test void constructor_does_not_throw() {}
 
-    @Specification(number="1.4.11", text="The client SHOULD provide asynchronous or non-blocking mechanisms for flag evaluation.")
+    @Specification(number="1.4.12", text="The client SHOULD provide asynchronous or non-blocking mechanisms for flag evaluation.")
     @Test void one_thread_per_request_model() {}
 
+    @Specification(number="1.4.14.1", text="Condition: Flag metadata MUST be immutable.")
+    @Test void compiler_enforced() {}
+
+    @Specification(number="1.4.2.1", text="The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), and evaluation options (optional), which returns an evaluation details structure.")
+    @Specification(number="1.3.2.1", text="The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), and evaluation options (optional), which returns the flag value.")
+    @Specification(number="3.2.2.2", text="The Client and invocation MUST NOT have a method for supplying evaluation context.")
+    @Specification(number="3.2.4.1", text="When the global evaluation context is set, the on context changed handler MUST run.")
+    @Test void not_applicable_for_dynamic_context() {}
+
 }
diff --git a/src/test/java/dev/openfeature/sdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java
index 14a2ef2..763069f 100644
--- a/src/test/java/dev/openfeature/sdk/HookContextTest.java
+++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java
@@ -23,4 +23,7 @@ class HookContextTest {
         assertTrue(Metadata.class.isAssignableFrom(hc.getProviderMetadata().getClass()));
     }
 
+    @Specification(number="4.3.3.1", text="The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters. It has no return value.")
+    @Test void not_applicable_for_dynamic_context() {}
+
 }
\ No newline at end of file
diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java
index d1daa70..def331d 100644
--- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java
+++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java
@@ -154,7 +154,7 @@ class HookSpecTest implements HookFixtures {
                 .build();
     }
 
-    @Specification(number="4.3.2", text="The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters and returns either an evaluation context or nothing.")
+    @Specification(number="4.3.2.1", text="The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters and returns either an evaluation context or nothing.")
     @Test void before_runs_ahead_of_evaluation() {
         OpenFeatureAPI api = OpenFeatureAPI.getInstance();
         api.setProvider(new AlwaysBrokenProvider());
@@ -181,11 +181,11 @@ class HookSpecTest implements HookFixtures {
         verify(h, times(0)).error(any(), any(), any());
     }
 
+    @Specification(number="4.3.6", text="The after stage MUST run after flag resolution occurs. It accepts a hook context (required), flag evaluation details (required) and hook hints (optional). It has no return value.")
+    @Specification(number="4.3.7", text="The error hook MUST run when errors are encountered in the before stage, the after stage or during flag resolution. It accepts hook context (required), exception representing what went wrong (required), and hook hints (optional). It has no return value.")
+    @Specification(number="4.3.8", text="The finally hook MUST run after the before, after, and error stages. It accepts a hook context (required) and hook hints (optional). There is no return value.")
     @Specification(number="4.4.1", text="The API, Client, Provider, and invocation MUST have a method for registering hooks.")
-    @Specification(number="4.3.5", text="The after stage MUST run after flag resolution occurs. It accepts a hook context (required), flag evaluation details (required) and hook hints (optional). It has no return value.")
     @Specification(number="4.4.2", text="Hooks MUST be evaluated in the following order:  - before: API, Client, Invocation, Provider - after: Provider, Invocation, Client, API - error (if applicable): Provider, Invocation, Client, API - finally: Provider, Invocation, Client, API")
-    @Specification(number="4.3.6", text="The error hook MUST run when errors are encountered in the before stage, the after stage or during flag resolution. It accepts hook context (required), exception representing what went wrong (required), and hook hints (optional). It has no return value.")
-    @Specification(number="4.3.7", text="The finally hook MUST run after the before, after, and error stages. It accepts a hook context (required) and hook hints (optional). There is no return value.")
     @Test void hook_eval_order() {
         List<String> evalOrder = new ArrayList<>();
         OpenFeatureAPI api = OpenFeatureAPI.getInstance();
@@ -446,7 +446,7 @@ class HookSpecTest implements HookFixtures {
     }
 
     @Specification(number = "4.1.4", text = "The evaluation context MUST be mutable only within the before hook.")
-    @Specification(number = "4.3.3", text = "Any evaluation context returned from a before hook MUST be passed to subsequent before hooks (via HookContext).")
+    @Specification(number = "4.3.4", text = "Any `evaluation context` returned from a `before` hook MUST be passed to subsequent `before` hooks (via `HookContext`).")
     @Test void beforeContextUpdated() {
         EvaluationContext ctx = new ImmutableContext();
         Hook hook = mockBooleanHook();
@@ -471,7 +471,7 @@ class HookSpecTest implements HookFixtures {
 
     }
 
-    @Specification(number="4.3.4", text="When before hooks have finished executing, any resulting evaluation context MUST be merged with the existing evaluation context.")
+    @Specification(number="4.3.5", text="When before hooks have finished executing, any resulting evaluation context MUST be merged with the existing evaluation context.")
     @Test void mergeHappensCorrectly() {
         Map<String, Value>  attributes= new HashMap<>();
         attributes.put("test", new Value("works"));
@@ -561,7 +561,7 @@ class HookSpecTest implements HookFixtures {
     @Specification(number="4.3.1", text="Hooks MUST specify at least one stage.")
     @Test void default_methods_so_impossible() {}
 
-    @Specification(number="4.3.8.1", text="Instead of finally, finallyAfter SHOULD be used.")
+    @Specification(number="4.3.9.1", text="Instead of finally, finallyAfter SHOULD be used.")
     @SneakyThrows
     @Test void doesnt_use_finally() {
         assertThatCode(() -> Hook.class.getMethod("finally", HookContext.class, Map.class))
diff --git a/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java
index 0ab5e37..270ac77 100644
--- a/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java
+++ b/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java
@@ -30,7 +30,7 @@ class InitializeBehaviorSpecTest {
             verify(featureProvider, timeout(1000)).initialize(any());
         }
 
-        @Specification(number = "1.4.9", text = "Methods, functions, or operations on the client MUST NOT throw "
+        @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw "
             + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the "
             + "`default value` in the event of abnormal execution. Exceptions include functions or methods for "
             + "the purposes for configuration or setup.")
@@ -65,7 +65,7 @@ class InitializeBehaviorSpecTest {
             verify(featureProvider, timeout(1000)).initialize(any());
         }
 
-        @Specification(number = "1.4.9", text = "Methods, functions, or operations on the client MUST NOT throw "
+        @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw "
             + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the "
             + "`default value` in the event of abnormal execution. Exceptions include functions or methods for "
             + "the purposes for configuration or setup.")
diff --git a/src/test/java/dev/openfeature/sdk/LockingTest.java b/src/test/java/dev/openfeature/sdk/LockingTest.java
index d9601e8..f58795a 100644
--- a/src/test/java/dev/openfeature/sdk/LockingTest.java
+++ b/src/test/java/dev/openfeature/sdk/LockingTest.java
@@ -12,9 +12,11 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Isolated;
 
 import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock;
 
+@Isolated()
 class LockingTest {
     
     private static OpenFeatureAPI api;
@@ -26,11 +28,12 @@ class LockingTest {
     @BeforeAll
     static void beforeAll() {
         api = OpenFeatureAPI.getInstance();
+        OpenFeatureAPI.getInstance().setProvider("LockingTest", new NoOpProvider());
     }
 
     @BeforeEach
     void beforeEach() {
-        client = (OpenFeatureClient) api.getClient();
+        client = (OpenFeatureClient) api.getClient("LockingTest");
         
         apiLock = setupLock(apiLock, mockInnerReadLock(), mockInnerWriteLock());
         OpenFeatureAPI.lock = apiLock;
diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java
index a49bf64..10b38e6 100644
--- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java
+++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java
@@ -27,6 +27,19 @@ class OpenFeatureAPITest {
                 .isEqualTo(api.getProviderMetadata("namedProviderTest").getName());
     }
 
+    @Specification(number="1.1.3", text="The API MUST provide a function to bind a given provider to one or more client names. If the client-name already has a bound provider, it is overwritten with the new mapping.")
+    @Test
+    void namedProviderOverwrittenTest() {
+        String name = "namedProviderOverwrittenTest";
+        FeatureProvider provider1 = new NoOpProvider();
+        FeatureProvider provider2 = new DoSomethingProvider();
+        FeatureProviderTestUtils.setFeatureProvider(name, provider1);
+        FeatureProviderTestUtils.setFeatureProvider(name, provider2);
+
+        assertThat(OpenFeatureAPI.getInstance().getProvider(name).getMetadata().getName())
+                .isEqualTo(DoSomethingProvider.name);
+    }
+
     @Test
     void settingDefaultProviderToNullErrors() {
         assertThatCode(() -> api.setProvider(null)).isInstanceOf(IllegalArgumentException.class);
diff --git a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java
index f5e5e6a..a87cc51 100644
--- a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java
+++ b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java
@@ -3,6 +3,7 @@ package dev.openfeature.sdk;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.junit.jupiter.api.Test;
 
@@ -39,7 +40,7 @@ public class ProviderSpecTest {
 
     }
 
-    @Specification(number = "2.2.5", text = "The `provider` SHOULD populate the `resolution details` structure's `reason` field with `\"STATIC\"`, `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"CACHED\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"ERROR\"` or some other string indicating the semantic reason for the returned flag value.")
+    @Specification(number = "2.2.5", text = "The `provider` SHOULD populate the `resolution details` structure's `reason` field with `\"STATIC\"`, `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"CACHED\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"STALE\"`, `\"ERROR\"` or some other string indicating the semantic reason for the returned flag value.")
     @Test
     void has_reason() {
         ProviderEvaluation<Boolean> result = p.getBooleanEvaluation("key", false, new ImmutableContext());
@@ -76,10 +77,50 @@ public class ProviderSpecTest {
         assertNotNull(boolean_result.getReason());
     }
 
+    @Specification(number = "2.2.10", text = "`flag metadata` MUST be a structure supporting the definition of arbitrary properties, with keys of type `string`, and values of type `boolean | string | number`.")
+    @Test
+    void flag_metadata_structure() {
+        ImmutableMetadata metadata = ImmutableMetadata.builder()
+                .addBoolean("bool", true)
+                .addDouble("double", 1.1d)
+                .addFloat("float", 2.2f)
+                .addInteger("int", 3)
+                .addLong("long", 1l)
+                .addString("string", "str")
+                .build();
+
+        assertEquals(true, metadata.getBoolean("bool"));
+        assertEquals(1.1d, metadata.getDouble("double"));
+        assertEquals(2.2f, metadata.getFloat("float"));
+        assertEquals(3, metadata.getInteger("int"));
+        assertEquals(1l, metadata.getLong("long"));
+        assertEquals("str", metadata.getString("string"));
+    }
+
     @Specification(number = "2.3.1", text = "The provider interface MUST define a provider hook mechanism which can be optionally implemented in order to add hook instances to the evaluation life-cycle.")
     @Specification(number = "4.4.1", text = "The API, Client, Provider, and invocation MUST have a method for registering hooks.")
     @Test
     void provider_hooks() {
         assertEquals(0, p.getProviderHooks().size());
     }
+
+    @Specification(number = "2.4.2", text = "The provider MAY define a status field/accessor which indicates the readiness of the provider, with possible values NOT_READY, READY, or ERROR.")
+    @Test
+    void defines_status() {
+        assertTrue(p.getState() instanceof ProviderState);
+    }
+
+    @Specification(number = "2.4.3", text = "The provider MUST set its status field/accessor to READY if its initialize function terminates normally.")
+    @Specification(number = "2.4.4", text = "The provider MUST set its status field to ERROR if its initialize function terminates abnormally.")
+    @Specification(number = "2.2.9", text = "The provider SHOULD populate the resolution details structure's flag metadata field.")
+    @Specification(number = "2.4.1", text = "The provider MAY define an initialize function which accepts the global evaluation context as an argument and performs initialization logic relevant to the provider.")
+    @Specification(number = "2.5.1", text = "The provider MAY define a mechanism to gracefully shutdown and dispose of resources.")
+    @Test
+    void provider_responsibility() {
+    }
+
+    @Specification(number = "2.6.1", text = "The provider MAY define an on context changed handler, which takes an argument for the previous context and the newly set context, in order to respond to an evaluation context change.")
+    @Test
+    void not_applicable_for_dynamic_context() {
+    }
 }
diff --git a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java
index 8659ce7..b0a0a9d 100644
--- a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java
+++ b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java
@@ -35,7 +35,7 @@ class ShutdownBehaviorSpecTest {
             verify(featureProvider, timeout(1000)).shutdown();
         }
 
-        @Specification(number = "1.4.9", text = "Methods, functions, or operations on the client MUST NOT throw "
+        @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw "
                 + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the "
                 + "`default value` in the event of abnormal execution. Exceptions include functions or methods for "
                 + "the purposes for configuration or setup.")
@@ -68,7 +68,7 @@ class ShutdownBehaviorSpecTest {
             verify(featureProvider, timeout(1000)).shutdown();
         }
 
-        @Specification(number = "1.4.9", text = "Methods, functions, or operations on the client MUST NOT throw "
+        @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw "
                 + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the "
                 + "`default value` in the event of abnormal execution. Exceptions include functions or methods for "
                 + "the purposes for configuration or setup.")
diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java b/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java
index 25650bf..af23964 100644
--- a/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java
+++ b/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java
@@ -16,6 +16,13 @@ public class TestEventsProvider extends EventProvider {
     private ProviderState state = ProviderState.NOT_READY;
     private boolean shutDown = false;
     private int initTimeoutMs = 0;
+    private String name = "test";
+    private Metadata metadata = new Metadata() {
+        @Override
+        public String getName() {
+            return name;
+        }
+    };
 
     @Override
     public ProviderState getState() {
@@ -64,7 +71,7 @@ public class TestEventsProvider extends EventProvider {
 
     @Override
     public Metadata getMetadata() {
-        throw new UnsupportedOperationException("Unimplemented method 'getMetadata'");
+        return this.metadata;
     }
 
     @Override