Repository: open-feature/java-sdk
Pull request #546 (2023-08-07 15:51:41)

feat: In-memory provider for e2e testing and minimal usage

## This PR
[Issue 523](https://github.com/open-feature/java-sdk/issues/523) - In-memory provider for e2e testing and minimal SDK usage

Kavindu-Dodan: Overall great work. I would love to get this to mergeable status. Please check comments from my initial review and let me know if you have any concerns 
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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&metric=new_duplicated_lines_density&view=list)


Kavindu-Dodan: Some observations and suggestions for improvement 

In the current implementation, flag configurations are loaded from a string. I think this is not ideal for general usage and diverge from the specification [^1]

> Provider must be initiated with a pre-defined set of flags provided to a constructor

I am suggesting changing the constructor to accept a known map of flags. The end user may use any mechanism to parse their flags and initialize the provider. 

Further, this should allow us to simplify `Flags` class and make it a simple pojo (no builders and parsing)

[^1]: https://github.com/open-feature/spec/blob/main/specification/appendix-A.md#sdk-end-to-end-testing 
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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&metric=new_duplicated_lines_density&view=list)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) Report
> Merging [#546](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) (f85cbb5) into [main](https://app.codecov.io/gh/open-feature/java-sdk/commit/4d049965716cef005f96146eaa909e50fc2fe73e?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) (4d04996) will **decrease** coverage by `1.22%`.
> Report is 5 commits behind head on main.
> The diff coverage is `85.00%`.

```diff
@@             Coverage Diff              @@
##               main     #546      +/-   ##
============================================
- Coverage     95.36%   94.15%   -1.22%     
- Complexity      330      357      +27     
============================================
  Files            31       33       +2     
  Lines           755      855     +100     
  Branches         37       50      +13     
============================================
+ Hits            720      805      +85     
- Misses           18       29      +11     
- Partials         17       21       +4     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `94.15% <85.00%> (-1.22%)` | :arrow_down: |

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 Changed](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature) | Coverage Δ | |
|---|---|---|
| [...ain/java/dev/openfeature/sdk/MutableStructure.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL011dGFibGVTdHJ1Y3R1cmUuamF2YQ==) | `94.11% <75.00%> (-2.55%)` | :arrow_down: |
| [src/main/java/dev/openfeature/sdk/Value.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL1ZhbHVlLmphdmE=) | `90.09% <82.60%> (-1.96%)` | :arrow_down: |
| [...feature/sdk/providers/memory/InMemoryProvider.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL3Byb3ZpZGVycy9tZW1vcnkvSW5NZW1vcnlQcm92aWRlci5qYXZh) | `85.71% <85.71%> (ø)` | |
| [...ava/dev/openfeature/sdk/FlagEvaluationDetails.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?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%> (ø)` | |
| [...ava/dev/openfeature/sdk/providers/memory/Flag.java](https://app.codecov.io/gh/open-feature/java-sdk/pull/546?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=open-feature#diff-c3JjL21haW4vamF2YS9kZXYvb3BlbmZlYXR1cmUvc2RrL3Byb3ZpZGVycy9tZW1vcnkvRmxhZy5qYXZh) | `100.00% <100.00%> (ø)` | |

: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)

toddbaert: I'll take a look at this early next week! Thanks @liran2000 
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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [4 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [4 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [4 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&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=546)

[![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=546&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=546&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-feature_java-sdk&pullRequest=546&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=546&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=546&resolved=false&types=CODE_SMELL) [3 Code Smells](https://sonarcloud.io/project/issues?id=open-feature_java-sdk&pullRequest=546&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=546) 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=546&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=open-feature_java-sdk&pullRequest=546&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
index 1ebcb4b..364ef65 100644
--- a/.github/workflows/pullrequest.yml
+++ b/.github/workflows/pullrequest.yml
@@ -8,13 +8,6 @@ permissions:
 jobs:
   build:
     runs-on: ubuntu-latest
-    # TODO: this can be removed with https://github.com/open-feature/java-sdk/issues/523
-    services:
-      flagd:
-        image: ghcr.io/open-feature/flagd-testbed:latest
-        ports:
-          - 8013:8013
-
     steps:
       - name: Check out the code
         uses: actions/checkout@96f53100ba2a5449eb71d2e6604bbcd94b9449b5
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 63c9d53..7c0b038 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -18,14 +18,9 @@ If you're adding tests to cover something in the spec, use the `@Specification`
 
 ## End-to-End Tests
 
-<!-- TODO: this section should be updated with https://github.com/open-feature/java-sdk/issues/523 -->
+The continuous integration runs a set of [gherkin e2e tests](https://github.com/open-feature/test-harness/blob/main/features/evaluation.feature) using `InMemoryProvider`.
 
-The continuous integration runs a set of [gherkin e2e tests](https://github.com/open-feature/test-harness/blob/main/features/evaluation.feature) using [`flagd`](https://github.com/open-feature/flagd). These tests do not run with the default maven profile. If you'd like to run them locally, you can start the flagd testbed with
-
-```
-docker run -p 8013:8013 ghcr.io/open-feature/flagd-testbed:latest
-```
-and then run 
+to run alone:
 ```
 mvn test -P e2e-test
 ```
diff --git a/pom.xml b/pom.xml
index 098d6eb..09c52f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,8 +11,6 @@
     <maven.compiler.source>1.8</maven.compiler.source>
     <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
     <junit.jupiter.version>5.10.0</junit.jupiter.version>
-    <!-- exclusion expression for e2e tests -->
-    <testExclusions>**/e2e/*.java</testExclusions>
     <module-name>${groupId}.${artifactId}</module-name>
   </properties>
 
@@ -21,10 +19,10 @@
   <url>https://openfeature.dev</url>
   <developers>
     <developer>
-       <id>abrahms</id>
-       <name>Justin Abrahms</name>
-       <organization>eBay</organization>
-       <url>https://justin.abrah.ms/</url>
+      <id>abrahms</id>
+      <name>Justin Abrahms</name>
+      <organization>eBay</organization>
+      <url>https://justin.abrah.ms/</url>
     </developer>
   </developers>
   <licenses>
@@ -120,9 +118,9 @@
     </dependency>
 
     <dependency>
-        <groupId>io.cucumber</groupId>
-        <artifactId>cucumber-junit-platform-engine</artifactId>
-        <scope>test</scope>
+      <groupId>io.cucumber</groupId>
+      <artifactId>cucumber-junit-platform-engine</artifactId>
+      <scope>test</scope>
     </dependency>
 
     <dependency>
@@ -139,39 +137,33 @@
       <scope>test</scope>
     </dependency>
 
-    <dependency>
-      <groupId>dev.openfeature.contrib.providers</groupId>
-      <artifactId>flagd</artifactId>
-      <version>0.5.10</version>
-      <scope>test</scope>
-    </dependency>
-
     <dependency>
       <groupId>org.awaitility</groupId>
       <artifactId>awaitility</artifactId>
       <version>4.2.0</version>
       <scope>test</scope>
     </dependency>
+
   </dependencies>
 
   <dependencyManagement>
     <dependencies>
 
-        <dependency>
-            <groupId>io.cucumber</groupId>
-            <artifactId>cucumber-bom</artifactId>
-            <version>7.13.0</version>
-            <type>pom</type>
-            <scope>import</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.junit</groupId>
-            <artifactId>junit-bom</artifactId>
-            <version>5.10.0</version>
-            <type>pom</type>
-            <scope>import</scope>
-        </dependency>
+      <dependency>
+        <groupId>io.cucumber</groupId>
+        <artifactId>cucumber-bom</artifactId>
+        <version>7.13.0</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+
+      <dependency>
+        <groupId>org.junit</groupId>
+        <artifactId>junit-bom</artifactId>
+        <version>5.10.0</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
 
     </dependencies>
   </dependencyManagement>
@@ -203,7 +195,7 @@
           </execution>
         </executions>
       </plugin>
-     
+
       <plugin>
         <artifactId>maven-dependency-plugin</artifactId>
         <version>3.6.0</version>
@@ -249,7 +241,7 @@
           <excludes>
             <!-- tests to exclude -->
             <exclude>${testExclusions}</exclude>
-         </excludes>
+          </excludes>
         </configuration>
       </plugin>
 
@@ -271,7 +263,7 @@
 
         <executions>
           <execution>
-      	    <id>prepare-agent</id>
+            <id>prepare-agent</id>
             <goals>
               <goal>prepare-agent</goal>
             </goals>
@@ -319,7 +311,7 @@
                 </rule>
               </rules>
             </configuration>
- 	        </execution>
+          </execution>
 
         </executions>
       </plugin>
@@ -496,14 +488,11 @@
     </profile>
 
     <profile>
-      <!-- this profile handles running the flagd e2e tests -->
-      <!-- TODO: this profile can likely be removed with TODO: this section should be updated with https://github.com/open-feature/java-sdk/issues/523 -->
-      <!-- TODO: we should pull the submodule and run these tests unconditionall once flagd isn't required -->
       <id>e2e-test</id>
       <properties>
         <!-- run the e2e tests by clearing the exclusions -->
         <testExclusions/>
-      </properties>  
+      </properties>
       <build>
         <plugins>
           <!-- pull the gherkin tests as a git submodule  -->
diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java
index 78e04c7..b324c07 100644
--- a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java
+++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java
@@ -40,6 +40,7 @@ public class FlagEvaluationDetails<T> implements BaseEvaluation<T> {
                 .value(providerEval.getValue())
                 .variant(providerEval.getVariant())
                 .reason(providerEval.getReason())
+                .errorMessage(providerEval.getErrorMessage())
                 .errorCode(providerEval.getErrorCode())
                 .flagMetadata(providerEval.getFlagMetadata())
                 .build();
diff --git a/src/main/java/dev/openfeature/sdk/Structure.java b/src/main/java/dev/openfeature/sdk/Structure.java
index f8b5521..46274e7 100644
--- a/src/main/java/dev/openfeature/sdk/Structure.java
+++ b/src/main/java/dev/openfeature/sdk/Structure.java
@@ -9,6 +9,8 @@ import java.util.Map.Entry;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import static dev.openfeature.sdk.Value.objectToValue;
+
 /**
  * {@link Structure} represents a potentially nested object type which is used to represent 
  * structured data.
@@ -123,4 +125,16 @@ public interface Structure {
         }
         return merged;
     }
+
+    /**
+     * Transform an object map to a {@link Structure} type.
+     *
+     * @param map map of objects
+     * @return a Structure object in the SDK format
+     */
+    static Structure mapToStructure(Map<String, Object> map) {
+        return new MutableStructure(map.entrySet().stream()
+            .filter(e -> e.getValue() != null)
+            .collect(Collectors.toMap(Map.Entry::getKey, e -> objectToValue(e.getValue()))));
+    }
 }
diff --git a/src/main/java/dev/openfeature/sdk/Value.java b/src/main/java/dev/openfeature/sdk/Value.java
index 672b65c..8be5017 100644
--- a/src/main/java/dev/openfeature/sdk/Value.java
+++ b/src/main/java/dev/openfeature/sdk/Value.java
@@ -5,10 +5,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import dev.openfeature.sdk.exceptions.TypeMismatchError;
 import lombok.EqualsAndHashCode;
 import lombok.SneakyThrows;
 import lombok.ToString;
 
+import static dev.openfeature.sdk.Structure.mapToStructure;
+
 /**
  * Values serve as a generic return type for structure data from providers.
  * Providers may deal in JSON, protobuf, XML or some other data-interchange format.
@@ -280,4 +283,38 @@ public class Value implements Cloneable {
         }
         return new Value(this.asObject());
     }
+
+    /**
+     * Wrap an object into a Value.
+     *
+     * @param object the object to wrap
+     * @return the wrapped object
+     */
+    public static Value objectToValue(Object object) {
+        if (object instanceof Value) {
+            return (Value) object;
+        } else if (object == null) {
+            return null;
+        } else if (object instanceof String) {
+            return new Value((String) object);
+        } else if (object instanceof Boolean) {
+            return new Value((Boolean) object);
+        } else if (object instanceof Integer) {
+            return new Value((Integer) object);
+        } else if (object instanceof Double) {
+            return new Value((Double) object);
+        } else if (object instanceof Structure) {
+            return new Value((Structure) object);
+        } else if (object instanceof List) {
+            return new Value(((List<Object>) object).stream()
+                .map(o -> objectToValue(o))
+                .collect(Collectors.toList()));
+        } else if (object instanceof Instant) {
+            return new Value((Instant) object);
+        } else if (object instanceof Map) {
+            return new Value(mapToStructure((Map<String, Object>) object));
+        } else {
+            throw new TypeMismatchError("Flag value " + object + " had unexpected type " + object.getClass() + ".");
+        }
+    }
 }
diff --git a/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java b/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java
new file mode 100644
index 0000000..02fa323
--- /dev/null
+++ b/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java
@@ -0,0 +1,12 @@
+package dev.openfeature.sdk.providers.memory;
+
+import dev.openfeature.sdk.EvaluationContext;
+
+/**
+ * Context evaluator - use for resolving flag according to evaluation context, for handling targeting.
+ * @param <T> expected value type
+ */
+public interface ContextEvaluator<T> {
+
+    T evaluate(Flag flag, EvaluationContext evaluationContext);
+}
diff --git a/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java b/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java
new file mode 100644
index 0000000..8cfe85c
--- /dev/null
+++ b/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java
@@ -0,0 +1,21 @@
+package dev.openfeature.sdk.providers.memory;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Singular;
+import lombok.ToString;
+
+import java.util.Map;
+
+/**
+ * Flag representation for the in-memory provider.
+ */
+@ToString
+@Builder
+@Getter
+public class Flag<T> {
+    @Singular
+    private Map<String, Object> variants;
+    private String defaultVariant;
+    private ContextEvaluator<T> contextEvaluator;
+}
diff --git a/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java b/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java
new file mode 100644
index 0000000..1006d88
--- /dev/null
+++ b/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java
@@ -0,0 +1,162 @@
+package dev.openfeature.sdk.providers.memory;
+
+import dev.openfeature.sdk.Value;
+import dev.openfeature.sdk.Metadata;
+import dev.openfeature.sdk.EventProvider;
+import dev.openfeature.sdk.ProviderState;
+import dev.openfeature.sdk.ProviderEventDetails;
+import dev.openfeature.sdk.ErrorCode;
+import dev.openfeature.sdk.EvaluationContext;
+import dev.openfeature.sdk.ProviderEvaluation;
+import dev.openfeature.sdk.Reason;
+import dev.openfeature.sdk.exceptions.OpenFeatureError;
+import lombok.Getter;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.ArrayList;
+
+/**
+ * In-memory provider.
+ */
+@Slf4j
+public class InMemoryProvider extends EventProvider {
+
+    @Getter
+    private static final String NAME = "InMemoryProvider";
+
+    private Map<String, Flag<?>> flags;
+
+    @Getter
+    private ProviderState state = ProviderState.NOT_READY;
+
+    @Override
+    public Metadata getMetadata() {
+        return () -> NAME;
+    }
+
+    public InMemoryProvider(Map<String, Flag<?>> flags) {
+        this.flags = new HashMap<>(flags);
+    }
+
+    /**
+     * Initialize the provider.
+     * @param evaluationContext evaluation context
+     * @throws Exception on error
+     */
+    public void initialize(EvaluationContext evaluationContext) throws Exception {
+        super.initialize(evaluationContext);
+        state = ProviderState.READY;
+        log.debug("finished initializing provider, state: {}", state);
+    }
+
+    /**
+     * Updating provider flags configuration, replacing existing flags.
+     * @param flags the flags to use instead of the previous flags.
+     */
+    public void updateFlags(Map<String, Flag<?>> flags) {
+        Set<String> flagsChanged = new HashSet<>();
+        flagsChanged.addAll(this.flags.keySet());
+        flagsChanged.addAll(flags.keySet());
+        this.flags = new HashMap<>(flags);
+        ProviderEventDetails details = ProviderEventDetails.builder()
+            .flagsChanged(new ArrayList<>(flagsChanged))
+            .message("flags changed")
+            .build();
+        emitProviderConfigurationChanged(details);
+    }
+
+    /**
+     * Updating provider flags configuration with adding or updating a flag.
+     * @param flag the flag to update. If a flag with this key already exists, new flag replaces it.
+     */
+    public void updateFlag(String flagKey, Flag<?> flag) {
+        this.flags.put(flagKey, flag);
+        ProviderEventDetails details = ProviderEventDetails.builder()
+            .flagsChanged(Arrays.asList(flagKey))
+            .message("flag added/updated")
+            .build();
+        emitProviderConfigurationChanged(details);
+    }
+
+    @Override
+    public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue,
+            EvaluationContext evaluationContext) {
+        return getEvaluation(key, defaultValue, evaluationContext, Boolean.class);
+    }
+
+    @Override
+    public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue,
+            EvaluationContext evaluationContext) {
+        return getEvaluation(key, defaultValue, evaluationContext, String.class);
+    }
+
+    @Override
+    public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue,
+            EvaluationContext evaluationContext) {
+        return getEvaluation(key, defaultValue, evaluationContext, Integer.class);
+    }
+
+    @Override
+    public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue,
+            EvaluationContext evaluationContext) {
+        return getEvaluation(key, defaultValue, evaluationContext, Double.class);
+    }
+
+    @SneakyThrows
+    @Override
+    public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue,
+            EvaluationContext evaluationContext) {
+        return getEvaluation(key, defaultValue, evaluationContext, Value.class);
+    }
+
+    private <T> ProviderEvaluation<T> getEvaluation(
+            String key, T defaultValue, EvaluationContext evaluationContext, Class<?> expectedType
+    ) throws OpenFeatureError {
+        if (!ProviderState.READY.equals(state)) {
+            ErrorCode errorCode = ErrorCode.PROVIDER_NOT_READY;
+            if (ProviderState.ERROR.equals(state)) {
+                errorCode = ErrorCode.GENERAL;
+            }
+            return ProviderEvaluation.<T>builder()
+                .errorCode(errorCode)
+                .reason(errorCode.name())
+                .value(defaultValue)
+                .build();
+        }
+        Flag<?> flag = flags.get(key);
+        if (flag == null) {
+            return ProviderEvaluation.<T>builder()
+                .value(defaultValue)
+                .reason(Reason.ERROR.toString())
+                .errorMessage(ErrorCode.FLAG_NOT_FOUND.name())
+                .errorCode(ErrorCode.FLAG_NOT_FOUND)
+                .build();
+        }
+        T value;
+        if (flag.getContextEvaluator() != null) {
+            value = (T) flag.getContextEvaluator().evaluate(flag, evaluationContext);
+        } else if (!expectedType.isInstance(flag.getVariants().get(flag.getDefaultVariant()))) {
+            return ProviderEvaluation.<T>builder()
+                .value(defaultValue)
+                .variant(flag.getDefaultVariant())
+                .reason(Reason.ERROR.toString())
+                .errorMessage(ErrorCode.TYPE_MISMATCH.name())
+                .errorCode(ErrorCode.TYPE_MISMATCH)
+                .build();
+        } else {
+            value = (T) flag.getVariants().get(flag.getDefaultVariant());
+        }
+        return ProviderEvaluation.<T>builder()
+            .value(value)
+            .variant(flag.getDefaultVariant())
+            .reason(Reason.STATIC.toString())
+            .build();
+    }
+
+}


Test patch:
diff --git a/src/test/java/dev/openfeature/sdk/StructureTest.java b/src/test/java/dev/openfeature/sdk/StructureTest.java
index f05f930..8f18891 100644
--- a/src/test/java/dev/openfeature/sdk/StructureTest.java
+++ b/src/test/java/dev/openfeature/sdk/StructureTest.java
@@ -1,16 +1,20 @@
 package dev.openfeature.sdk;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotSame;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import lombok.SneakyThrows;
+import org.junit.jupiter.api.Test;
 
 import java.time.Instant;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.junit.jupiter.api.Test;
+import static dev.openfeature.sdk.Structure.mapToStructure;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class StructureTest {
     @Test public void noArgShouldContainEmptyAttributes() {
@@ -46,7 +50,7 @@ public class StructureTest {
         double DOUBLE_VAL = .5;
         Instant DATE_VAL = Instant.now();
         MutableStructure STRUCT_VAL = new MutableStructure();
-        List<Value> LIST_VAL = new ArrayList<Value>();
+        List<Value> LIST_VAL = new ArrayList<>();
         Value VALUE_VAL = new Value();
 
         MutableStructure structure = new MutableStructure();
@@ -68,4 +72,32 @@ public class StructureTest {
         assertEquals(LIST_VAL, structure.getValue(LIST_KEY).asList());
         assertTrue(structure.getValue(VALUE_KEY).isNull());
     }
+
+    @SneakyThrows
+    @Test
+    void mapToStructureTest() {
+        Map<String, Object> map = new HashMap<>();
+        map.put("String", "str");
+        map.put("Boolean", true);
+        map.put("Integer", 1);
+        map.put("Double", 1.1);
+        map.put("List", Collections.singletonList(new Value(1)));
+        map.put("Value", new Value((true)));
+        map.put("Instant", Instant.ofEpochSecond(0));
+        map.put("Map", new HashMap<>());
+        map.put("nullKey", null);
+        ImmutableContext immutableContext = new ImmutableContext();
+        map.put("ImmutableContext", immutableContext);
+        Structure res = mapToStructure(map);
+        assertEquals(new Value("str"), res.getValue("String"));
+        assertEquals(new Value(true), res.getValue("Boolean"));
+        assertEquals(new Value(1), res.getValue("Integer"));
+        assertEquals(new Value(1.1), res.getValue("Double"));
+        assertEquals(new Value(Collections.singletonList(new Value(1))), res.getValue("List"));
+        assertEquals(new Value(true), res.getValue("Value"));
+        assertEquals(new Value(Instant.ofEpochSecond(0)), res.getValue("Instant"));
+        assertEquals(new HashMap<>(), res.getValue("Map").asStructure().asMap());
+        assertEquals(new Value(immutableContext), res.getValue("ImmutableContext"));
+        assertNull(res.getValue("nullKey"));
+    }
 }
diff --git a/src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java
index 7048fc0..650fa24 100644
--- a/src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java
+++ b/src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java
@@ -1,22 +1,25 @@
 package dev.openfeature.sdk.e2e;
 
-import dev.openfeature.contrib.providers.flagd.FlagdProvider;
-import dev.openfeature.sdk.Client;
+import dev.openfeature.sdk.Value;
 import dev.openfeature.sdk.EvaluationContext;
-import dev.openfeature.sdk.FlagEvaluationDetails;
-import dev.openfeature.sdk.ImmutableContext;
-import dev.openfeature.sdk.OpenFeatureAPI;
 import dev.openfeature.sdk.Reason;
+import dev.openfeature.sdk.Client;
+import dev.openfeature.sdk.OpenFeatureAPI;
 import dev.openfeature.sdk.Structure;
-import dev.openfeature.sdk.Value;
+import dev.openfeature.sdk.ImmutableContext;
+import dev.openfeature.sdk.FlagEvaluationDetails;
+import dev.openfeature.sdk.providers.memory.Flag;
+import dev.openfeature.sdk.providers.memory.InMemoryProvider;
 import io.cucumber.java.BeforeAll;
 import io.cucumber.java.en.Given;
 import io.cucumber.java.en.Then;
 import io.cucumber.java.en.When;
+import lombok.SneakyThrows;
 
 import java.util.HashMap;
 import java.util.Map;
 
+import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -47,13 +50,17 @@ public class StepDefinitions {
     private int typeErrorDefaultValue;
     private FlagEvaluationDetails<Integer> typeErrorDetails;
 
+    @SneakyThrows
     @BeforeAll()
     @Given("an openfeature client is registered with cache disabled")
     public static void setup() {
-        // TODO: when the FlagdProvider is updated to support caching, we might need to disable it here for this test to work as expected.
-        FlagdProvider provider = new FlagdProvider();
-        provider.setDeadline(3000); // set a generous deadline, to prevent timeouts in actions
+        Map<String, Flag<?>> flags = buildFlags();
+        InMemoryProvider provider = new InMemoryProvider(flags);
         OpenFeatureAPI.getInstance().setProvider(provider);
+
+        // TODO: setProvider with wait for init, pending https://github.com/open-feature/ofep/pull/80
+        Thread.sleep(500);
+
         client = OpenFeatureAPI.getInstance().getClient();
     }
 
@@ -265,7 +272,7 @@ public class StepDefinitions {
     public void the_reason_should_indicate_an_error_and_the_error_code_should_be_flag_not_found(String errorCode) {
         assertEquals(Reason.ERROR.toString(), notFoundDetails.getReason());
         assertTrue(notFoundDetails.getErrorMessage().contains(errorCode));
-        // TODO: add errorCode assertion once flagd provider is updated.
+        assertTrue(notFoundDetails.getErrorCode().name().equals(errorCode));
     }
 
     // type mismatch
@@ -286,7 +293,7 @@ public class StepDefinitions {
     public void the_reason_should_indicate_an_error_and_the_error_code_should_be_type_mismatch(String errorCode) {
         assertEquals(Reason.ERROR.toString(), typeErrorDetails.getReason());
         assertTrue(typeErrorDetails.getErrorMessage().contains(errorCode));
-        // TODO: add errorCode assertion once flagd provider is updated.
+        assertTrue(typeErrorDetails.getErrorCode().name().equals(errorCode));
     }
 
 }
diff --git a/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java b/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java
new file mode 100644
index 0000000..f05a6b7
--- /dev/null
+++ b/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java
@@ -0,0 +1,84 @@
+package dev.openfeature.sdk.providers.memory;
+
+import com.google.common.collect.ImmutableMap;
+import dev.openfeature.sdk.Client;
+import dev.openfeature.sdk.OpenFeatureAPI;
+import dev.openfeature.sdk.Value;
+import lombok.SneakyThrows;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static dev.openfeature.sdk.Structure.mapToStructure;
+import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+class InMemoryProviderTest {
+
+    private static Client client;
+
+    private static InMemoryProvider provider;
+
+    @SneakyThrows
+    @BeforeAll
+    static void beforeAll() {
+        Map<String, Flag<?>> flags = buildFlags();
+        provider = spy(new InMemoryProvider(flags));
+        OpenFeatureAPI.getInstance().onProviderConfigurationChanged(eventDetails -> {});
+        OpenFeatureAPI.getInstance().setProvider(provider);
+
+        // TODO: setProvider with wait for init, pending https://github.com/open-feature/ofep/pull/80
+        Thread.sleep(500);
+
+        client = OpenFeatureAPI.getInstance().getClient();
+        provider.updateFlags(flags);
+        provider.updateFlag("addedFlag", Flag.builder()
+            .variant("on", true)
+            .variant("off", false)
+            .defaultVariant("on")
+            .build());
+    }
+
+    @SneakyThrows
+    @Test
+    void eventsTest() {
+        verify(provider, times(2)).emitProviderConfigurationChanged(any());
+    }
+
+    @Test
+    void getBooleanEvaluation() {
+        assertTrue(client.getBooleanValue("boolean-flag", false));
+    }
+
+    @Test
+    void getStringEvaluation() {
+        assertEquals("hi", client.getStringValue("string-flag", "dummy"));
+    }
+
+    @Test
+    void getIntegerEvaluation() {
+        assertEquals(10, client.getIntegerValue("integer-flag", 999));
+    }
+
+    @Test
+    void getDoubleEvaluation() {
+        assertEquals(0.5, client.getDoubleValue("float-flag", 9.99));
+    }
+
+    @Test
+    void getObjectEvaluation() {
+        Value expectedObject = new Value(mapToStructure(ImmutableMap.of(
+            "showImages", new Value(true),
+            "title", new Value("Check out these pics!"),
+            "imagesPerPage", new Value(100)
+        )));
+        assertEquals(expectedObject, client.getObjectValue("object-flag", new Value(true)));
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java
new file mode 100644
index 0000000..d903592
--- /dev/null
+++ b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java
@@ -0,0 +1,73 @@
+package dev.openfeature.sdk.testutils;
+
+import com.google.common.collect.ImmutableMap;
+import dev.openfeature.sdk.Value;
+import dev.openfeature.sdk.providers.memory.Flag;
+import lombok.experimental.UtilityClass;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static dev.openfeature.sdk.Structure.mapToStructure;
+
+/**
+ * Test flags utils.
+ */
+@UtilityClass
+public class TestFlagsUtils {
+
+    /**
+     * Building flags for testing purposes.
+     * @return map of flags
+     */
+    public static Map<String, Flag<?>> buildFlags() {
+        Map<String, Flag<?>> flags = new HashMap<>();
+        flags.put("boolean-flag", Flag.builder()
+            .variant("on", true)
+            .variant("off", false)
+            .defaultVariant("on")
+            .build());
+        flags.put("string-flag", Flag.builder()
+            .variant("greeting", "hi")
+            .variant("parting", "bye")
+            .defaultVariant("greeting")
+            .build());
+        flags.put("integer-flag", Flag.builder()
+            .variant("one", 1)
+            .variant("ten", 10)
+            .defaultVariant("ten")
+            .build());
+        flags.put("float-flag", Flag.builder()
+            .variant("tenth", 0.1)
+            .variant("half", 0.5)
+            .defaultVariant("half")
+            .build());
+        flags.put("object-flag", Flag.builder()
+            .variant("empty", new HashMap<>())
+            .variant("template", new Value(mapToStructure(ImmutableMap.of(
+                "showImages", new Value(true),
+                "title", new Value("Check out these pics!"),
+                "imagesPerPage", new Value(100)
+            ))))
+            .defaultVariant("template")
+            .build());
+        flags.put("context-aware", Flag.<String>builder()
+            .variant("internal", "INTERNAL")
+            .variant("external", "EXTERNAL")
+            .defaultVariant("external")
+            .contextEvaluator((flag, evaluationContext) -> {
+                if (new Value(false).equals(evaluationContext.getValue("customer"))) {
+                    return (String) flag.getVariants().get("internal");
+                } else {
+                    return (String) flag.getVariants().get(flag.getDefaultVariant());
+                }
+            })
+            .build());
+        flags.put("wrong-flag", Flag.builder()
+            .variant("one", "uno")
+            .variant("two", "dos")
+            .defaultVariant("one")
+            .build());
+        return flags;
+    }
+}