diff --git a/docs/src/pages/guides/FHIRServerUsersGuide.md b/docs/src/pages/guides/FHIRServerUsersGuide.md
index 3608764c230..8d626e12089 100644
--- a/docs/src/pages/guides/FHIRServerUsersGuide.md
+++ b/docs/src/pages/guides/FHIRServerUsersGuide.md
@@ -2082,6 +2082,7 @@ This section contains reference information about each of the configuration prop
 |`fhirServer/core/ifNoneMatchReturnsNotModified`|boolean|When If-None-Match is specified, overrides the standard return status "412 Precondition Failed" to be "304 Not Modified". Useful in transaction bundles for clients not wanting the bundle to fail when a conflict is found.|
 |`fhirServer/core/capabilitiesUrl`|string|The URL that is embedded in the default Capabilities statement|
 |`fhirServer/core/externalBaseUrl`|string|The base URL that is embedded in the Search bundle response, as of version 4.9.0. Note that the base URL must not include a path segment that matches any FHIR resource type name (case-sensitive). For example, "https://example.com" or "https://example.com/my/patient/api" are fine, but "https://example.com/my/Patient/api" is not.|
+|`fhirServer/core/defaultFhirVersion`|string|The implicit value to use for the MIME-type fhirVersion parameter on incoming Accept and Content-Type headers when the client has not passed an explicit value.|
 |`fhirServer/core/useImplicitTypeScopingForWholeSystemInteractions`|boolean|Whether to apply implicit resource type scoping for whole-system search and whole-system history interactions where no `_type` values were passed. Only set to false if you are certain that there are no instances of unsupported resource types in the database.|
 |`fhirServer/validation/failFast`|boolean|Indicates whether validation should fail fast on create and update interactions|
 |`fhirServer/term/capabilitiesUrl`|string|The URL that is embedded in the Terminology Capabilities statement using `mode=terminology`|
@@ -2266,6 +2267,7 @@ This section contains reference information about each of the configuration prop
 |`fhirServer/core/capabilitiesUrl`|null|
 |`fhirServer/core/externalBaseUrl`|null|
 |`fhirServer/core/ifNoneMatchReturnsNotModified`|false|
+|`fhirServer/core/defaultFhirVersion`|4.0|
 |`fhirServer/core/useImplicitTypeScopingForWholeSystemInteractions`|true|
 |`fhirServer/validation/failFast`|false|
 |`fhirServer/term/capabilitiesUrl`|null|
@@ -2419,6 +2421,7 @@ must restart the server for that change to take effect.
 |`fhirServer/core/maxPageIncludeCount`|Y|Y|
 |`fhirServer/core/capabilitiesUrl`|Y|Y|
 |`fhirServer/core/externalBaseUrl`|Y|Y|
+|`fhirServer/core/defaultFhirVersion`|Y|Y|
 |`fhirServer/core/useImplicitTypeScopingForWholeSystemInteractions`|Y|Y|
 |`fhirServer/validation/failFast`|Y|Y|
 |`fhirServer/term/cachingDisabled`|N|N|
diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java b/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java
index f64c844dafd..98f12056440 100644
--- a/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java
+++ b/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java
@@ -8,10 +8,12 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import com.ibm.fhir.config.PropertyGroup.PropertyEntry;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.exception.FHIRException;
 
 import jakarta.json.JsonValue;
@@ -23,7 +25,7 @@
  */
 public class FHIRConfigHelper {
     private static final Logger log = Logger.getLogger(FHIRConfigHelper.class.getName());
-    
+
     //Constants
     public static final String SEARCH_PROPERTY_TYPE_INCLUDE = "_include";
     public static final String SEARCH_PROPERTY_TYPE_REVINCLUDE = "_revinclude";
@@ -84,7 +86,7 @@ private static JsonValue getPropertyFromTenantOrDefault(String propertyName) {
         if (result == null && !FHIRConfiguration.DEFAULT_TENANT_ID.equals(tenantId)) {
             try {
                 if (propertyName.startsWith(FHIRConfiguration.PROPERTY_DATASOURCES)) {
-                    // Issue #639. Prevent datasource lookups from falling back to 
+                    // Issue #639. Prevent datasource lookups from falling back to
                     // the default datasource which breaks tenant isolation.
                     result = null;
                 } else {
@@ -160,43 +162,29 @@ private static <T> T getTypedProperty(Class<T> expectedDataType, String property
         }
 
         return (result != null ? result : defaultValue);
-    }    
-    
+    }
+
     /**
-     * This method returns the list of supported resource types
-     * @return a list of resource types that isn't null
+     * @return a non-null list of supported resource types for fhirVersion 4.3
      */
     public static List<String> getSupportedResourceTypes() throws FHIRException {
-        List<String> result = new ArrayList<>();
+        return new ArrayList<>(getSupportedResourceTypes(FHIRVersionParam.VERSION_43));
+    }
 
-        PropertyGroup rsrcsGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
-        List<PropertyEntry> rsrcsEntries;
+    /**
+     * @return a non-null list of supported resource types for the given fhirVersion
+     */
+    public static Set<String> getSupportedResourceTypes(FHIRVersionParam fhirVersion) throws FHIRException {
+        PropertyGroup resourcesGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
         try {
-            rsrcsEntries = rsrcsGroup.getProperties();
-
-            if (rsrcsEntries != null && !rsrcsEntries.isEmpty()) {
-                for (PropertyEntry rsrcsEntry : rsrcsEntries) {
-                    String name = rsrcsEntry.getName();
-                    
-                    // Ensure we skip over the special property "open" and process only the others
-                    // and skip the abstract types Resource and DomainResource
-                    // It would be nice to be able to verify if the resource names were valid, but
-                    // not possible at this layer of the code.  
-                    if (!FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN.equals(name) &&
-                        !"Resource".equals(name) &&
-                        !"DomainResource".equals(name)) {
-                            result.add(name);
-                    }
-                }
-            }
+            ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(resourcesGroup, fhirVersion);
+            return configAdapter.getSupportedResourceTypes();
         } catch (Exception e) {
-            log.fine("FHIRConfigHelper.getSupportedResourceTypes is configured with no "
-                    + "resources in the server config file or is not configured properly");
+            log.log(Level.SEVERE, "Unexpected exception while constructing a ResourcesConfigAdapter for fhirServer/resources", e);
+            throw new FHIRException(e);
         }
-        
-        return result;
     }
-    
+
     /**
      * Retrieves the search property restrictions.
      *
diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfiguration.java b/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfiguration.java
index 565ae76c584..fbe72d208a3 100644
--- a/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfiguration.java
+++ b/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfiguration.java
@@ -43,6 +43,7 @@ public class FHIRConfiguration {
     public static final String PROPERTY_MAX_PAGE_SIZE = "fhirServer/core/maxPageSize";
     public static final String PROPERTY_MAX_PAGE_INCLUDE_COUNT = "fhirServer/core/maxPageIncludeCount";
     public static final String PROPERTY_CAPABILITIES_URL = "fhirServer/core/capabilitiesUrl";
+    public static final String PROPERTY_DEFAULT_FHIR_VERSION = "fhirServer/core/defaultFhirVersion";
     // Migration properties
     public static final String PROPERTY_WHOLE_SYSTEM_TYPE_SCOPING = "fhirServer/core/useImplicitTypeScopingForWholeSystemInteractions";
 
diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java b/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java
new file mode 100644
index 00000000000..78f9c6c3c42
--- /dev/null
+++ b/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.ibm.fhir.config;
+
+/**
+ * Interaction constants to the allowed values of the
+ * fhirServer/resources/[resourceType]/interactions config property
+ */
+public enum Interaction {
+    CREATE("create"),
+    DELETE("delete"),
+    HISTORY("history"),
+    PATCH("patch"),
+    READ("read"),
+    SEARCH("search"),
+    UPDATE("update"),
+    VREAD("vread");
+
+    private final String value;
+
+    Interaction(String value) {
+        this.value = value;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static Interaction from(String value) {
+        for (Interaction interaction : Interaction.values()) {
+            if (interaction.value.equals(value)) {
+                return interaction;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+}
\ No newline at end of file
diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java b/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java
new file mode 100644
index 00000000000..8c3b55f11ac
--- /dev/null
+++ b/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.ibm.fhir.config;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.ibm.fhir.config.PropertyGroup.PropertyEntry;
+import com.ibm.fhir.core.FHIRVersionParam;
+import com.ibm.fhir.core.util.ResourceTypeHelper;
+
+/**
+ * An abstraction for the ibm-fhir-server fhirServer/resources property group
+ */
+public class ResourcesConfigAdapter {
+    public static final Logger log = Logger.getLogger(ResourcesConfigAdapter.class.getName());
+
+    private final Set<String> supportedTypes;
+    private final Map<Interaction, Set<String>> typesByInteraction;
+
+    /**
+     * Public constructor
+     *
+     * @param resourcesConfig a PropertyGroup instance for the fhirServer/resources property group
+     * @param fhirVersion a FHIRVersionParam with the fhirVersion to use for computing the applicable resource types
+     * @throws Exception
+     */
+    public ResourcesConfigAdapter(PropertyGroup resourcesConfig, FHIRVersionParam fhirVersion) throws Exception {
+        supportedTypes = computeSupportedResourceTypes(resourcesConfig, fhirVersion);
+        typesByInteraction = computeTypesByInteraction(resourcesConfig);
+    }
+
+    /**
+     * @return an immutable, non-null set of supported resource types for the given fhirVersion
+     * @throws Exception
+     */
+    public Set<String> getSupportedResourceTypes() {
+        return supportedTypes;
+    }
+
+    /**
+     * @return an immutable, non-null set of resource types that are configured for the given interaction and fhirVersion
+     */
+    public Set<String> getSupportedResourceTypes(Interaction interaction) {
+        return typesByInteraction.get(interaction);
+    }
+
+    /**
+     * Construct the list of supported resource types from the passed configuration and fhirVersion
+     *
+     * @param resourcesConfig
+     * @param fhirVersion
+     * @return
+     * @throws Exception
+     */
+    private Set<String> computeSupportedResourceTypes(PropertyGroup resourcesConfig, FHIRVersionParam fhirVersion) throws Exception {
+        Set<String> applicableTypes = ResourceTypeHelper.getResourceTypesFor(fhirVersion);
+
+        Set<String> result;
+        if (resourcesConfig == null || resourcesConfig.getBooleanProperty("open", true)) {
+            result = applicableTypes;
+        } else {
+            result = new LinkedHashSet<String>();
+            for (PropertyEntry rsrcsEntry : resourcesConfig.getProperties()) {
+                String name = rsrcsEntry.getName();
+
+                // Ensure we skip over the special property "open"
+                // and skip the abstract types Resource and DomainResource
+                if (FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN.equals(name) ||
+                        ResourceTypeHelper.getAbstractResourceTypeNames().contains(name)) {
+                    continue;
+                }
+
+                if (applicableTypes.contains(name)) {
+                    result.add(name);
+                } else if (log.isLoggable(Level.FINE)) {
+                    log.fine("Configured resource type '" + name + "' is not valid "
+                            + "or not applicable for fhirVersion " + fhirVersion.value());
+                }
+            }
+        }
+
+        return Collections.unmodifiableSet(result);
+    }
+
+    // note that this private method depends on the member supportedTypes having already been computed
+    private Map<Interaction, Set<String>> computeTypesByInteraction(PropertyGroup resourcesConfig) throws Exception {
+        Map<Interaction, Set<String>> typeMap = new HashMap<>();
+        if (resourcesConfig == null) {
+            for (Interaction interaction : Interaction.values()) {
+                typeMap.put(interaction, supportedTypes);
+            }
+        } else {
+            for (String resourceType : supportedTypes) {
+                List<String> interactions = resourcesConfig.getStringListProperty(resourceType + "/" + FHIRConfiguration.PROPERTY_FIELD_RESOURCES_INTERACTIONS);
+                if (interactions == null) {
+                    interactions = resourcesConfig.getStringListProperty("Resource/" + FHIRConfiguration.PROPERTY_FIELD_RESOURCES_INTERACTIONS);
+                }
+
+                if (interactions == null) {
+                    for (Interaction interaction : Interaction.values()) {
+                        typeMap.computeIfAbsent(interaction, k -> new LinkedHashSet<>()).add(resourceType);
+                    }
+                    continue;
+                }
+
+                for (String interactionString : interactions) {
+                    Interaction interaction = Interaction.from(interactionString);
+                    typeMap.computeIfAbsent(interaction, k -> new LinkedHashSet<>()).add(resourceType);
+                }
+            }
+        }
+
+        Map<Interaction, Set<String>> finalMap = new HashMap<>();
+        for (Entry<Interaction, Set<String>> entry : typeMap.entrySet()) {
+            finalMap.put(entry.getKey(), Collections.unmodifiableSet(entry.getValue()));
+        }
+        return Collections.unmodifiableMap(finalMap);
+    }
+}
diff --git a/fhir-config/src/test/java/com/ibm/fhir/config/test/ResourcesConfigAdapterTest.java b/fhir-config/src/test/java/com/ibm/fhir/config/test/ResourcesConfigAdapterTest.java
new file mode 100644
index 00000000000..b36e0905c9e
--- /dev/null
+++ b/fhir-config/src/test/java/com/ibm/fhir/config/test/ResourcesConfigAdapterTest.java
@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.ibm.fhir.config.test;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+import com.ibm.fhir.config.Interaction;
+import com.ibm.fhir.config.PropertyGroup;
+import com.ibm.fhir.config.ResourcesConfigAdapter;
+import com.ibm.fhir.core.FHIRVersionParam;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+
+public class ResourcesConfigAdapterTest {
+  @Test
+  public void testGetSupportedResourceTypes_r4() throws Exception {
+      JsonObject json = Json.createObjectBuilder().build();
+      PropertyGroup pg = new PropertyGroup(json);
+      ResourcesConfigAdapter resourcesConfigAdapter = new ResourcesConfigAdapter(pg, FHIRVersionParam.VERSION_40);
+
+      Set<String> supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes();
+      assertEquals(supportedResourceTypes.size(), 125);
+
+      for (Interaction interaction : Interaction.values()) {
+          supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes(interaction);
+          assertEquals(supportedResourceTypes.size(), 125);
+      }
+  }
+
+  @Test
+  public void testGetSupportedResourceTypes_r4b() throws Exception {
+      JsonObject json = Json.createObjectBuilder().build();
+      PropertyGroup pg = new PropertyGroup(json);
+      ResourcesConfigAdapter resourcesConfigAdapter = new ResourcesConfigAdapter(pg, FHIRVersionParam.VERSION_43);
+
+      Set<String> supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes();
+      assertEquals(supportedResourceTypes.size(), 141);
+
+      for (Interaction interaction : Interaction.values()) {
+          supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes(interaction);
+          assertEquals(supportedResourceTypes.size(), 141);
+      }
+  }
+}
diff --git a/fhir-core/src/main/java/com/ibm/fhir/core/FHIRMediaType.java b/fhir-core/src/main/java/com/ibm/fhir/core/FHIRMediaType.java
index 7f603d808f7..3889717fad5 100644
--- a/fhir-core/src/main/java/com/ibm/fhir/core/FHIRMediaType.java
+++ b/fhir-core/src/main/java/com/ibm/fhir/core/FHIRMediaType.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2019, 2021
+ * (C) Copyright IBM Corp. 2019, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -8,7 +8,8 @@
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
 import java.util.Set;
 
 import javax.ws.rs.core.MediaType;
@@ -18,29 +19,44 @@
  */
 public class FHIRMediaType extends MediaType {
 
-    public final static String SUBTYPE_FHIR_JSON = "fhir+json";
-    public final static String APPLICATION_FHIR_JSON = "application/" + SUBTYPE_FHIR_JSON;
-    public final static MediaType APPLICATION_FHIR_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON);
+    // use com.ibm.fhir.core.FHIRVersionParam instead
+    private static final String VERSION_40 = "4.0";
+    private static final String VERSION_43 = "4.3";
+    private static final String VERSION_401 = "4.0.1";
+    private static final String VERSION_430 = "4.3.0";
 
-    public final static String SUBTYPE_FHIR_XML = "fhir+xml";
-    public final static String APPLICATION_FHIR_XML = "application/" + SUBTYPE_FHIR_XML;
-    public final static MediaType APPLICATION_FHIR_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_XML);
+    // Supported values for the MIME-type parameter fhirVersion.
+    // https://www.hl7.org/fhir/http.html#version-parameter
+    public static final String FHIR_VERSION_PARAMETER = "fhirVersion";
+    public static final Set<String> ADVERTISED_FHIR_VERSIONS =
+            Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(VERSION_40, VERSION_43)));
+    public static final Set<String> SUPPORTED_FHIR_VERSIONS =
+            Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(VERSION_40, VERSION_401, VERSION_43, VERSION_430)));
+
+    private static final Map<String,String> fhirVersion40ParameterMap = Collections.singletonMap(FHIR_VERSION_PARAMETER, VERSION_40);
+    private static final Map<String,String> fhirVersion43ParameterMap = Collections.singletonMap(FHIR_VERSION_PARAMETER, VERSION_43);
+
+    public static final String SUBTYPE_FHIR_JSON = "fhir+json";
+    public static final String APPLICATION_FHIR_JSON = "application/" + SUBTYPE_FHIR_JSON;
+    public static final MediaType APPLICATION_FHIR_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON);
+    public static final MediaType APPLICATION_FHIR_40_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion40ParameterMap);
+    public static final MediaType APPLICATION_FHIR_43_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion43ParameterMap);
 
-    public final static String SUBTYPE_JSON_PATCH = "json-patch+json";
-    public final static String APPLICATION_JSON_PATCH = "application/" + SUBTYPE_JSON_PATCH;
-    public final static MediaType APPLICATION_JSON_PATCH_TYPE = new MediaType("application", SUBTYPE_JSON_PATCH);
+    public static final String SUBTYPE_FHIR_XML = "fhir+xml";
+    public static final String APPLICATION_FHIR_XML = "application/" + SUBTYPE_FHIR_XML;
+    public static final MediaType APPLICATION_FHIR_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_XML);
+    public static final MediaType APPLICATION_FHIR_40_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion40ParameterMap);
+    public static final MediaType APPLICATION_FHIR_43_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion43ParameterMap);
 
-    public final static String SUBTYPE_FHIR_NDJSON = "fhir+ndjson";
+    public static final String SUBTYPE_JSON_PATCH = "json-patch+json";
+    public static final String APPLICATION_JSON_PATCH = "application/" + SUBTYPE_JSON_PATCH;
+    public static final MediaType APPLICATION_JSON_PATCH_TYPE = new MediaType("application", SUBTYPE_JSON_PATCH);
+
+    public static final String SUBTYPE_FHIR_NDJSON = "fhir+ndjson";
     public static final String APPLICATION_NDJSON = "application/" + SUBTYPE_FHIR_NDJSON;
-    public final static MediaType APPLICATION_FHIR_NDJSON_TYPE = new MediaType("application", SUBTYPE_FHIR_NDJSON);
+    public static final MediaType APPLICATION_FHIR_NDJSON_TYPE = new MediaType("application", SUBTYPE_FHIR_NDJSON);
 
-    public final static String SUBTYPE_FHIR_PARQUET = "fhir+parquet";
+    public static final String SUBTYPE_FHIR_PARQUET = "fhir+parquet";
     public static final String APPLICATION_PARQUET = "application/" + SUBTYPE_FHIR_PARQUET;
-    public final static MediaType APPLICATION_FHIR_PARQUET_TYPE = new MediaType("application", SUBTYPE_FHIR_PARQUET);
-
-    // Supported values for the MIME-type parameter fhirVersion.
-    // https://www.hl7.org/fhir/http.html#version-parameter
-    public static final String FHIR_VERSION_PARAMETER = "fhirVersion";
-    public static final Set<String> SUPPORTED_FHIR_VERSIONS =
-            Collections.unmodifiableSet(new HashSet<>(Arrays.asList("4.0","4.0.1","4.3","4.3.0")));
+    public static final MediaType APPLICATION_FHIR_PARQUET_TYPE = new MediaType("application", SUBTYPE_FHIR_PARQUET);
 }
diff --git a/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java b/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java
new file mode 100644
index 00000000000..ed502e94379
--- /dev/null
+++ b/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.ibm.fhir.core;
+
+/**
+ * Enum constants for the allowed values of the fhirVersion MIME-type parameter
+ */
+public enum FHIRVersionParam {
+    VERSION_40("4.0"),
+    VERSION_43("4.3");
+
+    private final String value;
+
+    /**
+     * Private constructor
+     *
+     * @param value the fhirVersion value string
+     */
+    private FHIRVersionParam(String value) {
+        this.value = value;
+    }
+
+    /**
+     * @return
+     *     The String value of the fhirVersion parameter
+     */
+    public java.lang.String value() {
+        return value;
+    }
+
+    /**
+     * Factory method for creating FHIRVersionParam values from a passed string value.
+     *
+     * @param value
+     *     A string that matches one of the allowed FHIRVersionParam values
+     * @return
+     *     The corresponding FHIRVersionParam or null if a null value was passed
+     * @throws IllegalArgumentException
+     *     If the passed string is not null and cannot be parsed into an allowed FHIRVersionParam value
+     */
+    public static FHIRVersionParam from(String value) {
+        if (value == null) {
+            return null;
+        }
+        switch (value) {
+        case "4.0":
+            return VERSION_40;
+        case "4.3":
+            return VERSION_43;
+        default:
+            throw new IllegalArgumentException(value);
+        }
+    }
+}
diff --git a/fhir-core/src/main/java/com/ibm/fhir/core/ResourceTypeName.java b/fhir-core/src/main/java/com/ibm/fhir/core/ResourceTypeName.java
new file mode 100644
index 00000000000..986925a0089
--- /dev/null
+++ b/fhir-core/src/main/java/com/ibm/fhir/core/ResourceTypeName.java
@@ -0,0 +1,1312 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.ibm.fhir.core;
+
+/**
+ * Enum constants for all resource type names across all versions of HL7 FHIR
+ */
+public enum ResourceTypeName {
+    /**
+     * EffectEvidenceSynthesis
+     *
+     * <p>The EffectEvidenceSynthesis resource describes the difference in an outcome between exposures states in a
+     * population where the effect estimate is derived from a combination of research studies.
+     */
+    EFFECT_EVIDENCE_SYNTHESIS("EffectEvidenceSynthesis"),
+
+    /**
+     * MedicinalProduct
+     *
+     * <p>Detailed definition of a medicinal product, typically for uses other than direct patient care (e.g. regulatory use).
+     */
+    MEDICINAL_PRODUCT("MedicinalProduct"),
+
+    /**
+     * MedicinalProductAuthorization
+     *
+     * <p>The regulatory authorization of a medicinal product.
+     */
+    MEDICINAL_PRODUCT_AUTHORIZATION("MedicinalProductAuthorization"),
+
+    /**
+     * MedicinalProductContraindication
+     *
+     * <p>The clinical particulars - indications, contraindications etc. of a medicinal product, including for regulatory
+     * purposes.
+     */
+    MEDICINAL_PRODUCT_CONTRAINDICATION("MedicinalProductContraindication"),
+
+    /**
+     * MedicinalProductIndication
+     *
+     * <p>Indication for the Medicinal Product.
+     */
+    MEDICINAL_PRODUCT_INDICATION("MedicinalProductIndication"),
+
+    /**
+     * MedicinalProductIngredient
+     *
+     * <p>An ingredient of a manufactured item or pharmaceutical product.
+     */
+    MEDICINAL_PRODUCT_INGREDIENT("MedicinalProductIngredient"),
+
+    /**
+     * MedicinalProductInteraction
+     *
+     * <p>The interactions of the medicinal product with other medicinal products, or other forms of interactions.
+     */
+    MEDICINAL_PRODUCT_INTERACTION("MedicinalProductInteraction"),
+
+    /**
+     * MedicinalProductManufactured
+     *
+     * <p>The manufactured item as contained in the packaged medicinal product.
+     */
+    MEDICINAL_PRODUCT_MANUFACTURED("MedicinalProductManufactured"),
+
+    /**
+     * MedicinalProductPackaged
+     *
+     * <p>A medicinal product in a container or package.
+     */
+    MEDICINAL_PRODUCT_PACKAGED("MedicinalProductPackaged"),
+
+    /**
+     * MedicinalProductPharmaceutical
+     *
+     * <p>A pharmaceutical product described in terms of its composition and dose form.
+     */
+    MEDICINAL_PRODUCT_PHARMACEUTICAL("MedicinalProductPharmaceutical"),
+
+    /**
+     * MedicinalProductUndesirableEffect
+     *
+     * <p>Describe the undesirable effects of the medicinal product.
+     */
+    MEDICINAL_PRODUCT_UNDESIRABLE_EFFECT("MedicinalProductUndesirableEffect"),
+
+    /**
+     * RiskEvidenceSynthesis
+     *
+     * <p>The RiskEvidenceSynthesis resource describes the likelihood of an outcome in a population plus exposure state where
+     * the risk estimate is derived from a combination of research studies.
+     */
+    RISK_EVIDENCE_SYNTHESIS("RiskEvidenceSynthesis"),
+
+    /**
+     * SubstanceNucleicAcid
+     *
+     * <p>Nucleic acids are defined by three distinct elements: the base, sugar and linkage. Individual substance/moiety IDs
+     * will be created for each of these elements. The nucleotide sequence will be always entered in the 5’-3’ direction.
+     */
+    SUBSTANCE_NUCLEIC_ACID("SubstanceNucleicAcid"),
+
+    /**
+     * SubstancePolymer
+     *
+     * <p>Todo.
+     */
+    SUBSTANCE_POLYMER("SubstancePolymer"),
+
+    /**
+     * SubstanceProtein
+     *
+     * <p>A SubstanceProtein is defined as a single unit of a linear amino acid sequence, or a combination of subunits that
+     * are either covalently linked or have a defined invariant stoichiometric relationship. This includes all synthetic,
+     * recombinant and purified SubstanceProteins of defined sequence, whether the use is therapeutic or prophylactic. This
+     * set of elements will be used to describe albumins, coagulation factors, cytokines, growth factors,
+     * peptide/SubstanceProtein hormones, enzymes, toxins, toxoids, recombinant vaccines, and immunomodulators.
+     */
+    SUBSTANCE_PROTEIN("SubstanceProtein"),
+
+    /**
+     * SubstanceReferenceInformation
+     *
+     * <p>Todo.
+     */
+    SUBSTANCE_REFERENCE_INFORMATION("SubstanceReferenceInformation"),
+
+    /**
+     * SubstanceSourceMaterial
+     *
+     * <p>Source material shall capture information on the taxonomic and anatomical origins as well as the fraction of a
+     * material that can result in or can be modified to form a substance. This set of data elements shall be used to define
+     * polymer substances isolated from biological matrices. Taxonomic and anatomical origins shall be described using a
+     * controlled vocabulary as required. This information is captured for naturally derived polymers ( . starch) and
+     * structurally diverse substances. For Organisms belonging to the Kingdom Plantae the Substance level defines the fresh
+     * material of a single species or infraspecies, the Herbal Drug and the Herbal preparation. For Herbal preparations, the
+     * fraction information will be captured at the Substance information level and additional information for herbal
+     * extracts will be captured at the Specified Substance Group 1 information level. See for further explanation the
+     * Substance Class: Structurally Diverse and the herbal annex.
+     */
+    SUBSTANCE_SOURCE_MATERIAL("SubstanceSourceMaterial"),
+
+    /**
+     * SubstanceSpecification
+     *
+     * <p>The detailed description of a substance, typically at a level beyond what is used for prescribing.
+     */
+    SUBSTANCE_SPECIFICATION("SubstanceSpecification"),
+
+    /**
+     * Resource
+     *
+     * <p>--- Abstract Type! ---This is the base resource type for everything.
+     */
+    RESOURCE("Resource"),
+
+    /**
+     * Binary
+     *
+     * <p>A resource that represents the data of a single raw artifact as digital content accessible in its native format. A
+     * Binary resource can contain any content, whether text, image, pdf, zip archive, etc.
+     */
+    BINARY("Binary"),
+
+    /**
+     * Bundle
+     *
+     * <p>A container for a collection of resources.
+     */
+    BUNDLE("Bundle"),
+
+    /**
+     * DomainResource
+     *
+     * <p>--- Abstract Type! ---A resource that includes narrative, extensions, and contained resources.
+     */
+    DOMAIN_RESOURCE("DomainResource"),
+
+    /**
+     * Account
+     *
+     * <p>A financial tool for tracking value accrued for a particular purpose. In the healthcare field, used to track
+     * charges for a patient, cost centers, etc.
+     */
+    ACCOUNT("Account"),
+
+    /**
+     * ActivityDefinition
+     *
+     * <p>This resource allows for the definition of some activity to be performed, independent of a particular patient,
+     * practitioner, or other performance context.
+     */
+    ACTIVITY_DEFINITION("ActivityDefinition"),
+
+    /**
+     * AdministrableProductDefinition
+     *
+     * <p>A medicinal product in the final form which is suitable for administering to a patient (after any mixing of
+     * multiple components, dissolution etc. has been performed).
+     */
+    ADMINISTRABLE_PRODUCT_DEFINITION("AdministrableProductDefinition"),
+
+    /**
+     * AdverseEvent
+     *
+     * <p>Actual or potential/avoided event causing unintended physical injury resulting from or contributed to by medical
+     * care, a research study or other healthcare setting factors that requires additional monitoring, treatment, or
+     * hospitalization, or that results in death.
+     */
+    ADVERSE_EVENT("AdverseEvent"),
+
+    /**
+     * AllergyIntolerance
+     *
+     * <p>Risk of harmful or undesirable, physiological response which is unique to an individual and associated with
+     * exposure to a substance.
+     */
+    ALLERGY_INTOLERANCE("AllergyIntolerance"),
+
+    /**
+     * Appointment
+     *
+     * <p>A booking of a healthcare event among patient(s), practitioner(s), related person(s) and/or device(s) for a
+     * specific date/time. This may result in one or more Encounter(s).
+     */
+    APPOINTMENT("Appointment"),
+
+    /**
+     * AppointmentResponse
+     *
+     * <p>A reply to an appointment request for a patient and/or practitioner(s), such as a confirmation or rejection.
+     */
+    APPOINTMENT_RESPONSE("AppointmentResponse"),
+
+    /**
+     * AuditEvent
+     *
+     * <p>A record of an event made for purposes of maintaining a security log. Typical uses include detection of intrusion
+     * attempts and monitoring for inappropriate usage.
+     */
+    AUDIT_EVENT("AuditEvent"),
+
+    /**
+     * Basic
+     *
+     * <p>Basic is used for handling concepts not yet defined in FHIR, narrative-only resources that don't map to an existing
+     * resource, and custom resources not appropriate for inclusion in the FHIR specification.
+     */
+    BASIC("Basic"),
+
+    /**
+     * BiologicallyDerivedProduct
+     *
+     * <p>A material substance originating from a biological entity intended to be transplanted or infused
+     * <p>into another (possibly the same) biological entity.
+     */
+    BIOLOGICALLY_DERIVED_PRODUCT("BiologicallyDerivedProduct"),
+
+    /**
+     * BodyStructure
+     *
+     * <p>Record details about an anatomical structure. This resource may be used when a coded concept does not provide the
+     * necessary detail needed for the use case.
+     */
+    BODY_STRUCTURE("BodyStructure"),
+
+    /**
+     * CapabilityStatement
+     *
+     * <p>A Capability Statement documents a set of capabilities (behaviors) of a FHIR Server for a particular version of
+     * FHIR that may be used as a statement of actual server functionality or a statement of required or desired server
+     * implementation.
+     */
+    CAPABILITY_STATEMENT("CapabilityStatement"),
+
+    /**
+     * CarePlan
+     *
+     * <p>Describes the intention of how one or more practitioners intend to deliver care for a particular patient, group or
+     * community for a period of time, possibly limited to care for a specific condition or set of conditions.
+     */
+    CARE_PLAN("CarePlan"),
+
+    /**
+     * CareTeam
+     *
+     * <p>The Care Team includes all the people and organizations who plan to participate in the coordination and delivery of
+     * care for a patient.
+     */
+    CARE_TEAM("CareTeam"),
+
+    /**
+     * CatalogEntry
+     *
+     * <p>Catalog entries are wrappers that contextualize items included in a catalog.
+     */
+    CATALOG_ENTRY("CatalogEntry"),
+
+    /**
+     * ChargeItem
+     *
+     * <p>The resource ChargeItem describes the provision of healthcare provider products for a certain patient, therefore
+     * referring not only to the product, but containing in addition details of the provision, like date, time, amounts and
+     * participating organizations and persons. Main Usage of the ChargeItem is to enable the billing process and internal
+     * cost allocation.
+     */
+    CHARGE_ITEM("ChargeItem"),
+
+    /**
+     * ChargeItemDefinition
+     *
+     * <p>The ChargeItemDefinition resource provides the properties that apply to the (billing) codes necessary to calculate
+     * costs and prices. The properties may differ largely depending on type and realm, therefore this resource gives only a
+     * rough structure and requires profiling for each type of billing code system.
+     */
+    CHARGE_ITEM_DEFINITION("ChargeItemDefinition"),
+
+    /**
+     * Citation
+     *
+     * <p>The Citation Resource enables reference to any knowledge artifact for purposes of identification and attribution.
+     * The Citation Resource supports existing reference structures and developing publication practices such as versioning,
+     * expressing complex contributorship roles, and referencing computable resources.
+     */
+    CITATION("Citation"),
+
+    /**
+     * Claim
+     *
+     * <p>A provider issued list of professional services and products which have been provided, or are to be provided, to a
+     * patient which is sent to an insurer for reimbursement.
+     */
+    CLAIM("Claim"),
+
+    /**
+     * ClaimResponse
+     *
+     * <p>This resource provides the adjudication details from the processing of a Claim resource.
+     */
+    CLAIM_RESPONSE("ClaimResponse"),
+
+    /**
+     * ClinicalImpression
+     *
+     * <p>A record of a clinical assessment performed to determine what problem(s) may affect the patient and before planning
+     * the treatments or management strategies that are best to manage a patient's condition. Assessments are often 1:1 with
+     * a clinical consultation / encounter, but this varies greatly depending on the clinical workflow. This resource is
+     * called "ClinicalImpression" rather than "ClinicalAssessment" to avoid confusion with the recording of assessment tools
+     * such as Apgar score.
+     */
+    CLINICAL_IMPRESSION("ClinicalImpression"),
+
+    /**
+     * ClinicalUseDefinition
+     *
+     * <p>A single issue - either an indication, contraindication, interaction or an undesirable effect for a medicinal
+     * product, medication, device or procedure.
+     */
+    CLINICAL_USE_DEFINITION("ClinicalUseDefinition"),
+
+    /**
+     * CodeSystem
+     *
+     * <p>The CodeSystem resource is used to declare the existence of and describe a code system or code system supplement
+     * and its key properties, and optionally define a part or all of its content.
+     */
+    CODE_SYSTEM("CodeSystem"),
+
+    /**
+     * Communication
+     *
+     * <p>An occurrence of information being transmitted; e.g. an alert that was sent to a responsible provider, a public
+     * health agency that was notified about a reportable condition.
+     */
+    COMMUNICATION("Communication"),
+
+    /**
+     * CommunicationRequest
+     *
+     * <p>A request to convey information; e.g. the CDS system proposes that an alert be sent to a responsible provider, the
+     * CDS system proposes that the public health agency be notified about a reportable condition.
+     */
+    COMMUNICATION_REQUEST("CommunicationRequest"),
+
+    /**
+     * CompartmentDefinition
+     *
+     * <p>A compartment definition that defines how resources are accessed on a server.
+     */
+    COMPARTMENT_DEFINITION("CompartmentDefinition"),
+
+    /**
+     * Composition
+     *
+     * <p>A set of healthcare-related information that is assembled together into a single logical package that provides a
+     * single coherent statement of meaning, establishes its own context and that has clinical attestation with regard to who
+     * is making the statement. A Composition defines the structure and narrative content necessary for a document. However,
+     * a Composition alone does not constitute a document. Rather, the Composition must be the first entry in a Bundle where
+     * Bundle.type=document, and any other resources referenced from Composition must be included as subsequent entries in
+     * the Bundle (for example Patient, Practitioner, Encounter, etc.).
+     */
+    COMPOSITION("Composition"),
+
+    /**
+     * ConceptMap
+     *
+     * <p>A statement of relationships from one set of concepts to one or more other concepts - either concepts in code
+     * systems, or data element/data element concepts, or classes in class models.
+     */
+    CONCEPT_MAP("ConceptMap"),
+
+    /**
+     * Condition
+     *
+     * <p>A clinical condition, problem, diagnosis, or other event, situation, issue, or clinical concept that has risen to a
+     * level of concern.
+     */
+    CONDITION("Condition"),
+
+    /**
+     * Consent
+     *
+     * <p>A record of a healthcare consumer’s choices, which permits or denies identified recipient(s) or recipient role(s)
+     * to perform one or more actions within a given policy context, for specific purposes and periods of time.
+     */
+    CONSENT("Consent"),
+
+    /**
+     * Contract
+     *
+     * <p>Legally enforceable, formally recorded unilateral or bilateral directive i.e., a policy or agreement.
+     */
+    CONTRACT("Contract"),
+
+    /**
+     * Coverage
+     *
+     * <p>Financial instrument which may be used to reimburse or pay for health care products and services. Includes both
+     * insurance and self-payment.
+     */
+    COVERAGE("Coverage"),
+
+    /**
+     * CoverageEligibilityRequest
+     *
+     * <p>The CoverageEligibilityRequest provides patient and insurance coverage information to an insurer for them to
+     * respond, in the form of an CoverageEligibilityResponse, with information regarding whether the stated coverage is
+     * valid and in-force and optionally to provide the insurance details of the policy.
+     */
+    COVERAGE_ELIGIBILITY_REQUEST("CoverageEligibilityRequest"),
+
+    /**
+     * CoverageEligibilityResponse
+     *
+     * <p>This resource provides eligibility and plan details from the processing of an CoverageEligibilityRequest resource.
+     */
+    COVERAGE_ELIGIBILITY_RESPONSE("CoverageEligibilityResponse"),
+
+    /**
+     * DetectedIssue
+     *
+     * <p>Indicates an actual or potential clinical issue with or between one or more active or proposed clinical actions for
+     * a patient; e.g. Drug-drug interaction, Ineffective treatment frequency, Procedure-condition conflict, etc.
+     */
+    DETECTED_ISSUE("DetectedIssue"),
+
+    /**
+     * Device
+     *
+     * <p>A type of a manufactured item that is used in the provision of healthcare without being substantially changed
+     * through that activity. The device may be a medical or non-medical device.
+     */
+    DEVICE("Device"),
+
+    /**
+     * DeviceDefinition
+     *
+     * <p>The characteristics, operational status and capabilities of a medical-related component of a medical device.
+     */
+    DEVICE_DEFINITION("DeviceDefinition"),
+
+    /**
+     * DeviceMetric
+     *
+     * <p>Describes a measurement, calculation or setting capability of a medical device.
+     */
+    DEVICE_METRIC("DeviceMetric"),
+
+    /**
+     * DeviceRequest
+     *
+     * <p>Represents a request for a patient to employ a medical device. The device may be an implantable device, or an
+     * external assistive device, such as a walker.
+     */
+    DEVICE_REQUEST("DeviceRequest"),
+
+    /**
+     * DeviceUseStatement
+     *
+     * <p>A record of a device being used by a patient where the record is the result of a report from the patient or another
+     * clinician.
+     */
+    DEVICE_USE_STATEMENT("DeviceUseStatement"),
+
+    /**
+     * DiagnosticReport
+     *
+     * <p>The findings and interpretation of diagnostic tests performed on patients, groups of patients, devices, and
+     * locations, and/or specimens derived from these. The report includes clinical context such as requesting and provider
+     * information, and some mix of atomic results, images, textual and coded interpretations, and formatted representation
+     * of diagnostic reports.
+     */
+    DIAGNOSTIC_REPORT("DiagnosticReport"),
+
+    /**
+     * DocumentManifest
+     *
+     * <p>A collection of documents compiled for a purpose together with metadata that applies to the collection.
+     */
+    DOCUMENT_MANIFEST("DocumentManifest"),
+
+    /**
+     * DocumentReference
+     *
+     * <p>A reference to a document of any kind for any purpose. Provides metadata about the document so that the document
+     * can be discovered and managed. The scope of a document is any seralized object with a mime-type, so includes formal
+     * patient centric documents (CDA), cliical notes, scanned paper, and non-patient specific documents like policy text.
+     */
+    DOCUMENT_REFERENCE("DocumentReference"),
+
+    /**
+     * Encounter
+     *
+     * <p>An interaction between a patient and healthcare provider(s) for the purpose of providing healthcare service(s) or
+     * assessing the health status of a patient.
+     */
+    ENCOUNTER("Encounter"),
+
+    /**
+     * Endpoint
+     *
+     * <p>The technical details of an endpoint that can be used for electronic services, such as for web services providing
+     * XDS.b or a REST endpoint for another FHIR server. This may include any security context information.
+     */
+    ENDPOINT("Endpoint"),
+
+    /**
+     * EnrollmentRequest
+     *
+     * <p>This resource provides the insurance enrollment details to the insurer regarding a specified coverage.
+     */
+    ENROLLMENT_REQUEST("EnrollmentRequest"),
+
+    /**
+     * EnrollmentResponse
+     *
+     * <p>This resource provides enrollment and plan details from the processing of an EnrollmentRequest resource.
+     */
+    ENROLLMENT_RESPONSE("EnrollmentResponse"),
+
+    /**
+     * EpisodeOfCare
+     *
+     * <p>An association between a patient and an organization / healthcare provider(s) during which time encounters may
+     * occur. The managing organization assumes a level of responsibility for the patient during this time.
+     */
+    EPISODE_OF_CARE("EpisodeOfCare"),
+
+    /**
+     * EventDefinition
+     *
+     * <p>The EventDefinition resource provides a reusable description of when a particular event can occur.
+     */
+    EVENT_DEFINITION("EventDefinition"),
+
+    /**
+     * Evidence
+     *
+     * <p>The Evidence Resource provides a machine-interpretable expression of an evidence concept including the evidence
+     * variables (eg population, exposures/interventions, comparators, outcomes, measured variables, confounding variables),
+     * the statistics, and the certainty of this evidence.
+     */
+    EVIDENCE("Evidence"),
+
+    /**
+     * EvidenceReport
+     *
+     * <p>The EvidenceReport Resource is a specialized container for a collection of resources and codable concepts, adapted
+     * to support compositions of Evidence, EvidenceVariable, and Citation resources and related concepts.
+     */
+    EVIDENCE_REPORT("EvidenceReport"),
+
+    /**
+     * EvidenceVariable
+     *
+     * <p>The EvidenceVariable resource describes an element that knowledge (Evidence) is about.
+     */
+    EVIDENCE_VARIABLE("EvidenceVariable"),
+
+    /**
+     * ExampleScenario
+     *
+     * <p>Example of workflow instance.
+     */
+    EXAMPLE_SCENARIO("ExampleScenario"),
+
+    /**
+     * ExplanationOfBenefit
+     *
+     * <p>This resource provides: the claim details; adjudication details from the processing of a Claim; and optionally
+     * account balance information, for informing the subscriber of the benefits provided.
+     */
+    EXPLANATION_OF_BENEFIT("ExplanationOfBenefit"),
+
+    /**
+     * FamilyMemberHistory
+     *
+     * <p>Significant health conditions for a person related to the patient relevant in the context of care for the patient.
+     */
+    FAMILY_MEMBER_HISTORY("FamilyMemberHistory"),
+
+    /**
+     * Flag
+     *
+     * <p>Prospective warnings of potential issues when providing care to the patient.
+     */
+    FLAG("Flag"),
+
+    /**
+     * Goal
+     *
+     * <p>Describes the intended objective(s) for a patient, group or organization care, for example, weight loss, restoring
+     * an activity of daily living, obtaining herd immunity via immunization, meeting a process improvement objective, etc.
+     */
+    GOAL("Goal"),
+
+    /**
+     * GraphDefinition
+     *
+     * <p>A formal computable definition of a graph of resources - that is, a coherent set of resources that form a graph by
+     * following references. The Graph Definition resource defines a set and makes rules about the set.
+     */
+    GRAPH_DEFINITION("GraphDefinition"),
+
+    /**
+     * Group
+     *
+     * <p>Represents a defined collection of entities that may be discussed or acted upon collectively but which are not
+     * expected to act collectively, and are not formally or legally recognized; i.e. a collection of entities that isn't an
+     * Organization.
+     */
+    GROUP("Group"),
+
+    /**
+     * GuidanceResponse
+     *
+     * <p>A guidance response is the formal response to a guidance request, including any output parameters returned by the
+     * evaluation, as well as the description of any proposed actions to be taken.
+     */
+    GUIDANCE_RESPONSE("GuidanceResponse"),
+
+    /**
+     * HealthcareService
+     *
+     * <p>The details of a healthcare service available at a location.
+     */
+    HEALTHCARE_SERVICE("HealthcareService"),
+
+    /**
+     * ImagingStudy
+     *
+     * <p>Representation of the content produced in a DICOM imaging study. A study comprises a set of series, each of which
+     * includes a set of Service-Object Pair Instances (SOP Instances - images or other data) acquired or produced in a
+     * common context. A series is of only one modality (e.g. X-ray, CT, MR, ultrasound), but a study may have multiple
+     * series of different modalities.
+     */
+    IMAGING_STUDY("ImagingStudy"),
+
+    /**
+     * Immunization
+     *
+     * <p>Describes the event of a patient being administered a vaccine or a record of an immunization as reported by a
+     * patient, a clinician or another party.
+     */
+    IMMUNIZATION("Immunization"),
+
+    /**
+     * ImmunizationEvaluation
+     *
+     * <p>Describes a comparison of an immunization event against published recommendations to determine if the
+     * administration is "valid" in relation to those recommendations.
+     */
+    IMMUNIZATION_EVALUATION("ImmunizationEvaluation"),
+
+    /**
+     * ImmunizationRecommendation
+     *
+     * <p>A patient's point-in-time set of recommendations (i.e. forecasting) according to a published schedule with optional
+     * supporting justification.
+     */
+    IMMUNIZATION_RECOMMENDATION("ImmunizationRecommendation"),
+
+    /**
+     * ImplementationGuide
+     *
+     * <p>A set of rules of how a particular interoperability or standards problem is solved - typically through the use of
+     * FHIR resources. This resource is used to gather all the parts of an implementation guide into a logical whole and to
+     * publish a computable definition of all the parts.
+     */
+    IMPLEMENTATION_GUIDE("ImplementationGuide"),
+
+    /**
+     * Ingredient
+     *
+     * <p>An ingredient of a manufactured item or pharmaceutical product.
+     */
+    INGREDIENT("Ingredient"),
+
+    /**
+     * InsurancePlan
+     *
+     * <p>Details of a Health Insurance product/plan provided by an organization.
+     */
+    INSURANCE_PLAN("InsurancePlan"),
+
+    /**
+     * Invoice
+     *
+     * <p>Invoice containing collected ChargeItems from an Account with calculated individual and total price for Billing
+     * purpose.
+     */
+    INVOICE("Invoice"),
+
+    /**
+     * Library
+     *
+     * <p>The Library resource is a general-purpose container for knowledge asset definitions. It can be used to describe and
+     * expose existing knowledge assets such as logic libraries and information model descriptions, as well as to describe a
+     * collection of knowledge assets.
+     */
+    LIBRARY("Library"),
+
+    /**
+     * Linkage
+     *
+     * <p>Identifies two or more records (resource instances) that refer to the same real-world "occurrence".
+     */
+    LINKAGE("Linkage"),
+
+    /**
+     * List
+     *
+     * <p>A list is a curated collection of resources.
+     */
+    LIST("List"),
+
+    /**
+     * Location
+     *
+     * <p>Details and position information for a physical place where services are provided and resources and participants
+     * may be stored, found, contained, or accommodated.
+     */
+    LOCATION("Location"),
+
+    /**
+     * ManufacturedItemDefinition
+     *
+     * <p>The definition and characteristics of a medicinal manufactured item, such as a tablet or capsule, as contained in a
+     * packaged medicinal product.
+     */
+    MANUFACTURED_ITEM_DEFINITION("ManufacturedItemDefinition"),
+
+    /**
+     * Measure
+     *
+     * <p>The Measure resource provides the definition of a quality measure.
+     */
+    MEASURE("Measure"),
+
+    /**
+     * MeasureReport
+     *
+     * <p>The MeasureReport resource contains the results of the calculation of a measure; and optionally a reference to the
+     * resources involved in that calculation.
+     */
+    MEASURE_REPORT("MeasureReport"),
+
+    /**
+     * Media
+     *
+     * <p>A photo, video, or audio recording acquired or used in healthcare. The actual content may be inline or provided by
+     * direct reference.
+     */
+    MEDIA("Media"),
+
+    /**
+     * Medication
+     *
+     * <p>This resource is primarily used for the identification and definition of a medication for the purposes of
+     * prescribing, dispensing, and administering a medication as well as for making statements about medication use.
+     */
+    MEDICATION("Medication"),
+
+    /**
+     * MedicationAdministration
+     *
+     * <p>Describes the event of a patient consuming or otherwise being administered a medication. This may be as simple as
+     * swallowing a tablet or it may be a long running infusion. Related resources tie this event to the authorizing
+     * prescription, and the specific encounter between patient and health care practitioner.
+     */
+    MEDICATION_ADMINISTRATION("MedicationAdministration"),
+
+    /**
+     * MedicationDispense
+     *
+     * <p>Indicates that a medication product is to be or has been dispensed for a named person/patient. This includes a
+     * description of the medication product (supply) provided and the instructions for administering the medication. The
+     * medication dispense is the result of a pharmacy system responding to a medication order.
+     */
+    MEDICATION_DISPENSE("MedicationDispense"),
+
+    /**
+     * MedicationKnowledge
+     *
+     * <p>Information about a medication that is used to support knowledge.
+     */
+    MEDICATION_KNOWLEDGE("MedicationKnowledge"),
+
+    /**
+     * MedicationRequest
+     *
+     * <p>An order or request for both supply of the medication and the instructions for administration of the medication to
+     * a patient. The resource is called "MedicationRequest" rather than "MedicationPrescription" or "MedicationOrder" to
+     * generalize the use across inpatient and outpatient settings, including care plans, etc., and to harmonize with
+     * workflow patterns.
+     */
+    MEDICATION_REQUEST("MedicationRequest"),
+
+    /**
+     * MedicationStatement
+     *
+     * <p>A record of a medication that is being consumed by a patient. A MedicationStatement may indicate that the patient
+     * may be taking the medication now or has taken the medication in the past or will be taking the medication in the
+     * future. The source of this information can be the patient, significant other (such as a family member or spouse), or a
+     * clinician. A common scenario where this information is captured is during the history taking process during a patient
+     * visit or stay. The medication information may come from sources such as the patient's memory, from a prescription
+     * bottle, or from a list of medications the patient, clinician or other party maintains.
+     *
+     * <p>The primary difference between a medication statement and a medication administration is that the medication
+     * administration has complete administration information and is based on actual administration information from the
+     * person who administered the medication. A medication statement is often, if not always, less specific. There is no
+     * required date/time when the medication was administered, in fact we only know that a source has reported the patient
+     * is taking this medication, where details such as time, quantity, or rate or even medication product may be incomplete
+     * or missing or less precise. As stated earlier, the medication statement information may come from the patient's
+     * memory, from a prescription bottle or from a list of medications the patient, clinician or other party maintains.
+     * Medication administration is more formal and is not missing detailed information.
+     */
+    MEDICATION_STATEMENT("MedicationStatement"),
+
+    /**
+     * MedicinalProductDefinition
+     *
+     * <p>Detailed definition of a medicinal product, typically for uses other than direct patient care (e.g. regulatory use,
+     * drug catalogs).
+     */
+    MEDICINAL_PRODUCT_DEFINITION("MedicinalProductDefinition"),
+
+    /**
+     * MessageDefinition
+     *
+     * <p>Defines the characteristics of a message that can be shared between systems, including the type of event that
+     * initiates the message, the content to be transmitted and what response(s), if any, are permitted.
+     */
+    MESSAGE_DEFINITION("MessageDefinition"),
+
+    /**
+     * MessageHeader
+     *
+     * <p>The header for a message exchange that is either requesting or responding to an action. The reference(s) that are
+     * the subject of the action as well as other information related to the action are typically transmitted in a bundle in
+     * which the MessageHeader resource instance is the first resource in the bundle.
+     */
+    MESSAGE_HEADER("MessageHeader"),
+
+    /**
+     * MolecularSequence
+     *
+     * <p>Raw data describing a biological sequence.
+     */
+    MOLECULAR_SEQUENCE("MolecularSequence"),
+
+    /**
+     * NamingSystem
+     *
+     * <p>A curated namespace that issues unique symbols within that namespace for the identification of concepts, people,
+     * devices, etc. Represents a "System" used within the Identifier and Coding data types.
+     */
+    NAMING_SYSTEM("NamingSystem"),
+
+    /**
+     * NutritionOrder
+     *
+     * <p>A request to supply a diet, formula feeding (enteral) or oral nutritional supplement to a patient/resident.
+     */
+    NUTRITION_ORDER("NutritionOrder"),
+
+    /**
+     * NutritionProduct
+     *
+     * <p>A food or fluid product that is consumed by patients.
+     */
+    NUTRITION_PRODUCT("NutritionProduct"),
+
+    /**
+     * Observation
+     *
+     * <p>Measurements and simple assertions made about a patient, device or other subject.
+     */
+    OBSERVATION("Observation"),
+
+    /**
+     * ObservationDefinition
+     *
+     * <p>Set of definitional characteristics for a kind of observation or measurement produced or consumed by an orderable
+     * health care service.
+     */
+    OBSERVATION_DEFINITION("ObservationDefinition"),
+
+    /**
+     * OperationDefinition
+     *
+     * <p>A formal computable definition of an operation (on the RESTful interface) or a named query (using the search
+     * interaction).
+     */
+    OPERATION_DEFINITION("OperationDefinition"),
+
+    /**
+     * OperationOutcome
+     *
+     * <p>A collection of error, warning, or information messages that result from a system action.
+     */
+    OPERATION_OUTCOME("OperationOutcome"),
+
+    /**
+     * Organization
+     *
+     * <p>A formally or informally recognized grouping of people or organizations formed for the purpose of achieving some
+     * form of collective action. Includes companies, institutions, corporations, departments, community groups, healthcare
+     * practice groups, payer/insurer, etc.
+     */
+    ORGANIZATION("Organization"),
+
+    /**
+     * OrganizationAffiliation
+     *
+     * <p>Defines an affiliation/assotiation/relationship between 2 distinct oganizations, that is not a part-of
+     * relationship/sub-division relationship.
+     */
+    ORGANIZATION_AFFILIATION("OrganizationAffiliation"),
+
+    /**
+     * PackagedProductDefinition
+     *
+     * <p>A medically related item or items, in a container or package.
+     */
+    PACKAGED_PRODUCT_DEFINITION("PackagedProductDefinition"),
+
+    /**
+     * Parameters
+     *
+     * <p>This resource is a non-persisted resource used to pass information into and back from an [operation](operations.
+     * html). It has no other use, and there is no RESTful endpoint associated with it.
+     */
+    PARAMETERS("Parameters"),
+
+    /**
+     * Patient
+     *
+     * <p>Demographics and other administrative information about an individual or animal receiving care or other health-
+     * related services.
+     */
+    PATIENT("Patient"),
+
+    /**
+     * PaymentNotice
+     *
+     * <p>This resource provides the status of the payment for goods and services rendered, and the request and response
+     * resource references.
+     */
+    PAYMENT_NOTICE("PaymentNotice"),
+
+    /**
+     * PaymentReconciliation
+     *
+     * <p>This resource provides the details including amount of a payment and allocates the payment items being paid.
+     */
+    PAYMENT_RECONCILIATION("PaymentReconciliation"),
+
+    /**
+     * Person
+     *
+     * <p>Demographics and administrative information about a person independent of a specific health-related context.
+     */
+    PERSON("Person"),
+
+    /**
+     * PlanDefinition
+     *
+     * <p>This resource allows for the definition of various types of plans as a sharable, consumable, and executable
+     * artifact. The resource is general enough to support the description of a broad range of clinical and non-clinical
+     * artifacts such as clinical decision support rules, order sets, protocols, and drug quality specifications.
+     */
+    PLAN_DEFINITION("PlanDefinition"),
+
+    /**
+     * Practitioner
+     *
+     * <p>A person who is directly or indirectly involved in the provisioning of healthcare.
+     */
+    PRACTITIONER("Practitioner"),
+
+    /**
+     * PractitionerRole
+     *
+     * <p>A specific set of Roles/Locations/specialties/services that a practitioner may perform at an organization for a
+     * period of time.
+     */
+    PRACTITIONER_ROLE("PractitionerRole"),
+
+    /**
+     * Procedure
+     *
+     * <p>An action that is or was performed on or for a patient. This can be a physical intervention like an operation, or
+     * less invasive like long term services, counseling, or hypnotherapy.
+     */
+    PROCEDURE("Procedure"),
+
+    /**
+     * Provenance
+     *
+     * <p>Provenance of a resource is a record that describes entities and processes involved in producing and delivering or
+     * otherwise influencing that resource. Provenance provides a critical foundation for assessing authenticity, enabling
+     * trust, and allowing reproducibility. Provenance assertions are a form of contextual metadata and can themselves become
+     * important records with their own provenance. Provenance statement indicates clinical significance in terms of
+     * confidence in authenticity, reliability, and trustworthiness, integrity, and stage in lifecycle (e.g. Document
+     * Completion - has the artifact been legally authenticated), all of which may impact security, privacy, and trust
+     * policies.
+     */
+    PROVENANCE("Provenance"),
+
+    /**
+     * Questionnaire
+     *
+     * <p>A structured set of questions intended to guide the collection of answers from end-users. Questionnaires provide
+     * detailed control over order, presentation, phraseology and grouping to allow coherent, consistent data collection.
+     */
+    QUESTIONNAIRE("Questionnaire"),
+
+    /**
+     * QuestionnaireResponse
+     *
+     * <p>A structured set of questions and their answers. The questions are ordered and grouped into coherent subsets,
+     * corresponding to the structure of the grouping of the questionnaire being responded to.
+     */
+    QUESTIONNAIRE_RESPONSE("QuestionnaireResponse"),
+
+    /**
+     * RegulatedAuthorization
+     *
+     * <p>Regulatory approval, clearance or licencing related to a regulated product, treatment, facility or activity that is
+     * cited in a guidance, regulation, rule or legislative act. An example is Market Authorization relating to a Medicinal
+     * Product.
+     */
+    REGULATED_AUTHORIZATION("RegulatedAuthorization"),
+
+    /**
+     * RelatedPerson
+     *
+     * <p>Information about a person that is involved in the care for a patient, but who is not the target of healthcare, nor
+     * has a formal responsibility in the care process.
+     */
+    RELATED_PERSON("RelatedPerson"),
+
+    /**
+     * RequestGroup
+     *
+     * <p>A group of related requests that can be used to capture intended activities that have inter-dependencies such as
+     * "give this medication after that one".
+     */
+    REQUEST_GROUP("RequestGroup"),
+
+    /**
+     * ResearchDefinition
+     *
+     * <p>The ResearchDefinition resource describes the conditional state (population and any exposures being compared within
+     * the population) and outcome (if specified) that the knowledge (evidence, assertion, recommendation) is about.
+     */
+    RESEARCH_DEFINITION("ResearchDefinition"),
+
+    /**
+     * ResearchElementDefinition
+     *
+     * <p>The ResearchElementDefinition resource describes a "PICO" element that knowledge (evidence, assertion,
+     * recommendation) is about.
+     */
+    RESEARCH_ELEMENT_DEFINITION("ResearchElementDefinition"),
+
+    /**
+     * ResearchStudy
+     *
+     * <p>A process where a researcher or organization plans and then executes a series of steps intended to increase the
+     * field of healthcare-related knowledge. This includes studies of safety, efficacy, comparative effectiveness and other
+     * information about medications, devices, therapies and other interventional and investigative techniques. A
+     * ResearchStudy involves the gathering of information about human or animal subjects.
+     */
+    RESEARCH_STUDY("ResearchStudy"),
+
+    /**
+     * ResearchSubject
+     *
+     * <p>A physical entity which is the primary unit of operational and/or administrative interest in a study.
+     */
+    RESEARCH_SUBJECT("ResearchSubject"),
+
+    /**
+     * RiskAssessment
+     *
+     * <p>An assessment of the likely outcome(s) for a patient or other subject as well as the likelihood of each outcome.
+     */
+    RISK_ASSESSMENT("RiskAssessment"),
+
+    /**
+     * Schedule
+     *
+     * <p>A container for slots of time that may be available for booking appointments.
+     */
+    SCHEDULE("Schedule"),
+
+    /**
+     * SearchParameter
+     *
+     * <p>A search parameter that defines a named search item that can be used to search/filter on a resource.
+     */
+    SEARCH_PARAMETER("SearchParameter"),
+
+    /**
+     * ServiceRequest
+     *
+     * <p>A record of a request for service such as diagnostic investigations, treatments, or operations to be performed.
+     */
+    SERVICE_REQUEST("ServiceRequest"),
+
+    /**
+     * Slot
+     *
+     * <p>A slot of time on a schedule that may be available for booking appointments.
+     */
+    SLOT("Slot"),
+
+    /**
+     * Specimen
+     *
+     * <p>A sample to be used for analysis.
+     */
+    SPECIMEN("Specimen"),
+
+    /**
+     * SpecimenDefinition
+     *
+     * <p>A kind of specimen with associated set of requirements.
+     */
+    SPECIMEN_DEFINITION("SpecimenDefinition"),
+
+    /**
+     * StructureDefinition
+     *
+     * <p>A definition of a FHIR structure. This resource is used to describe the underlying resources, data types defined in
+     * FHIR, and also for describing extensions and constraints on resources and data types.
+     */
+    STRUCTURE_DEFINITION("StructureDefinition"),
+
+    /**
+     * StructureMap
+     *
+     * <p>A Map of relationships between 2 structures that can be used to transform data.
+     */
+    STRUCTURE_MAP("StructureMap"),
+
+    /**
+     * Subscription
+     *
+     * <p>The subscription resource is used to define a push-based subscription from a server to another system. Once a
+     * subscription is registered with the server, the server checks every resource that is created or updated, and if the
+     * resource matches the given criteria, it sends a message on the defined "channel" so that another system can take an
+     * appropriate action.
+     */
+    SUBSCRIPTION("Subscription"),
+
+    /**
+     * SubscriptionStatus
+     *
+     * <p>The SubscriptionStatus resource describes the state of a Subscription during notifications.
+     */
+    SUBSCRIPTION_STATUS("SubscriptionStatus"),
+
+    /**
+     * SubscriptionTopic
+     *
+     * <p>Describes a stream of resource state changes identified by trigger criteria and annotated with labels useful to
+     * filter projections from this topic.
+     */
+    SUBSCRIPTION_TOPIC("SubscriptionTopic"),
+
+    /**
+     * Substance
+     *
+     * <p>A homogeneous material with a definite composition.
+     */
+    SUBSTANCE("Substance"),
+
+    /**
+     * SubstanceDefinition
+     *
+     * <p>The detailed description of a substance, typically at a level beyond what is used for prescribing.
+     */
+    SUBSTANCE_DEFINITION("SubstanceDefinition"),
+
+    /**
+     * SupplyDelivery
+     *
+     * <p>Record of delivery of what is supplied.
+     */
+    SUPPLY_DELIVERY("SupplyDelivery"),
+
+    /**
+     * SupplyRequest
+     *
+     * <p>A record of a request for a medication, substance or device used in the healthcare setting.
+     */
+    SUPPLY_REQUEST("SupplyRequest"),
+
+    /**
+     * Task
+     *
+     * <p>A task to be performed.
+     */
+    TASK("Task"),
+
+    /**
+     * TerminologyCapabilities
+     *
+     * <p>A TerminologyCapabilities resource documents a set of capabilities (behaviors) of a FHIR Terminology Server that
+     * may be used as a statement of actual server functionality or a statement of required or desired server implementation.
+     */
+    TERMINOLOGY_CAPABILITIES("TerminologyCapabilities"),
+
+    /**
+     * TestReport
+     *
+     * <p>A summary of information based on the results of executing a TestScript.
+     */
+    TEST_REPORT("TestReport"),
+
+    /**
+     * TestScript
+     *
+     * <p>A structured set of tests against a FHIR server or client implementation to determine compliance against the FHIR
+     * specification.
+     */
+    TEST_SCRIPT("TestScript"),
+
+    /**
+     * ValueSet
+     *
+     * <p>A ValueSet resource instance specifies a set of codes drawn from one or more code systems, intended for use in a
+     * particular context. Value sets link between [[[CodeSystem]]] definitions and their use in [coded elements]
+     * (terminologies.html).
+     */
+    VALUE_SET("ValueSet"),
+
+    /**
+     * VerificationResult
+     *
+     * <p>Describes validation requirements, source(s), status and dates for one or more elements.
+     */
+    VERIFICATION_RESULT("VerificationResult"),
+
+    /**
+     * VisionPrescription
+     *
+     * <p>An authorization for the provision of glasses and/or contact lenses to a patient.
+     */
+    VISION_PRESCRIPTION("VisionPrescription");
+
+    private final String value;
+
+    ResourceTypeName(String value) {
+        this.value = value;
+    }
+
+    /**
+     * @return
+     *     The String value of the resource type name
+     */
+    public java.lang.String value() {
+        return value;
+    }
+}
diff --git a/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java b/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java
new file mode 100644
index 00000000000..7bfc704efd1
--- /dev/null
+++ b/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.ibm.fhir.core.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.ibm.fhir.core.FHIRVersionParam;
+import com.ibm.fhir.core.ResourceTypeName;
+
+/**
+ * Helper methods for working with FHIR Resource Type Strings
+ */
+public class ResourceTypeHelper {
+    private static final Set<ResourceTypeName> REMOVED_RESOURCE_TYPES = collectRemovedResourceTypes();
+    private static final Set<ResourceTypeName> R4B_ONLY_RESOURCE_TYPES = collectR4bOnlyResourceTypes();
+    private static final Set<ResourceTypeName> ABSTRACT_TYPES = Collections.unmodifiableSet(new HashSet<>(
+            Arrays.asList(
+                ResourceTypeName.RESOURCE,
+                ResourceTypeName.DOMAIN_RESOURCE
+            )));
+
+    private static final Set<String> R4_RESOURCES = Collections.unmodifiableSet(new LinkedHashSet<>(
+            Arrays.stream(ResourceTypeName.values())
+                .filter(rtn -> !REMOVED_RESOURCE_TYPES.contains(rtn))
+                .filter(rtn -> !R4B_ONLY_RESOURCE_TYPES.contains(rtn))
+                .filter(rtn -> !ABSTRACT_TYPES.contains(rtn))
+                .map(ResourceTypeName::value)
+                .collect(Collectors.toList())));
+
+    private static final Set<String> R4B_RESOURCES = Collections.unmodifiableSet(new LinkedHashSet<>(
+            Arrays.stream(ResourceTypeName.values())
+                .filter(rtn -> !REMOVED_RESOURCE_TYPES.contains(rtn))
+                .filter(rtn -> !ABSTRACT_TYPES.contains(rtn))
+                .map(ResourceTypeName::value)
+                .collect(Collectors.toList())));
+
+    private static final Set<String> R4B_ONLY_RESOURCES = Collections.unmodifiableSet(new LinkedHashSet<>(
+            R4B_ONLY_RESOURCE_TYPES.stream()
+                .map(ResourceTypeName::value)
+                .collect(Collectors.toList())));
+
+    private static final Set<String> ABSTRACT_RESOURCES = Collections.unmodifiableSet(
+            ABSTRACT_TYPES.stream()
+                .map(ResourceTypeName::value)
+                .collect(Collectors.toSet()));
+
+    /**
+     * @param fhirVersion The value of the MIME-type parameter 'fhirVersion' for the current interaction
+     *          (e.g. "4.3" not "4.3.0")
+     * @return a set of resource type names that corresponds to the requested fhirVersion
+     */
+    public static Set<String> getResourceTypesFor(FHIRVersionParam fhirVersion) {
+        switch (fhirVersion) {
+        case VERSION_43:
+            return R4B_RESOURCES;
+        case VERSION_40:
+        default:
+            return R4_RESOURCES;
+        }
+    }
+
+    /**
+     * @return the set of resource type names that were either introduced in 4.3.0 (e.g. Ingredient) or changed
+     *          in backwards-incompatible ways in the 4.3.0 release (e.g. Evidence and EvidenceVariable)
+     */
+    public static Set<String> getNewOrBreakingResourceTypeNames() {
+        return R4B_ONLY_RESOURCES;
+    }
+
+    /**
+     * @return the set of resource type names that were either introduced in 4.3.0 (e.g. Ingredient) or changed
+     *          in backwards-incompatible ways in the 4.3.0 release (e.g. Evidence and EvidenceVariable)
+     */
+    public static Set<String> getAbstractResourceTypeNames() {
+        return ABSTRACT_RESOURCES;
+    }
+
+    private static Set<ResourceTypeName> collectRemovedResourceTypes() {
+        Set<ResourceTypeName> set = new HashSet<>();
+        set.add(ResourceTypeName.EFFECT_EVIDENCE_SYNTHESIS);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_AUTHORIZATION);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_CONTRAINDICATION);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_INDICATION);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_INGREDIENT);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_INTERACTION);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_MANUFACTURED);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_PACKAGED);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_PHARMACEUTICAL);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_UNDESIRABLE_EFFECT);
+        set.add(ResourceTypeName.RISK_EVIDENCE_SYNTHESIS);
+        set.add(ResourceTypeName.SUBSTANCE_NUCLEIC_ACID);
+        set.add(ResourceTypeName.SUBSTANCE_POLYMER);
+        set.add(ResourceTypeName.SUBSTANCE_PROTEIN);
+        set.add(ResourceTypeName.SUBSTANCE_REFERENCE_INFORMATION);
+        set.add(ResourceTypeName.SUBSTANCE_SOURCE_MATERIAL);
+        set.add(ResourceTypeName.SUBSTANCE_SPECIFICATION);
+        return set;
+    }
+
+    private static Set<ResourceTypeName> collectR4bOnlyResourceTypes() {
+        Set<ResourceTypeName> set = new HashSet<>();
+        set.add(ResourceTypeName.ADMINISTRABLE_PRODUCT_DEFINITION);
+        set.add(ResourceTypeName.CITATION);
+        set.add(ResourceTypeName.CLINICAL_USE_DEFINITION);
+        set.add(ResourceTypeName.EVIDENCE_REPORT);
+        set.add(ResourceTypeName.INGREDIENT);
+        set.add(ResourceTypeName.MANUFACTURED_ITEM_DEFINITION);
+        set.add(ResourceTypeName.MEDICINAL_PRODUCT_DEFINITION);
+        set.add(ResourceTypeName.NUTRITION_PRODUCT);
+        set.add(ResourceTypeName.PACKAGED_PRODUCT_DEFINITION);
+        set.add(ResourceTypeName.REGULATED_AUTHORIZATION);
+        set.add(ResourceTypeName.SUBSCRIPTION_STATUS);
+        set.add(ResourceTypeName.SUBSCRIPTION_TOPIC);
+        set.add(ResourceTypeName.SUBSTANCE_DEFINITION);
+        // The following resource types existed in R4, but have breaking changes in R4B.
+        // Because we only support the R4B version, we don't want to advertise these in our 4.0.1 statement.
+        set.add(ResourceTypeName.DEVICE_DEFINITION);
+        set.add(ResourceTypeName.EVIDENCE);
+        set.add(ResourceTypeName.EVIDENCE_VARIABLE);
+        return set;
+    }
+}
diff --git a/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java b/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java
new file mode 100644
index 00000000000..62aebbb3fce
--- /dev/null
+++ b/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java
@@ -0,0 +1,60 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.ibm.fhir.core.util.test;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+import com.ibm.fhir.core.FHIRVersionParam;
+import com.ibm.fhir.core.util.ResourceTypeHelper;
+
+/**
+ * Tests for the ResourceTypeHelper class
+ */
+public class ResourceTypeHelperTest {
+    @Test
+    public void testGetNewOrBreakingResourceTypeNames() {
+        Set<String> newOrBreakingResourceTypeNames = ResourceTypeHelper.getNewOrBreakingResourceTypeNames();
+        assertEquals(newOrBreakingResourceTypeNames.size(), 16, "number of new or breaking resource types");
+    }
+
+    @Test(expectedExceptions = UnsupportedOperationException.class)
+    public void testGetNewOrBreakingResourceTypeNamesInvalidAddTo() {
+        Set<String> newOrBreakingResourceTypeNames = ResourceTypeHelper.getNewOrBreakingResourceTypeNames();
+        newOrBreakingResourceTypeNames.add("test");
+    }
+
+    @Test(expectedExceptions = UnsupportedOperationException.class)
+    public void testGetNewOrBreakingResourceTypeNamesInvalidRemove() {
+        Set<String> newOrBreakingResourceTypeNames = ResourceTypeHelper.getNewOrBreakingResourceTypeNames();
+        newOrBreakingResourceTypeNames.remove("Ingredient");
+    }
+
+    @Test
+    public void testGetResourceTypesFor() {
+        Set<String> r4Types = ResourceTypeHelper.getResourceTypesFor(FHIRVersionParam.VERSION_40);
+        assertEquals(r4Types.size(), 125, "number of r4 resource types");
+
+        Set<String> r4bTypes = ResourceTypeHelper.getResourceTypesFor(FHIRVersionParam.VERSION_43);
+        assertEquals(r4bTypes.size(), 141, "number of r4b resource types");
+    }
+
+    @Test(expectedExceptions = UnsupportedOperationException.class)
+    public void testInvalidAdd() {
+        Set<String> newOrBreakingResourceTypeNames = ResourceTypeHelper.getResourceTypesFor(FHIRVersionParam.VERSION_40);
+        newOrBreakingResourceTypeNames.add("test");
+    }
+
+    @Test(expectedExceptions = UnsupportedOperationException.class)
+    public void testInvalidRemove() {
+        Set<String> newOrBreakingResourceTypeNames = ResourceTypeHelper.getResourceTypesFor(FHIRVersionParam.VERSION_43);
+        newOrBreakingResourceTypeNames.remove("Ingredient");
+    }
+}
\ No newline at end of file
diff --git a/fhir-persistence/src/main/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtil.java b/fhir-persistence/src/main/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtil.java
index b0085418fe8..de76093e93f 100644
--- a/fhir-persistence/src/main/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtil.java
+++ b/fhir-persistence/src/main/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtil.java
@@ -11,17 +11,21 @@
 import java.time.format.DateTimeParseException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
 
 import org.owasp.encoder.Encode;
 
 import com.ibm.fhir.config.FHIRConfigHelper;
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.config.Interaction;
 import com.ibm.fhir.config.PropertyGroup;
+import com.ibm.fhir.config.ResourcesConfigAdapter;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.core.HTTPReturnPreference;
+import com.ibm.fhir.core.util.ResourceTypeHelper;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.resource.Resource;
 import com.ibm.fhir.model.resource.Resource.Builder;
@@ -29,6 +33,7 @@
 import com.ibm.fhir.model.type.Id;
 import com.ibm.fhir.model.type.Instant;
 import com.ibm.fhir.model.type.Meta;
+import com.ibm.fhir.model.type.code.FHIRVersion;
 import com.ibm.fhir.model.type.code.IssueType;
 import com.ibm.fhir.model.util.FHIRUtil;
 import com.ibm.fhir.model.util.ModelSupport;
@@ -43,10 +48,6 @@
 public class FHIRPersistenceUtil {
     private static final Logger log = Logger.getLogger(FHIRPersistenceUtil.class.getName());
 
-    private static final List<String> ALL_RESOURCE_TYPES = ModelSupport.getResourceTypes(false).stream()
-            .map(r -> ModelSupport.getTypeName(r))
-            .collect(Collectors.toList());
-
     private FHIRPersistenceUtil() {
         // No operation
     }
@@ -94,14 +95,26 @@ public static FHIRHistoryContext parseHistoryParameters(Map<String, List<String>
 
 
     /**
-     * Parse history parameters into a FHIRHistoryContext
+     * Parse history parameters into a FHIRHistoryContext with a fhirVersion of 4.3.0
+     *
+     * @see #parseSystemHistoryParameters(Map, boolean, FHIRVersion)
+     */
+    public static FHIRSystemHistoryContext parseSystemHistoryParameters(Map<String, List<String>> queryParameters, boolean lenient)
+            throws FHIRPersistenceException {
+        return parseSystemHistoryParameters(queryParameters, lenient, FHIRVersionParam.VERSION_43);
+    }
+
+    /**
+     * Parse history parameters into a FHIRHistoryContext for a given fhirVersion
      *
      * @param queryParameters
      * @param lenient
+     * @param fhirVersion
      * @return
      * @throws FHIRPersistenceException
      */
-    public static FHIRSystemHistoryContext parseSystemHistoryParameters(Map<String, List<String>> queryParameters, boolean lenient) throws FHIRPersistenceException {
+    public static FHIRSystemHistoryContext parseSystemHistoryParameters(Map<String, List<String>> queryParameters, boolean lenient,
+            FHIRVersionParam fhirVersion) throws FHIRPersistenceException {
         log.entering(FHIRPersistenceUtil.class.getName(), "parseSystemHistoryParameters");
         FHIRSystemHistoryContextImpl context = new FHIRSystemHistoryContextImpl();
         context.setLenient(lenient);
@@ -128,11 +141,17 @@ public static FHIRSystemHistoryContext parseSystemHistoryParameters(Map<String,
                                         .withIssue(FHIRUtil.buildOperationOutcomeIssue(msg, IssueType.INVALID));
                             }
                             // Note: if we decide to support invalid _type values in 'lenient' mode (like search), then the following
-                            // if/else will need to be in an else block for the preceding if
+                            // if/else block will need to be in an else block for the preceding if
                             if (!isHistoryEnabled(resourceType)) {
                                 String msg = "history interaction is not supported for _type parameter value: " + Encode.forHtml(resourceType);
                                 throw new FHIRPersistenceException(msg)
                                         .withIssue(FHIRUtil.buildOperationOutcomeIssue(msg, IssueType.NOT_SUPPORTED));
+                            } else if (fhirVersion == FHIRVersionParam.VERSION_40 &&
+                                    ResourceTypeHelper.getNewOrBreakingResourceTypeNames().contains(resourceType)) {
+                                String msg = "fhirVersion 4.0 interaction for _type parameter value: '" + resourceType +
+                                        "' is not supported";
+                                throw new FHIRPersistenceException(msg)
+                                    .withIssue(FHIRUtil.buildOperationOutcomeIssue(msg, IssueType.NOT_SUPPORTED));
                             } else {
                                 context.addResourceType(resourceType);
                             }
@@ -181,13 +200,11 @@ public static FHIRSystemHistoryContext parseSystemHistoryParameters(Map<String,
             if (context.getResourceTypes().isEmpty()) {
                 Boolean implicitTypeScoping = FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_WHOLE_SYSTEM_TYPE_SCOPING, true);
                 if (implicitTypeScoping) {
-                    Boolean isOpen = FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_RESOURCES + "/"
-                            + FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN, true);
-                    List<String> supportedResourceTypes = isOpen ? ALL_RESOURCE_TYPES : FHIRConfigHelper.getSupportedResourceTypes();
+                    PropertyGroup rsrcsGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
+                    ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(rsrcsGroup, fhirVersion);
+                    Set<String> supportedResourceTypes = configAdapter.getSupportedResourceTypes(Interaction.HISTORY);
                     for (String resType : supportedResourceTypes) {
-                        if (isHistoryEnabled(resType)) {
-                            context.addResourceType(resType);
-                        }
+                        context.addResourceType(resType);
                     }
                 }
             }
diff --git a/fhir-persistence/src/test/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtilTest.java b/fhir-persistence/src/test/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtilTest.java
index 26bf02d57aa..0f44147fe3a 100644
--- a/fhir-persistence/src/test/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtilTest.java
+++ b/fhir-persistence/src/test/java/com/ibm/fhir/persistence/util/FHIRPersistenceUtilTest.java
@@ -24,6 +24,7 @@
 
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.exception.FHIRException;
 import com.ibm.fhir.model.resource.Patient;
 import com.ibm.fhir.model.type.HumanName;
@@ -35,9 +36,8 @@
  */
 public class FHIRPersistenceUtilTest {
 
-    @BeforeClass(alwaysRun = true)
+    @BeforeClass
     public void setUp() throws Exception {
-        // Note: this assumes that the concrete test classes will be in a project that is peer to the fhir-persistence module
         // TODO: it would be better for our unit tests if we could load config files from the classpath
         FHIRConfiguration.setConfigHome("target/test-classes");
     }
@@ -161,6 +161,80 @@ public void testParseSystemHistoryParameters_explicitTypes() throws FHIRExceptio
         }
     }
 
+    /**
+     * Test the parsing of system history parameters into a HistoryContext
+     * with no implicit or explicit _type filter.
+     */
+    @Test
+    public void testParseSystemHistoryParameters_r4() throws FHIRException {
+        String originalTenantId = FHIRRequestContext.get().getTenantId();
+        try {
+            // change to a tenant (any tenant) that has `useImplicitTypeScopingForWholeSystemInteractions = false`
+            FHIRRequestContext.get().setTenantId("all");
+
+            // no explicit _type param
+            Map<String, List<String>> params = new HashMap<>();
+            FHIRSystemHistoryContext historyContext = FHIRPersistenceUtil.parseSystemHistoryParameters(params, false, FHIRVersionParam.VERSION_40);
+
+            assertTrue(historyContext.getResourceTypes().isEmpty(), historyContext.getResourceTypes().toString());
+        } finally {
+            FHIRRequestContext.get().setTenantId(originalTenantId);
+        }
+    }
+
+    /**
+     * Test the parsing of system history parameters into a HistoryContext
+     * with an implicit _type filter.
+     */
+    @Test
+    public void testParseSystemHistoryParameters_implicitTypes_r4() throws FHIRException {
+        String originalTenantId = FHIRRequestContext.get().getTenantId();
+        try {
+            // change to a tenant (any tenant) that has `useImplicitTypeScopingForWholeSystemInteractions = true`
+            FHIRRequestContext.get().setTenantId("default");
+
+            // no explicit _type param
+            Map<String, List<String>> params = new HashMap<>();
+            FHIRSystemHistoryContext historyContext = FHIRPersistenceUtil.parseSystemHistoryParameters(params, false, FHIRVersionParam.VERSION_40);
+
+            assertEquals(historyContext.getResourceTypes().size(), 125, "implicitly scoped to all R4 resource types");
+        } finally {
+            FHIRRequestContext.get().setTenantId(originalTenantId);
+        }
+    }
+
+    /**
+     * Test the parsing of system history parameters into a HistoryContext
+     * with an explicit _type filter.
+     */
+    @Test
+    public void testParseSystemHistoryParameters_explicitTypes_r4() throws FHIRException {
+        String originalTenantId = FHIRRequestContext.get().getTenantId();
+
+        // add a _type parameter value with a list of resource types
+        List<String> explicitTypes = Arrays.asList("Patient","Device","Observation","Condition","Medication");
+        Map<String, List<String>> params = new HashMap<>();
+        params.put("_type", Collections.singletonList(String.join(",",explicitTypes)));
+
+        try {
+            // change to a tenant (any tenant) that has `useImplicitTypeScopingForWholeSystemInteractions = true`
+            FHIRRequestContext.get().setTenantId("default");
+            FHIRSystemHistoryContext historyContext = FHIRPersistenceUtil.parseSystemHistoryParameters(params, false, FHIRVersionParam.VERSION_40);
+            assertEquals(historyContext.getResourceTypes(), explicitTypes);
+
+            // change to a tenant (any tenant) that has `useImplicitTypeScopingForWholeSystemInteractions = false`
+            FHIRRequestContext.get().setTenantId("all");
+            historyContext = FHIRPersistenceUtil.parseSystemHistoryParameters(params, false, FHIRVersionParam.VERSION_40);
+            assertEquals(historyContext.getResourceTypes(), explicitTypes);
+        } finally {
+            FHIRRequestContext.get().setTenantId(originalTenantId);
+        }
+    }
+
+    /**
+     * Test the parsing of system history parameters into a HistoryContext
+     * when multiple _type parameters are specified.
+     */
     @Test
     public void testParseSystemHistoryParameters_multipleTypeParam() throws FHIRException {
         String originalTenantId = FHIRRequestContext.get().getTenantId();
diff --git a/fhir-search/src/main/java/com/ibm/fhir/search/util/SearchUtil.java b/fhir-search/src/main/java/com/ibm/fhir/search/util/SearchUtil.java
index 147f6546925..62fa2ed3dad 100644
--- a/fhir-search/src/main/java/com/ibm/fhir/search/util/SearchUtil.java
+++ b/fhir-search/src/main/java/com/ibm/fhir/search/util/SearchUtil.java
@@ -34,9 +34,13 @@
 import com.ibm.fhir.config.FHIRConfigHelper;
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.config.Interaction;
 import com.ibm.fhir.config.PropertyGroup;
 import com.ibm.fhir.config.PropertyGroup.PropertyEntry;
+import com.ibm.fhir.config.ResourcesConfigAdapter;
 import com.ibm.fhir.core.FHIRConstants;
+import com.ibm.fhir.core.FHIRVersionParam;
+import com.ibm.fhir.core.util.ResourceTypeHelper;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.resource.CodeSystem;
 import com.ibm.fhir.model.resource.CodeSystem.Concept;
@@ -136,15 +140,9 @@ public class SearchUtil {
 
     private static final String IBM_COMPOSITE_PREFIX = "ibm_composite_";
 
-    private static final List<String> ALL_RESOURCE_TYPES = ModelSupport.getResourceTypes(false).stream()
-            .map(r -> ModelSupport.getTypeName(r))
-            .collect(Collectors.toList());
-
     // The functionality is split into a new class.
     private static final Sort sort = new Sort();
 
-
-
     private SearchUtil() {
         // No Operation
         // Hides the Initialization
@@ -374,11 +372,27 @@ public static Map<SearchParameter, List<FHIRPathNode>> extractParameterValues(Re
 
     public static FHIRSearchContext parseQueryParameters(Class<?> resourceType,
             Map<String, List<String>> queryParameters) throws Exception {
-        return parseQueryParameters(resourceType, queryParameters, false, true);
+        return parseQueryParameters(resourceType, queryParameters, false, true, FHIRVersionParam.VERSION_43);
     }
 
     public static FHIRSearchContext parseQueryParameters(Class<?> resourceType,
             Map<String, List<String>> queryParameters, boolean lenient, boolean includeResource) throws Exception {
+        return parseQueryParameters(resourceType, queryParameters, lenient, includeResource, FHIRVersionParam.VERSION_43);
+    }
+
+    /**
+     * Parse the passed query parameters into a FHIRSeachContext according to the given options
+     *
+     * @param resourceType
+     * @param queryParameters
+     * @param lenient
+     * @param includeResource
+     * @param fhirVersion
+     * @return
+     * @throws Exception
+     */
+    public static FHIRSearchContext parseQueryParameters(Class<?> resourceType, Map<String, List<String>> queryParameters,
+            boolean lenient, boolean includeResource, FHIRVersionParam fhirVersion) throws Exception {
 
         FHIRSearchContext context = FHIRSearchContextFactory.createSearchContext();
         context.setLenient(lenient);
@@ -419,6 +433,11 @@ public static FHIRSearchContext parseQueryParameters(Class<?> resourceType,
                         if (!isSearchEnabled(resType)) {
                             manageException("search interaction is not supported for _type parameter value: " + Encode.forHtml(resType),
                                     IssueType.NOT_SUPPORTED, context, false);
+                        } else if (fhirVersion == FHIRVersionParam.VERSION_40 &&
+                                ResourceTypeHelper.getNewOrBreakingResourceTypeNames().contains(resType)) {
+                            String msg = "fhirVersion 4.0 interaction for _type parameter value: '" + resType +
+                                    "' is not supported";
+                            manageException(msg, IssueType.NOT_SUPPORTED, context, false);
                         } else {
                             resourceTypes.add(resType);
                         }
@@ -429,14 +448,9 @@ public static FHIRSearchContext parseQueryParameters(Class<?> resourceType,
             if (resourceTypes.isEmpty()) {
                 Boolean implicitTypeScoping = FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_WHOLE_SYSTEM_TYPE_SCOPING, true);
                 if (implicitTypeScoping) {
-                    Boolean isOpen = FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_RESOURCES + "/"
-                            + FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN, true);
-                    List<String> supportedResourceTypes = isOpen ? ALL_RESOURCE_TYPES : FHIRConfigHelper.getSupportedResourceTypes();
-                    for (String resType : supportedResourceTypes) {
-                        if (isSearchEnabled(resType)) {
-                            resourceTypes.add(resType);
-                        }
-                    }
+                    PropertyGroup rsrcsGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
+                    ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(rsrcsGroup, fhirVersion);
+                    resourceTypes.addAll(configAdapter.getSupportedResourceTypes(Interaction.SEARCH));
                 }
             }
         }
@@ -1234,11 +1248,12 @@ public static Map<String, SearchParameter> getSearchParameters(String resourceTy
      * @param queryParameters the query parameters
      * @param interaction read or vread
      * @param lenient true if lenient, false if strict
+     * @param fhirVersion
      * @return the FHIR search context
      * @throws Exception an exception
      */
     public static FHIRSearchContext parseReadQueryParameters(Class<?> resourceType,
-            Map<String, List<String>> queryParameters, String interaction, boolean lenient) throws Exception {
+            Map<String, List<String>> queryParameters, String interaction, boolean lenient, FHIRVersionParam fhirVersion) throws Exception {
         String resourceTypeName = resourceType.getSimpleName();
 
         // Read and vRead only allow general search parameters
@@ -1252,25 +1267,18 @@ public static FHIRSearchContext parseReadQueryParameters(Class<?> resourceType,
             log.log(Level.FINE, "Error while parsing search parameter '" + nonGeneralParam + "' for resource type " + resourceTypeName, se);
         }
 
-        return parseCompartmentQueryParameters(null, null, resourceType, queryParameters, lenient, true);
+        return parseCompartmentQueryParameters(null, null, resourceType, queryParameters, lenient, true, fhirVersion);
     }
 
 
     public static FHIRSearchContext parseCompartmentQueryParameters(String compartmentName, String compartmentLogicalId,
             Class<?> resourceType, Map<String, List<String>> queryParameters) throws Exception {
-        return parseCompartmentQueryParameters(compartmentName, compartmentLogicalId, resourceType, queryParameters, true, true);
+        return parseCompartmentQueryParameters(compartmentName, compartmentLogicalId, resourceType, queryParameters, true, true, FHIRVersionParam.VERSION_43);
     }
 
-    /**
-     * Check the configuration to see if the flag enabling the compartment search
-     * optimization. Defaults to false so the behavior won't change unless it
-     * is explicitly enabled in fhir-server-config. This is important, because
-     * existing data must be reindexed (see $reindex custom operation) to
-     * generate values for the ibm-internal compartment relationship params.
-     * @return
-     */
-    public static boolean useStoredCompartmentParam() {
-        return FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_USE_STORED_COMPARTMENT_PARAM, true);
+    public static FHIRSearchContext parseCompartmentQueryParameters(String compartmentName, String compartmentLogicalId,
+            Class<?> resourceType, Map<String, List<String>> queryParameters, FHIRVersionParam fhirVersion) throws Exception {
+        return parseCompartmentQueryParameters(compartmentName, compartmentLogicalId, resourceType, queryParameters, true, true, fhirVersion);
     }
 
     /**
@@ -1282,15 +1290,17 @@ public static boolean useStoredCompartmentParam() {
      *                Whether to ignore unknown or unsupported parameter
      * @param includeResource
      *                Whether to include the resource from the result (return handling prefer != minimal)
+     * @param fhirVersion
      * @return
      * @throws Exception
      */
     public static FHIRSearchContext parseCompartmentQueryParameters(String compartmentName, String compartmentLogicalId,
-            Class<?> resourceType, Map<String, List<String>> queryParameters, boolean lenient, boolean includeResource) throws Exception {
+            Class<?> resourceType, Map<String, List<String>> queryParameters, boolean lenient, boolean includeResource,
+            FHIRVersionParam fhirVersion) throws Exception {
 
         Set<String> compartmentLogicalIds = Collections.singleton(compartmentLogicalId);
         QueryParameter inclusionCriteria = buildInclusionCriteria(compartmentName, compartmentLogicalIds, resourceType.getSimpleName());
-        FHIRSearchContext context = parseQueryParameters(resourceType, queryParameters, lenient, includeResource);
+        FHIRSearchContext context = parseQueryParameters(resourceType, queryParameters, lenient, includeResource, fhirVersion);
 
         // Add the inclusion criteria to the front of the search parameter list
         if (inclusionCriteria != null) {
@@ -1352,6 +1362,15 @@ public static QueryParameter buildInclusionCriteria(String compartmentName, Set<
         return rootParameter;
     }
 
+    /**
+     * Check the configuration to see if the compartment search optimization is enabled.
+     * The config property defaults to true and may be removed in a near-future release.
+     * @return
+     */
+    public static boolean useStoredCompartmentParam() {
+        return FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_USE_STORED_COMPARTMENT_PARAM, true);
+    }
+
     private static SearchConstants.Prefix getPrefix(String s) throws FHIRSearchException {
 
         SearchConstants.Prefix returnPrefix = null;
diff --git a/fhir-search/src/test/java/com/ibm/fhir/search/test/CompartmentParseQueryParmsTest.java b/fhir-search/src/test/java/com/ibm/fhir/search/test/CompartmentParseQueryParmsTest.java
index ee6ac6d3275..6f5f0ed713e 100644
--- a/fhir-search/src/test/java/com/ibm/fhir/search/test/CompartmentParseQueryParmsTest.java
+++ b/fhir-search/src/test/java/com/ibm/fhir/search/test/CompartmentParseQueryParmsTest.java
@@ -24,6 +24,7 @@
 import org.testng.annotations.Test;
 
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.model.resource.CommunicationRequest;
 import com.ibm.fhir.model.resource.Condition;
 import com.ibm.fhir.model.resource.Device;
@@ -230,7 +231,7 @@ public void testCompartmentWithFakeQueryParm(boolean useStoredCompartmentParam)
         assertFalse(selfUri.contains(queryString), selfUri + " contain unexpectedExceptions query parameter 'fakeParameter'");
 
         try {
-            SearchUtil.parseCompartmentQueryParameters(compartmentName, compartmentLogicalId, resourceType, queryParameters, false, true);
+            SearchUtil.parseCompartmentQueryParameters(compartmentName, compartmentLogicalId, resourceType, queryParameters, false, true, FHIRVersionParam.VERSION_43);
             fail("expectedExceptions parseQueryParameters to throw due to strict mode but it didn't.");
         } catch (Exception e) {
             assertTrue(e instanceof FHIRSearchException);
diff --git a/fhir-server-spi/src/main/java/com/ibm/fhir/server/spi/operation/FHIROperationContext.java b/fhir-server-spi/src/main/java/com/ibm/fhir/server/spi/operation/FHIROperationContext.java
index fe77fa78dd3..96cab5f1c29 100644
--- a/fhir-server-spi/src/main/java/com/ibm/fhir/server/spi/operation/FHIROperationContext.java
+++ b/fhir-server-spi/src/main/java/com/ibm/fhir/server/spi/operation/FHIROperationContext.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2017, 2021
+ * (C) Copyright IBM Corp. 2017, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -84,6 +84,11 @@ public enum Type { SYSTEM, RESOURCE_TYPE, INSTANCE }
      */
     public static final String PROPNAME_RESPONSE_PARAMETERS = "RESPONSE_PARAMETERS";
 
+    /**
+     * The FHIRVersionParam for this invocation
+     */
+    public static final String PROPNAME_FHIR_VERSION = "FHIR_VERSION";
+
     private final Type type;
     private final String code;
     private Map<String, Object> properties = null;
diff --git a/fhir-server-test/src/test/java/com/ibm/fhir/server/test/CapabilitiesVersionTest.java b/fhir-server-test/src/test/java/com/ibm/fhir/server/test/CapabilitiesVersionTest.java
new file mode 100644
index 00000000000..85ebcf6e9ed
--- /dev/null
+++ b/fhir-server-test/src/test/java/com/ibm/fhir/server/test/CapabilitiesVersionTest.java
@@ -0,0 +1,113 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.ibm.fhir.server.test;
+
+import static com.ibm.fhir.core.FHIRMediaType.FHIR_VERSION_PARAMETER;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+import static org.testng.AssertJUnit.assertNotNull;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.ibm.fhir.core.FHIRMediaType;
+import com.ibm.fhir.model.resource.CapabilityStatement;
+import com.ibm.fhir.model.resource.CapabilityStatement.Rest;
+import com.ibm.fhir.model.resource.CapabilityStatement.Rest.Resource;
+import com.ibm.fhir.model.type.code.FHIRVersion;
+import com.ibm.fhir.model.type.code.ResourceType;
+import com.ibm.fhir.path.exception.FHIRPathException;
+import com.ibm.fhir.validation.exception.FHIRValidationException;
+
+public class CapabilitiesVersionTest extends FHIRServerTestBase {
+    private static final Set<ResourceType.Value> R4B_ONLY_RESOURCES = new HashSet<>();
+    {
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.ADMINISTRABLE_PRODUCT_DEFINITION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.CITATION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.CLINICAL_USE_DEFINITION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.EVIDENCE_REPORT);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.INGREDIENT);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.MANUFACTURED_ITEM_DEFINITION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.MEDICINAL_PRODUCT_DEFINITION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.NUTRITION_PRODUCT);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.PACKAGED_PRODUCT_DEFINITION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.REGULATED_AUTHORIZATION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.SUBSCRIPTION_STATUS);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.SUBSCRIPTION_TOPIC);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.SUBSTANCE_DEFINITION);
+        // The following resource types existed in R4, but have breaking changes in R4B.
+        // Because we only support the R4B version, we don't want to advertise these in our 4.0.1 statement.
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.DEVICE_DEFINITION);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.EVIDENCE);
+        R4B_ONLY_RESOURCES.add(ResourceType.Value.EVIDENCE_VARIABLE);
+    }
+
+    /**
+     * Verify the 'metadata' API.
+     */
+    @Test(dataProvider = "dataMethod")
+    public void testWithTenantAndFHIRVersion(String tenant, String requestFhirVersion, FHIRVersion expectedVersion) throws FHIRPathException, FHIRValidationException {
+        WebTarget target = getWebTarget();
+        Map<String,String> fhirVersionParameterMap = (requestFhirVersion == null) ? null : Collections.singletonMap(FHIR_VERSION_PARAMETER, requestFhirVersion);
+        MediaType mediaType = new MediaType("application", FHIRMediaType.SUBTYPE_FHIR_JSON, fhirVersionParameterMap);
+
+        Response response = target.path("metadata")
+                .request(mediaType)
+                .header("X-FHIR-TENANT-ID", tenant)
+                .get();
+        assertResponse(response, Response.Status.OK.getStatusCode());
+
+        CapabilityStatement conf = response.readEntity(CapabilityStatement.class);
+        assertNotNull(conf);
+        assertEquals(conf.getFhirVersion(), expectedVersion);
+
+        switch (conf.getFhirVersion().getValueAsEnum()) {
+        case VERSION_4_0_1:
+            // verify it has no "R4B-only" resource types
+            for (Rest rest : conf.getRest()) {
+                for (Resource resource : rest.getResource()) {
+                    assertFalse(R4B_ONLY_RESOURCES.contains(resource.getType().getValueAsEnum()),
+                            "unexpected resource type: " + resource.getType().getValue());
+                }
+            }
+            break;
+        case VERSION_4_3_0_CIBUILD:
+            // nothing to verify at the moment
+            break;
+        default:
+            fail("unexpected fhirVersion: " + conf.getFhirVersion().getValue());
+        }
+    }
+
+    /**
+     * tenant, requestedVersion, expectedVersion
+     */
+    @DataProvider
+    public static Object[][] dataMethod() {
+        return new Object[][] {
+            { "default", null, FHIRVersion.VERSION_4_0_1 },
+            { "default", "4.0", FHIRVersion.VERSION_4_0_1 },
+            { "default", "4.3", FHIRVersion.VERSION_4_3_0_CIBUILD },
+            { "tenant1", null, FHIRVersion.VERSION_4_3_0_CIBUILD },
+            { "tenant1", "4.0", FHIRVersion.VERSION_4_0_1 },
+            { "tenant1", "4.3", FHIRVersion.VERSION_4_3_0_CIBUILD },
+            { "tenant2", null, FHIRVersion.VERSION_4_0_1 },
+            { "tenant2", "4.0", FHIRVersion.VERSION_4_0_1 },
+            { "tenant2", "4.3", FHIRVersion.VERSION_4_3_0_CIBUILD }
+        };
+    }
+}
diff --git a/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/ReindexOperationTest.java b/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/ReindexOperationTest.java
index acea6a39359..f12d6e45d3e 100644
--- a/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/ReindexOperationTest.java
+++ b/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/ReindexOperationTest.java
@@ -142,7 +142,7 @@ public void testReindexWithInvalidType() {
                 .header("X-FHIR-DSID", "default")
                 .post(entity, Response.class);
 
-        assertEquals(r.getStatus(), Status.BAD_REQUEST.getStatusCode());
+        assertEquals(r.getStatus(), Status.NOT_FOUND.getStatusCode());
     }
 
     @Test(groups = { "reindex" })
diff --git a/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/RetrieveIndexOperationTest.java b/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/RetrieveIndexOperationTest.java
index 23852149517..45645d48111 100644
--- a/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/RetrieveIndexOperationTest.java
+++ b/fhir-server-test/src/test/java/com/ibm/fhir/server/test/operation/RetrieveIndexOperationTest.java
@@ -156,6 +156,6 @@ public void testRetrieveIndex_invalidType() {
                 .header("X-FHIR-DSID", "default")
                 .post(entity, Response.class);
 
-        assertEquals(r.getStatus(), Status.BAD_REQUEST.getStatusCode());
+        assertEquals(r.getStatus(), Status.NOT_FOUND.getStatusCode());
     }
 }
\ No newline at end of file
diff --git a/fhir-server-webapp/src/main/liberty/config/config/default/fhir-server-config.json b/fhir-server-webapp/src/main/liberty/config/config/default/fhir-server-config.json
index e08fe80beeb..ee8777b8548 100644
--- a/fhir-server-webapp/src/main/liberty/config/config/default/fhir-server-config.json
+++ b/fhir-server-webapp/src/main/liberty/config/config/default/fhir-server-config.json
@@ -8,7 +8,8 @@
             "checkReferenceTypes": true,
             "conditionalDeleteMaxNumber": 10,
             "serverRegistryResourceProviderEnabled": true,
-            "disabledOperations": ""
+            "disabledOperations": "",
+            "defaultFhirVersion": "4.0"
         },
         "search": {
             "useStoredCompartmentParam": true
diff --git a/fhir-server-webapp/src/test/liberty/config/config/tenant1/fhir-server-config.json b/fhir-server-webapp/src/test/liberty/config/config/tenant1/fhir-server-config.json
index 62302ae75ee..f8c4bfdaf71 100644
--- a/fhir-server-webapp/src/test/liberty/config/config/tenant1/fhir-server-config.json
+++ b/fhir-server-webapp/src/test/liberty/config/config/tenant1/fhir-server-config.json
@@ -39,7 +39,8 @@
           "defaultPageSize": 11,
           "maxPageSize": 1001,
           "maxPageIncludeCount": 1000,
-          "externalBaseUrl": "https://chocolate.fudge"
+          "externalBaseUrl": "https://chocolate.fudge",
+          "defaultFhirVersion": "4.3"
         },
         "persistence": {
             "datasources": {
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/FHIRApplication.java b/fhir-server/src/main/java/com/ibm/fhir/server/FHIRApplication.java
index 0573243e6ab..5f507d737f3 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/FHIRApplication.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/FHIRApplication.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2020
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -30,6 +30,7 @@
 import com.ibm.fhir.server.resources.Update;
 import com.ibm.fhir.server.resources.VRead;
 import com.ibm.fhir.server.resources.WellKnown;
+import com.ibm.fhir.server.resources.filters.FHIRVersionRequestFilter;
 import com.ibm.fhir.server.resources.filters.OriginalRequestFilter;
 
 public class FHIRApplication extends Application {
@@ -64,6 +65,7 @@ public Set<Class<?>> getClasses() {
                 classes.add(Search.class);
                 classes.add(Update.class);
                 classes.add(VRead.class);
+                classes.add(FHIRVersionRequestFilter.class);
                 classes.add(OriginalRequestFilter.class);
                 if (FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_SECURITY_OAUTH_SMART_ENABLED, false)) {
                     classes.add(WellKnown.class);
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/filter/rest/FHIRRestServletFilter.java b/fhir-server/src/main/java/com/ibm/fhir/server/filter/rest/FHIRRestServletFilter.java
index 205b0aca4b3..fbc010d559d 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/filter/rest/FHIRRestServletFilter.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/filter/rest/FHIRRestServletFilter.java
@@ -275,7 +275,7 @@ private void computeReturnPref(FHIRRequestContext context, ServletRequest reques
             try {
                 returnPref = HTTPReturnPreference.from(returnPrefString);
                 isDefault = false;
-                
+
                 if (log.isLoggable(Level.FINE)) {
                     log.fine("Requested return preference = " + returnPref);
                 }
@@ -288,7 +288,7 @@ private void computeReturnPref(FHIRRequestContext context, ServletRequest reques
                 }
             }
         }
-        
+
         context.setReturnPreference(returnPref);
         context.setReturnPreferenceDefault(isDefault);
     }
@@ -315,7 +315,7 @@ void checkFhirVersionParameter(Map<String, List<String>> requestHeaders) throws
                             if (curFhirVersion != null && !FHIRMediaType.SUPPORTED_FHIR_VERSIONS.contains(curFhirVersion)) {
                                 throw new FHIRRestServletRequestException("Invalid '" + FHIRMediaType.FHIR_VERSION_PARAMETER
                                     + "' parameter value in '" + headerName + "' header; the following FHIR versions are supported: "
-                                        + FHIRMediaType.SUPPORTED_FHIR_VERSIONS, headerStatusMap.get(headerName));
+                                        + FHIRMediaType.ADVERTISED_FHIR_VERSIONS, headerStatusMap.get(headerName));
                             }
                             // If Content-Type header, check for multiple different FHIR versions
                             if (headerName.equals(HttpHeaders.CONTENT_TYPE)) {
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Batch.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Batch.java
index 7009f6b491c..0bedc290930 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Batch.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Batch.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -28,7 +28,6 @@
 
 import com.ibm.fhir.config.FHIRRequestContext;
 import com.ibm.fhir.core.FHIRConstants;
-
 import com.ibm.fhir.core.FHIRMediaType;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.resource.Bundle;
@@ -86,7 +85,7 @@ public Response bundle(Resource resource, @HeaderParam(FHIRConstants.UPDATE_IF_M
                 throw buildRestException(msg, IssueType.INVALID);
             }
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             responseBundle = helper.doBundle(inputBundle, updateOnlyIfModified);
             status = Status.OK;
             return Response.ok(responseBundle).build();
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Capabilities.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Capabilities.java
index 9cff50b6c57..8c9871027cc 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Capabilities.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Capabilities.java
@@ -38,16 +38,13 @@
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
 
-import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
-import javax.ws.rs.HeaderParam;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.CacheControl;
-import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
@@ -56,7 +53,10 @@
 import com.ibm.fhir.config.FHIRConfigHelper;
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.PropertyGroup;
+import com.ibm.fhir.config.ResourcesConfigAdapter;
 import com.ibm.fhir.core.FHIRMediaType;
+import com.ibm.fhir.core.FHIRVersionParam;
+import com.ibm.fhir.core.ResourceTypeName;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.format.Format;
 import com.ibm.fhir.model.resource.CapabilityStatement;
@@ -120,9 +120,6 @@ public class Capabilities extends FHIRResource {
     private static final String BASE_CAPABILITY_URL = "http://hl7.org/fhir/CapabilityStatement/base";
     private static final String BASE_2_CAPABILITY_URL = "http://hl7.org/fhir/CapabilityStatement/base2";
     private static final List<String> ALL_INTERACTIONS = Arrays.asList("create", "read", "vread", "update", "patch", "delete", "history", "search");
-    private static final List<ResourceType.Value> ALL_RESOURCE_TYPES = ModelSupport.getResourceTypes(false).stream()
-            .map(rt -> ResourceType.Value.from(rt.getSimpleName()))
-            .collect(Collectors.toList());
 
     private static final Set<ResourceType.Value> R4B_ONLY_RESOURCES = new HashSet<>();
     {
@@ -144,9 +141,6 @@ public class Capabilities extends FHIRResource {
         R4B_ONLY_RESOURCES.add(ResourceType.Value.DEVICE_DEFINITION);
         R4B_ONLY_RESOURCES.add(ResourceType.Value.EVIDENCE);
         R4B_ONLY_RESOURCES.add(ResourceType.Value.EVIDENCE_VARIABLE);
-        // TODO: make final decision on whether to lump these in with the breaking resources
-        // R4B_ONLY_RESOURCES.add(ResourceType.Value.PLAN_DEFINITION);
-        // R4B_ONLY_RESOURCES.add(ResourceType.Value.ACTIVITY_DEFINITION);
     }
 
     // Error Messages
@@ -155,9 +149,6 @@ public class Capabilities extends FHIRResource {
 
     private static final String CAPABILITY_STATEMENT_CACHE_NAME = "com.ibm.fhir.server.resources.Capabilities.statementCache";
 
-    @Context
-    protected HttpServletRequest httpServletRequest;
-
     // Constructor
     public Capabilities() throws Exception {
         super();
@@ -165,7 +156,7 @@ public Capabilities() throws Exception {
 
     @GET
     @Path("metadata")
-    public Response capabilities(@QueryParam("mode") @DefaultValue("full") String mode, @HeaderParam("accept") String accept) {
+    public Response capabilities(@QueryParam("mode") @DefaultValue("full") String mode) {
         log.entering(this.getClass().getName(), "capabilities()");
         try {
             Date startTime = new Date();
@@ -175,8 +166,6 @@ public Response capabilities(@QueryParam("mode") @DefaultValue("full") String mo
                 throw new IllegalArgumentException("Invalid mode parameter: must be one of [full, normative, terminology]");
             }
 
-            FHIRVersion fhirVersion = getFhirVersion(accept);
-
             // Defaults to 60 minutes (or what's in the fhirConfig)
             int cacheTimeout = FHIRConfigHelper.getIntProperty(PROPERTY_CAPABILITY_STATEMENT_CACHE, 60);
             Configuration configuration = Configuration.of(Duration.of(cacheTimeout, ChronoUnit.MINUTES));
@@ -184,7 +173,8 @@ public Response capabilities(@QueryParam("mode") @DefaultValue("full") String mo
             Map<String, Resource> cacheAsMap = CacheManager.getCacheAsMap(CAPABILITY_STATEMENT_CACHE_NAME, configuration);
             CacheManager.reportCacheStats(log, CAPABILITY_STATEMENT_CACHE_NAME);
 
-            String cacheKey = mode + "-" + fhirVersion.getValue();
+            FHIRVersionParam fhirVersion = getFhirVersion();
+            String cacheKey = mode + "-" + fhirVersion.value();
             Resource capabilityStatement = cacheAsMap.computeIfAbsent(cacheKey, k -> computeCapabilityStatement(mode, fhirVersion));
 
             RestAuditLogger.logMetadata(httpServletRequest, startTime, new Date(), Response.Status.OK);
@@ -211,30 +201,11 @@ public Response capabilities(@QueryParam("mode") @DefaultValue("full") String mo
         }
     }
 
-    /**
-     * Which FHIRVersion to use for the generated CapabilityStatement
-     *
-     * @param acceptHeaderValue
-     * @return 4.3.0 if the client is asking for it, otherwise 4.0.1
-     */
-    private FHIRVersion getFhirVersion(String acceptHeaderValue) {
-        if (acceptHeaderValue != null && !acceptHeaderValue.isEmpty()) {
-            for (String headerValueElement : acceptHeaderValue.split(",")) {
-                String requestedVersion = MediaType.valueOf(headerValueElement).getParameters().get(FHIRMediaType.FHIR_VERSION_PARAMETER);
-                if ("4.3".equals(requestedVersion) || "4.3.0".equals(requestedVersion)) {
-                    // TODO: remove _CIBUILD after generating from the published 4.3.0 artifacts
-                    return FHIRVersion.VERSION_4_3_0_CIBUILD;
-                }
-            }
-        }
-        return FHIRVersion.VERSION_4_0_1;
-    }
-
     private boolean isValidMode(String mode) {
         return "full".equals(mode) || "normative".equals(mode) || "terminology".equals(mode);
     }
 
-    private Resource computeCapabilityStatement(String mode, FHIRVersion fhirVersion) {
+    private Resource computeCapabilityStatement(String mode, FHIRVersionParam fhirVersion) {
         try {
             switch (mode) {
             case "terminology":
@@ -340,7 +311,7 @@ private List<TerminologyCapabilities.CodeSystem> buildCodeSystem() {
      *
      * @throws Exception
      */
-    private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) throws Exception {
+    private CapabilityStatement buildCapabilityStatement(FHIRVersionParam fhirVersion) throws Exception {
         // Retrieve the "resources" config property group.
         PropertyGroup rsrcsGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
 
@@ -371,7 +342,7 @@ private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) th
 
         // Build the lists of operations that are supported
         Set<OperationDefinition> systemOps = new LinkedHashSet<>();
-        Map<ResourceType.Value, Set<OperationDefinition>> typeOps = new HashMap<>();
+        Map<String, Set<OperationDefinition>> typeOps = new HashMap<>();
 
         FHIROperationRegistry opRegistry = FHIROperationRegistry.getInstance();
         List<String> operationNames = opRegistry.getOperationNames();
@@ -382,13 +353,13 @@ private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) th
                 systemOps.add(opDef);
             }
             for (ResourceType resourceType : opDef.getResource()) {
-                ResourceType.Value typeValue = resourceType.getValueAsEnum();
-                if (typeOps.containsKey(typeValue)) {
-                    typeOps.get(typeValue).add(opDef);
+                String resourceTypeName = resourceType.getValue();
+                if (typeOps.containsKey(resourceTypeName)) {
+                    typeOps.get(resourceTypeName).add(opDef);
                 } else {
                     Set<OperationDefinition> typeOpList = new LinkedHashSet<>();
                     typeOpList.add(opDef);
-                    typeOps.put(typeValue, typeOpList);
+                    typeOps.put(resourceTypeName, typeOpList);
                 }
             }
         }
@@ -398,11 +369,10 @@ private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) th
         // Build the list of supported resources.
         List<Rest.Resource> resources = new ArrayList<>();
 
-        List<ResourceType.Value> resourceTypes = getSupportedResourceTypes(rsrcsGroup, fhirVersion);
-
-        for (ResourceType.Value resourceType : resourceTypes) {
-            String resourceTypeName = resourceType.value();
+        ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(rsrcsGroup, fhirVersion);
+        Set<String> resourceTypeNames = configAdapter.getSupportedResourceTypes();
 
+        for (String resourceTypeName : resourceTypeNames) {
             // Build the set of ConformanceSearchParams for this resource type.
             List<Rest.Resource.SearchParam> conformanceSearchParams = new ArrayList<>();
             Map<String, SearchParameter> searchParameters = SearchUtil.getSearchParameters(resourceTypeName);
@@ -423,12 +393,12 @@ private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) th
                 conformanceSearchParams.add(conformanceSearchParam);
             }
 
-            List<Operation> ops = mapOperationDefinitionsToRestOperations(typeOps.get(resourceType));
+            List<Operation> ops = mapOperationDefinitionsToRestOperations(typeOps.get(resourceTypeName));
             // If the type is an abstract resource ("Resource" or "DomainResource")
             // then the operation can be invoked on any concrete specialization.
-            ops.addAll(mapOperationDefinitionsToRestOperations(typeOps.get(ResourceType.Value.RESOURCE)));
+            ops.addAll(mapOperationDefinitionsToRestOperations(typeOps.get(ResourceTypeName.RESOURCE.value())));
             if (DomainResource.class.isAssignableFrom(ModelSupport.getResourceType(resourceTypeName))) {
-                ops.addAll(mapOperationDefinitionsToRestOperations(typeOps.get(ResourceType.Value.DOMAIN_RESOURCE)));
+                ops.addAll(mapOperationDefinitionsToRestOperations(typeOps.get(ResourceTypeName.DOMAIN_RESOURCE.value())));
             }
 
             // Build the list of interactions, searchIncludes, and searchRevIncludes supported for the resource type.
@@ -457,7 +427,7 @@ private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) th
 
             // Build the ConformanceResource for this resource type.
             Rest.Resource.Builder crb = Rest.Resource.builder()
-                    .type(ResourceType.of(resourceType))
+                    .type(ResourceType.of(resourceTypeName))
                     .profile(Canonical.of("http://hl7.org/fhir/profiles/" + resourceTypeName))
                     .interaction(interactions)
                     .operation(ops)
@@ -576,7 +546,7 @@ private CapabilityStatement buildCapabilityStatement(FHIRVersion fhirVersion) th
                 .status(PublicationStatus.ACTIVE)
                 .date(DateTime.now(ZoneOffset.UTC))
                 .kind(CapabilityStatementKind.INSTANCE)
-                .fhirVersion(fhirVersion)
+                .fhirVersion(fhirVersion == FHIRVersionParam.VERSION_43 ? FHIRVersion.VERSION_4_3_0_CIBUILD : FHIRVersion.VERSION_4_0_1)
                 .format(format)
                 .patchFormat(Code.of(FHIRMediaType.APPLICATION_JSON_PATCH),
                              Code.of(FHIRMediaType.APPLICATION_FHIR_JSON),
@@ -677,32 +647,6 @@ private List<com.ibm.fhir.model.type.String> convertStringList(List<String> stri
         return null;
     }
 
-    /**
-     * @param rsrcsGroup the "resources" propertyGroup from the server configuration
-     * @return a list of resource types to support
-     * @throws Exception
-     */
-    private List<ResourceType.Value> getSupportedResourceTypes(PropertyGroup rsrcsGroup, FHIRVersion fhirVersion) throws Exception {
-        final List<ResourceType.Value> resourceTypes = new ArrayList<>();
-
-        if (rsrcsGroup == null) {
-            resourceTypes.addAll(ALL_RESOURCE_TYPES);
-        } else {
-            if (rsrcsGroup.getBooleanProperty(FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN, true)) {
-                resourceTypes.addAll(ALL_RESOURCE_TYPES);
-            } else {
-                resourceTypes.addAll(FHIRConfigHelper.getSupportedResourceTypes().stream()
-                    .map(ResourceType.Value::from)
-                    .collect(Collectors.toList()));
-            }
-        }
-
-        if (fhirVersion.getValueAsEnum() == FHIRVersion.Value.VERSION_4_0_1) {
-            resourceTypes.removeAll(R4B_ONLY_RESOURCES);
-        }
-        return resourceTypes;
-    }
-
     /**
      * Builds the list of canonicals for the instantiates field based on the capability statements (except FHIR core)
      * found in the FHIR registry.
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Create.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Create.java
index d3a0926f3f5..9e395fb32af 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Create.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Create.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -71,7 +71,7 @@ public Response create(@PathParam("type") String type, Resource resource, @Heade
             checkInitComplete();
             checkType(type);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doCreate(type, resource, ifNoneExist);
 
             ResponseBuilder response =
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Delete.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Delete.java
index 3ce027bb9ef..37abda71559 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Delete.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Delete.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -58,7 +58,7 @@ public Response delete(@PathParam("type") String type, @PathParam("id") String i
             checkInitComplete();
             checkType(type);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doDelete(type, id, null);
             status = ior.getStatus();
             return buildResponse(ior);
@@ -103,7 +103,7 @@ public Response conditionalDelete(@PathParam("type") String type) throws Excepti
                 throw buildRestException(msg, IssueType.INVALID);
             }
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doDelete(type, null, searchQueryString);
             status = ior.getStatus();
             return buildResponse(ior);
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/FHIRResource.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/FHIRResource.java
index 9ab811194e0..290fb32f338 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/FHIRResource.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/FHIRResource.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -42,6 +42,7 @@
 import com.ibm.fhir.config.FHIRRequestContext;
 import com.ibm.fhir.config.PropertyGroup;
 import com.ibm.fhir.core.FHIRConstants;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.format.Format;
 import com.ibm.fhir.model.generator.FHIRGenerator;
@@ -62,6 +63,7 @@
 import com.ibm.fhir.persistence.helper.PersistenceHelper;
 import com.ibm.fhir.server.exception.FHIRRestBundledRequestException;
 import com.ibm.fhir.server.listener.FHIRServletContextListener;
+import com.ibm.fhir.server.resources.filters.FHIRVersionRequestFilter;
 
 import net.jcip.annotations.NotThreadSafe;
 
@@ -127,11 +129,8 @@ protected void checkInitComplete() throws FHIROperationException {
      * we'll throw an error to short-circuit the current in-progress REST API invocation.
      */
     protected void checkType(String type) throws FHIROperationException {
-        if (!ModelSupport.isResourceType(type)) {
-            throw buildUnsupportedResourceTypeException(type);
-        }
         if (!ModelSupport.isConcreteResourceType(type)) {
-            log.warning("Use of abstract resource types like '" + type + "' in FHIR URLs is deprecated and will be removed in a future release");
+            throw buildUnsupportedResourceTypeException(type);
         }
     }
 
@@ -502,4 +501,18 @@ protected FHIROperationException buildUnsupportedResourceTypeException(String re
                 .build();
         return new FHIROperationException(msg).withIssue(issue);
     }
+
+    /**
+     * The FHIRVersion to use for the current request
+     *
+     * @return the corresponding FHIRVersion for the com.ibm.fhir.server.fhirVersion request context attribute
+     */
+    protected FHIRVersionParam getFhirVersion() {
+        FHIRVersionParam fhirVersion = (FHIRVersionParam) httpServletRequest.getAttribute(FHIRVersionRequestFilter.FHIR_VERSION_PROP);
+        if (fhirVersion == null) {
+            log.warning("Missing request context attribute " + FHIRVersionRequestFilter.FHIR_VERSION_PROP + "; using 4.0");
+            fhirVersion = FHIRVersionParam.VERSION_40;
+        }
+        return fhirVersion;
+    }
 }
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/History.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/History.java
index 4324e7861e1..752687c8193 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/History.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/History.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -55,7 +55,7 @@ public Response history(@PathParam("type") String type, @PathParam("id") String
             checkInitComplete();
             checkType(type);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             bundle = helper.doHistory(type, id, uriInfo.getQueryParameters(), getRequestUri());
             status = Status.OK;
             return Response.status(status).entity(bundle).build();
@@ -88,7 +88,7 @@ public Response systemHistory() {
         try {
             checkInitComplete();
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             bundle = helper.doHistory(uriInfo.getQueryParameters(), getRequestUri());
             status = Status.OK;
             return Response.status(status).entity(bundle).build();
@@ -112,7 +112,7 @@ public Response systemHistory() {
 
     @GET
     @Path("{type}/_history")
-    public Response systemHistory(@PathParam("type") String type) {
+    public Response typeHistory(@PathParam("type") String type) {
         log.entering(this.getClass().getName(), "systemHistory(String)");
         Date startTime = new Date();
         Response.Status status = null;
@@ -122,7 +122,7 @@ public Response systemHistory(@PathParam("type") String type) {
             checkInitComplete();
             checkType(type);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             bundle = helper.doHistory(uriInfo.getQueryParameters(), getRequestUri(), type);
             status = Status.OK;
             return Response.status(status).entity(bundle).build();
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Operation.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Operation.java
index 014946b910d..0f9c8cfe9e4 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Operation.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Operation.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -79,7 +79,7 @@ public Response invoke(@PathParam("operationName") String operationName) {
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.GET);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, null, null, null,
                     null, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, null, result);
@@ -122,7 +122,7 @@ public Response invoke(@PathParam("operationName") String operationName, Resourc
             operationContext.setProperty(FHIROperationContext.PROPNAME_SECURITY_CONTEXT, securityContext);
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, null, null, null,
                     resource, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, null, result);
@@ -166,7 +166,7 @@ public Response invokeDelete(@PathParam("operationName") String operationName) {
             operationContext.setProperty(FHIROperationContext.PROPNAME_SECURITY_CONTEXT, securityContext);
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result =
                     helper.doInvoke(operationContext, null, null, null, null, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, null, result);
@@ -211,7 +211,7 @@ public Response invoke(@PathParam("resourceTypeName") String resourceTypeName,
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.GET);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, resourceTypeName, null, null,
                     null, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, resourceTypeName, result);
@@ -256,7 +256,7 @@ public Response invoke(@PathParam("resourceTypeName") String resourceTypeName,
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.POST);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, resourceTypeName, null, null,
                     resource, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, resourceTypeName, result);
@@ -315,7 +315,7 @@ public Response invoke(@PathParam("resourceTypeName") String resourceTypeName,
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.GET);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, resourceTypeName, logicalId, null,
                     null, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, resourceTypeName, result);
@@ -361,7 +361,7 @@ public Response invoke(@PathParam("resourceTypeName") String resourceTypeName,
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.POST);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, resourceTypeName, logicalId, null,
                     resource, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, resourceTypeName, result);
@@ -408,7 +408,7 @@ public Response invoke(@PathParam("resourceTypeName") String resourceTypeName,
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.GET);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, resourceTypeName, logicalId, versionId,
                     null, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, resourceTypeName, result);
@@ -455,7 +455,7 @@ public Response invoke(@PathParam("resourceTypeName") String resourceTypeName,
             operationContext.setProperty(FHIROperationContext.PROPNAME_HTTP_REQUEST, httpServletRequest);
             operationContext.setProperty(FHIROperationContext.PROPNAME_METHOD_TYPE, HttpMethod.POST);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource result = helper.doInvoke(operationContext, resourceTypeName, logicalId, versionId,
                     resource, uriInfo.getQueryParameters());
             Response response = buildResponse(operationContext, resourceTypeName, result);
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Patch.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Patch.java
index 753231f1e67..c6763d61873 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Patch.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Patch.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -78,7 +78,7 @@ public Response patch(@PathParam("type") String type, @PathParam("id") String id
 
             FHIRPatch patch = createPatch(array);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doPatch(type, id, patch, ifMatch, null, onlyIfModified);
 
             status = ior.getStatus();
@@ -136,7 +136,7 @@ public Response patch(@PathParam("type") String type, @PathParam("id") String id
                 throw buildRestException(e.getMessage(), IssueType.INVALID);
             }
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doPatch(type, id, patch, ifMatch, null, onlyIfModified);
 
             ResponseBuilder response =
@@ -199,7 +199,7 @@ public Response conditionalPatch(@PathParam("type") String type, JsonArray array
                 throw buildRestException(msg, IssueType.INVALID);
             }
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doPatch(type, null, patch, ifMatch, searchQueryString, onlyIfModified);
 
             ResponseBuilder response =
@@ -267,7 +267,7 @@ public Response conditionalPatch(@PathParam("type") String type, Parameters para
                 throw buildRestException(msg, IssueType.INVALID);
             }
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doPatch(type, null, patch, ifMatch, searchQueryString, onlyIfModified);
 
             status = ior.getStatus();
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Read.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Read.java
index aeb72202e5b..668f3a673e5 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Read.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Read.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -65,7 +65,7 @@ public Response read(@PathParam("type") String type, @PathParam("id") String id,
             MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
             long modifiedSince = parseIfModifiedSince();
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource resource = helper.doRead(type, id, true, false, null, queryParameters).getResource();
             int version2Match = -1;
             // Support ETag value with or without " (and W/)
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Search.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Search.java
index b21c3538fd8..80d88ef962c 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Search.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Search.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -68,7 +68,7 @@ private Response doSearch(String type) {
             checkType(type);
 
             queryParameters = uriInfo.getQueryParameters();
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             bundle = helper.doSearch(type, null, null, queryParameters, getRequestUri(), null);
             status = Status.OK;
             return Response.status(status).entity(bundle).build();
@@ -117,7 +117,7 @@ private Response doSearchCompartment(String compartment, String compartmentId, S
             checkType(type);
 
             queryParameters = uriInfo.getQueryParameters();
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             bundle = helper.doSearch(type, compartment, compartmentId, queryParameters, getRequestUri(), null);
             status = Status.OK;
             return Response.status(status).entity(bundle).build();
@@ -162,7 +162,7 @@ private Response doSearchAll() {
             checkInitComplete();
 
             queryParameters = uriInfo.getQueryParameters();
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             bundle = helper.doSearch("Resource", null, null, queryParameters, getRequestUri(), null);
             status = Status.OK;
             return Response.status(status).entity(bundle).build();
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Update.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Update.java
index 456dd515dfa..da792aff6f6 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/Update.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/Update.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -71,7 +71,7 @@ public Response update(@PathParam("type") String type, @PathParam("id") String i
             checkType(type);
             Integer ifNoneMatch = encodeIfNoneMatch(ifNoneMatchHdr);
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doUpdate(type, id, resource, ifMatch, null, onlyIfModified, ifNoneMatch);
 
             ResponseBuilder response = Response.ok()
@@ -143,7 +143,7 @@ public Response conditionalUpdate(@PathParam("type") String type, Resource resou
                 throw buildRestException(msg, IssueType.INVALID);
             }
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             ior = helper.doUpdate(type, null, resource, ifMatch, searchQueryString, onlyIfModified, IF_NONE_MATCH_NULL);
 
             ResponseBuilder response =
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/VRead.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/VRead.java
index 9ddd123344c..a49fc283bf6 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/resources/VRead.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/VRead.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2016, 2021
+ * (C) Copyright IBM Corp. 2016, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -60,7 +60,7 @@ public Response vread(@PathParam("type") String type, @PathParam("id") String id
 
             MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
 
-            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl());
+            FHIRRestHelper helper = new FHIRRestHelper(getPersistenceImpl(), getFhirVersion());
             Resource resource = helper.doVRead(type, id, vid, queryParameters);
             status = Status.OK;
             ResponseBuilder response = Response.ok().entity(resource);
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/resources/filters/FHIRVersionRequestFilter.java b/fhir-server/src/main/java/com/ibm/fhir/server/resources/filters/FHIRVersionRequestFilter.java
new file mode 100644
index 00000000000..42374e46dff
--- /dev/null
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/resources/filters/FHIRVersionRequestFilter.java
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright IBM Corp. 2022
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+ package com.ibm.fhir.server.resources.filters;
+
+import static com.ibm.fhir.core.FHIRVersionParam.VERSION_40;
+import static com.ibm.fhir.core.FHIRVersionParam.VERSION_43;
+
+import java.io.IOException;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.MediaType;
+
+import com.ibm.fhir.config.FHIRConfigHelper;
+import com.ibm.fhir.config.FHIRConfiguration;
+import com.ibm.fhir.core.FHIRMediaType;
+import com.ibm.fhir.core.FHIRVersionParam;
+
+/**
+ * A request filter that sets the {@value #FHIR_VERSION_PROP} request context property with the
+ * preferred FHIRVersionParam for the current interaction according to the following algorithm:
+ *
+ * <p>For PUT and POST requests:
+ * <ol>
+ * <li>if the Content-Type header has a proper fhirVersion value (e.g. "4.0" or "4.3") use that
+ * <li>otherwise fall back to the "other request" algorithm
+ * </ol>
+ * <p>For all other requests:
+ * <ol>
+ * <li>"4.3" from the acceptableMediaTypes
+ * <li>"4.0" from the acceptableMediaTypes
+ * <li>whatever is configured in the fhirServer/core/defaultFhirVersion config property
+ * <li>"4.0"
+ * </ol>
+ */
+public class FHIRVersionRequestFilter implements ContainerRequestFilter {
+    public static final String FHIR_VERSION_PROP = "com.ibm.fhir.server.fhirVersion";
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+        FHIRVersionParam fhirVersion;
+
+        switch (requestContext.getMethod()) {
+        case HttpMethod.POST:
+        case HttpMethod.PUT:
+            fhirVersion = getFhirVersionFromContentTypeHeader(requestContext);
+            break;
+        case HttpMethod.GET:
+        default:
+            fhirVersion = getFhirVersionFromAcceptHeader(requestContext);
+            break;
+        }
+
+        requestContext.setProperty(FHIR_VERSION_PROP, fhirVersion);
+    }
+
+    /**
+     * The FHIRVersionParam to use for the current interaction as determined by the Content-Type header
+     *
+     * @param requestContext
+     * @return the FHIRVersionParam value from the Content-Type header if it is specified,
+     *          otherwise falls back to {@link #getFhirVersionFromAcceptHeader(ContainerRequestContext)}
+     */
+    private FHIRVersionParam getFhirVersionFromContentTypeHeader(ContainerRequestContext requestContext) {
+        MediaType mediaType = requestContext.getMediaType();
+        if (mediaType != null) {
+            String submittedVersion = mediaType.getParameters().get(FHIRMediaType.FHIR_VERSION_PARAMETER);
+            if (submittedVersion != null) {
+                // "startsWith" to cover the x.y.z cases which are technically invalid, but close enough
+                if (submittedVersion.startsWith(VERSION_43.value())) {
+                    return VERSION_43;
+                } else if (submittedVersion.startsWith(VERSION_40.value())) {
+                    return VERSION_40;
+                }
+            }
+        }
+        // fall back to getFhirVersionFromAcceptHeader logic
+        return getFhirVersionFromAcceptHeader(requestContext);
+    }
+
+    /**
+     * The FHIRVersionParam to use for the current interaction as determined by the Accept header
+     *
+     * @param requestContext
+     * @return the FHIRVersionParam value from the Accept header if it is specified,
+     *          otherwise from the defaultFhirVersion property of the fhir-server-config
+     */
+    private FHIRVersionParam getFhirVersionFromAcceptHeader(ContainerRequestContext requestContext) {
+        FHIRVersionParam fhirVersion = null;
+        for (MediaType mediaType : requestContext.getAcceptableMediaTypes()) {
+            if (mediaType.getParameters() != null) {
+                String fhirVersionParam = mediaType.getParameters().get(FHIRMediaType.FHIR_VERSION_PARAMETER);
+                if (fhirVersionParam != null) {
+                    // "startsWith" to cover the x.y.z cases which are technically invalid, but close enough
+                    if (fhirVersionParam.startsWith(VERSION_43.value())) {
+                        // one of the acceptable media types was our "actual" fhir version, so use that and stop looking
+                        fhirVersion = VERSION_43;
+                        break;
+                    } else if (fhirVersionParam.startsWith(VERSION_40.value())) {
+                        // set the fhirVersion parameter but keep looking in case our "actual" version is also acceptable
+                        fhirVersion = VERSION_40;
+                    }
+                }
+            }
+        }
+        if (fhirVersion == null) {
+            String fhirVersionString = FHIRConfigHelper.getStringProperty(FHIRConfiguration.PROPERTY_DEFAULT_FHIR_VERSION, VERSION_40.value());
+            fhirVersion = FHIRVersionParam.from(fhirVersionString);
+        }
+        return fhirVersion;
+    }
+}
\ No newline at end of file
diff --git a/fhir-server/src/main/java/com/ibm/fhir/server/util/FHIRRestHelper.java b/fhir-server/src/main/java/com/ibm/fhir/server/util/FHIRRestHelper.java
index 3e6dab497b1..f7125803c7b 100644
--- a/fhir-server/src/main/java/com/ibm/fhir/server/util/FHIRRestHelper.java
+++ b/fhir-server/src/main/java/com/ibm/fhir/server/util/FHIRRestHelper.java
@@ -6,6 +6,7 @@
 
 package com.ibm.fhir.server.util;
 
+import static com.ibm.fhir.config.FHIRConfiguration.PROPERTY_VALIDATION_FAIL_FAST;
 import static com.ibm.fhir.core.FHIRConstants.EXT_BASE;
 import static com.ibm.fhir.model.type.String.string;
 import static com.ibm.fhir.model.util.ModelSupport.getResourceType;
@@ -45,9 +46,11 @@
 import com.ibm.fhir.config.PropertyGroup;
 import com.ibm.fhir.config.PropertyGroup.PropertyEntry;
 import com.ibm.fhir.core.FHIRConstants;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.core.HTTPHandlingPreference;
 import com.ibm.fhir.core.HTTPReturnPreference;
 import com.ibm.fhir.core.context.FHIRPagingContext;
+import com.ibm.fhir.core.util.ResourceTypeHelper;
 import com.ibm.fhir.database.utils.api.LockException;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.patch.FHIRPatch;
@@ -74,6 +77,7 @@
 import com.ibm.fhir.model.type.Uri;
 import com.ibm.fhir.model.type.Url;
 import com.ibm.fhir.model.type.code.BundleType;
+import com.ibm.fhir.model.type.code.FHIRVersion;
 import com.ibm.fhir.model.type.code.HTTPVerb;
 import com.ibm.fhir.model.type.code.IssueSeverity;
 import com.ibm.fhir.model.type.code.IssueType;
@@ -152,7 +156,7 @@ public class FHIRRestHelper implements FHIRResourceHelpers {
     private static final com.ibm.fhir.model.type.String SC_BAD_REQUEST_STRING = string(Integer.toString(SC_BAD_REQUEST));
     private static final com.ibm.fhir.model.type.String SC_ACCEPTED_STRING = string(Integer.toString(SC_ACCEPTED));
     private static final ZoneId UTC = ZoneId.of("UTC");
-    
+
     // Convenience constants to make call parameters more readable
     private static final boolean THROW_EXC_ON_NULL = true;
     private static final boolean INCLUDE_DELETED = true;
@@ -176,21 +180,37 @@ public class FHIRRestHelper implements FHIRResourceHelpers {
             .optionalEnd().toFormatter();
 
     private FHIRPersistence persistence = null;
+    private FHIRVersionParam fhirVersion = null;
 
     // Used for correlating requests within a bundle.
     private String bundleRequestCorrelationId = null;
 
-    private final FHIRValidator validator = FHIRValidator.validator(FHIRConfigHelper.getBooleanProperty(FHIRConfiguration.PROPERTY_VALIDATION_FAIL_FAST, Boolean.FALSE));
+    private final FHIRValidator validator = FHIRValidator.validator(FHIRConfigHelper.getBooleanProperty(PROPERTY_VALIDATION_FAIL_FAST, Boolean.FALSE));
 
+    /**
+     * Construct an instance with the passed FHIRPersistence and a FHIRVersion of 4.3.0
+     * @see #FHIRRestHelper(FHIRPersistence, FHIRVersion)
+     */
     public FHIRRestHelper(FHIRPersistence persistence) {
+        this(persistence, FHIRVersionParam.VERSION_43);
+    }
+
+    /**
+     * @param persistence a FHIRPersistence instance to use for the interactions
+     * @param fhirVersion the fhirVersion to use for the interactions
+     * @implNote fhirVersion is used to validate that the interactions are only
+     *          performed against resource types compatible with the target version
+     */
+    public FHIRRestHelper(FHIRPersistence persistence, FHIRVersionParam fhirVersion) {
         this.persistence = persistence;
+        this.fhirVersion = fhirVersion;
     }
 
     @Override
     public FHIRRestOperationResponse doCreate(String type, Resource resource, String ifNoneExist,
-        boolean doValidation) throws Exception {
+            boolean doValidation) throws Exception {
 
-        // Validate that interaction is allowed for given resource type
+        // Validate that the interaction is allowed for the given resource type
         validateInteraction(Interaction.CREATE, type);
 
         // Validate the input and, if valid, start collecting supplemental warnings
@@ -237,7 +257,7 @@ public FHIRRestOperationResponse doCreate(String type, Resource resource, String
 
     @Override
     public FHIRRestOperationResponse doCreateMeta(FHIRPersistenceEvent event, List<Issue> warnings, String type, Resource resource,
-        String ifNoneExist) throws Exception {
+            String ifNoneExist) throws Exception {
         log.entering(this.getClass().getName(), "doCreateMeta");
 
         // Save the current request context.
@@ -336,7 +356,8 @@ public FHIRRestOperationResponse doCreateMeta(FHIRPersistenceEvent event, List<I
     }
 
     @Override
-    public FHIRRestOperationResponse doCreatePersist(FHIRPersistenceEvent event, List<Issue> warnings, Resource resource, PayloadPersistenceResponse offloadResponse) throws Exception {
+    public FHIRRestOperationResponse doCreatePersist(FHIRPersistenceEvent event, List<Issue> warnings, Resource resource,
+            PayloadPersistenceResponse offloadResponse) throws Exception {
         log.entering(this.getClass().getName(), "doCreatePersist");
 
         FHIRRestOperationResponse ior = new FHIRRestOperationResponse();
@@ -353,7 +374,7 @@ public FHIRRestOperationResponse doCreatePersist(FHIRPersistenceEvent event, Lis
             checkIdAndMeta(resource);
 
             // create the resource and return the location header.
-            final FHIRPersistenceContext persistenceContext = 
+            final FHIRPersistenceContext persistenceContext =
                     FHIRPersistenceContextImpl.builder(event)
                     .withOffloadResponse(offloadResponse)
                     .build();
@@ -757,7 +778,7 @@ public FHIRRestOperationResponse doPatchOrUpdatePersist(FHIRPersistenceEvent eve
                     .withIfNoneMatch(ifNoneMatch)
                     .withOffloadResponse(offloadResponse)
                     .build();
-            
+
             boolean createOnUpdate = (prevResource == null);
             final SingleResourceResult<Resource> result;
             if (createOnUpdate) {
@@ -898,14 +919,10 @@ public FHIRRestOperationResponse doDelete(String type, String id, String searchQ
         List<Issue> warnings = new ArrayList<>();
 
         try {
-            String resourceTypeName = type;
             if (!ModelSupport.isResourceType(type)) {
                 throw buildUnsupportedResourceTypeException(type);
             }
 
-            Class<? extends Resource> resourceType =
-                    getResourceType(resourceTypeName);
-
             // Next, if a conditional delete was invoked then use the search criteria to find the
             // resource to be deleted. Otherwise, we'll use the id value to identify the resource
             // to be deleted.
@@ -989,7 +1006,7 @@ public FHIRRestOperationResponse doDelete(String type, String id, String searchQ
                             new FHIRPersistenceEvent(null, buildPersistenceEventProperties(type, id, null, null));
                     event.setFhirResource(resourceToDelete);
                     getInterceptorMgr().fireBeforeDeleteEvent(event);
-                    
+
                     // For soft-delete we store a new version of the resource with the deleted
                     // flag set. Update the resource meta so that it has the correct version id
                     final String resourcePayloadKey = UUID.randomUUID().toString();
@@ -1116,7 +1133,7 @@ private SingleResourceResult<? extends Resource> doRead(String type, String id,
             FHIRSearchContext searchContext = null;
             if (queryParameters != null) {
                 searchContext = SearchUtil.parseReadQueryParameters(resourceType, queryParameters, Interaction.READ.value(),
-                    HTTPHandlingPreference.LENIENT.equals(requestContext.getHandlingPreference()));
+                    HTTPHandlingPreference.LENIENT.equals(requestContext.getHandlingPreference()), fhirVersion);
             }
 
             // First, invoke the 'beforeRead' interceptor methods.
@@ -1183,7 +1200,7 @@ public Resource doVRead(String type, String id, String versionId, MultivaluedMap
             FHIRSearchContext searchContext = null;
             if (queryParameters != null) {
                 searchContext = SearchUtil.parseReadQueryParameters(resourceType, queryParameters, Interaction.VREAD.value(),
-                    HTTPHandlingPreference.LENIENT.equals(requestContext.getHandlingPreference()));
+                    HTTPHandlingPreference.LENIENT.equals(requestContext.getHandlingPreference()), fhirVersion);
             }
 
             // First, invoke the 'beforeVread' interceptor methods.
@@ -1342,7 +1359,7 @@ public Bundle doSearch(String type, String compartment, String compartmentId,
                 log.info("Not including resources");
             }
             FHIRSearchContext searchContext = SearchUtil.parseCompartmentQueryParameters(compartment, compartmentId, resourceType, queryParameters,
-                isLenientHandling, includeResources);
+                isLenientHandling, includeResources, fhirVersion);
 
             // First, invoke the 'beforeSearch' interceptor methods.
             FHIRPersistenceEvent event =
@@ -2145,10 +2162,10 @@ Bundle createSearchResponseBundle(List<ResourceResult<? extends Resource>> resou
                     issues.add(FHIRUtil.buildOperationOutcomeIssue(IssueSeverity.WARNING, IssueType.NOT_SUPPORTED, msg));
                 } else {
                     // Off-spec - simply provide the url without the resource body. But in order
-                    // to satisfy "Rule: must be a resource unless there's a request or response" 
+                    // to satisfy "Rule: must be a resource unless there's a request or response"
                     // we also add a minimal response element
                     final Uri uri = Uri.of(getRequestBaseUri(type) + "/" + resourceResult.getResourceTypeName() + "/" + resourceResult.getLogicalId());
-                    com.ibm.fhir.model.resource.Bundle.Entry.Response response = 
+                    com.ibm.fhir.model.resource.Bundle.Entry.Response response =
                             com.ibm.fhir.model.resource.Bundle.Entry.Response.builder()
                             .status("200")
                             .build();
@@ -2572,6 +2589,7 @@ private void setOperationContextProperties(FHIROperationContext operationContext
         operationContext.setProperty(FHIROperationContext.PROPNAME_REQUEST_BASE_URI, getRequestBaseUri(resourceTypeName));
         operationContext.setProperty(FHIROperationContext.PROPNAME_REQUEST_PARAMETERS, requestParameters);
         operationContext.setProperty(FHIROperationContext.PROPNAME_PERSISTENCE_IMPL, persistence);
+        operationContext.setProperty(FHIROperationContext.PROPNAME_FHIR_VERSION, fhirVersion);
     }
 
     @Override
@@ -2940,6 +2958,7 @@ public void validateInteraction(Interaction interaction, String resourceType) th
         List<String> interactions = null;
         boolean resourceValid = true;
 
+        // TODO: replace with ResourcesConfigAdapter
         // Retrieve the interaction configuration
         try {
             StringBuilder defaultInteractionsConfigPath = new StringBuilder(FHIRConfiguration.PROPERTY_RESOURCES).append("/Resource/")
@@ -2978,10 +2997,18 @@ public void validateInteraction(Interaction interaction, String resourceType) th
         // Perform validation of specified interaction against specified resourceType
         if (interactions != null && !interactions.contains(interaction.value())) {
             throw buildRestException("The requested interaction of type '" + interaction.value() + "' is not allowed for resource type '" + resourceType + "'",
-                IssueType.BUSINESS_RULE, IssueSeverity.ERROR);
+                    IssueType.BUSINESS_RULE, IssueSeverity.ERROR);
         } else if (!resourceValid) {
             throw buildRestException("The requested resource type '" + resourceType + "' is not found",
-                IssueType.NOT_FOUND, IssueSeverity.ERROR);
+                    IssueType.NOT_FOUND, IssueSeverity.ERROR);
+        }
+
+        if (fhirVersion == FHIRVersionParam.VERSION_40) {
+            // ensure that the version of this resource type in 4.0.1 is compatible with the fhirVersion of the server
+            if (ResourceTypeHelper.getNewOrBreakingResourceTypeNames().contains(resourceType)) {
+                throw buildRestException("The requested resource type '" + resourceType + "' is not supported for fhirVersion 4.0",
+                        IssueType.NOT_SUPPORTED, IssueSeverity.ERROR);
+            }
         }
     }
 
@@ -2998,14 +3025,14 @@ public Bundle doHistory(MultivaluedMap<String, String> queryParameters, String r
 
         // extract the query parameters
         FHIRRequestContext requestContext = FHIRRequestContext.get();
-        
+
         if (requestContext.isReturnPreferenceDefault()) {
             // For _history, override the default preference to be REPRESENTATION so resources
             // are returned in the response bundle per the R4 spec.
             requestContext.setReturnPreference(HTTPReturnPreference.REPRESENTATION);
         }
-        FHIRSystemHistoryContext historyContext =
-                FHIRPersistenceUtil.parseSystemHistoryParameters(queryParameters, HTTPHandlingPreference.LENIENT.equals(requestContext.getHandlingPreference()));
+        FHIRSystemHistoryContext historyContext = FHIRPersistenceUtil.parseSystemHistoryParameters(queryParameters,
+                HTTPHandlingPreference.LENIENT.equals(requestContext.getHandlingPreference()), fhirVersion);
 
         // If HTTPReturnPreference is REPRESENTATION, we fetch the resources and include them
         // in the response bundle. To make it simple, we make the records and resources the same
@@ -3025,26 +3052,26 @@ public Bundle doHistory(MultivaluedMap<String, String> queryParameters, String r
             } else if (count > MAX_HISTORY_ENTRIES) {
                 count = MAX_HISTORY_ENTRIES;
             }
-            
+
             if (resourceType != null) {
                 // Use the resource type on the path, ignoring any _type parameter
-                records = persistence.changes(count, since, before, historyContext.getChangeIdMarker(), Collections.singletonList(resourceType), historyContext.isExcludeTransactionTimeoutWindow(),
-                        historyContext.getHistorySortOrder());
+                records = persistence.changes(count, since, before, historyContext.getChangeIdMarker(), Collections.singletonList(resourceType),
+                        historyContext.isExcludeTransactionTimeoutWindow(), historyContext.getHistorySortOrder());
             } else if (historyContext.getResourceTypes().size() > 0) {
                 // New API allows us to filter using multiple resource type names, but first we
                 // have to check the interaction is allowed for each one
                 for (String rt: historyContext.getResourceTypes()) {
                     validateInteraction(Interaction.HISTORY, rt);
                 }
-                records = persistence.changes(count, since, before, historyContext.getChangeIdMarker(), historyContext.getResourceTypes(), 
+                records = persistence.changes(count, since, before, historyContext.getChangeIdMarker(), historyContext.getResourceTypes(),
                         historyContext.isExcludeTransactionTimeoutWindow(), historyContext.getHistorySortOrder());
             } else {
                 // no resource type filter
                 final List<String> NULL_RESOURCE_TYPE_NAMES = null;
-                records = persistence.changes(count, since, before, historyContext.getChangeIdMarker(), NULL_RESOURCE_TYPE_NAMES, historyContext.isExcludeTransactionTimeoutWindow(), 
-                        historyContext.getHistorySortOrder());
+                records = persistence.changes(count, since, before, historyContext.getChangeIdMarker(), NULL_RESOURCE_TYPE_NAMES,
+                        historyContext.isExcludeTransactionTimeoutWindow(), historyContext.getHistorySortOrder());
             }
-            
+
             if (historyContext.getReturnPreference() == HTTPReturnPreference.REPRESENTATION
                     || historyContext.getReturnPreference() == HTTPReturnPreference.OPERATION_OUTCOME) {
                 // vread the resources so that we can include them in the response bundle
@@ -3052,15 +3079,14 @@ public Bundle doHistory(MultivaluedMap<String, String> queryParameters, String r
                     log.fine("Fetching resources for history response bundle, count=" + records.size());
                 }
                 resources = persistence.readResourcesForRecords(records);
-                
+
                 if (resources.size() != records.size()) {
                     // very unlikely...unless we overlap with a patient erase operation
                     throw new FHIRPersistenceException("Could not read all required resource records");
                 }
             }
         } catch (FHIRPersistenceDataAccessException x) {
-            log.log(Level.SEVERE, "Error reading history; params = {" + historyContext + "}",
-                x);
+            log.log(Level.SEVERE, "Error reading history; params = {" + historyContext + "}", x);
             throw x;
         } finally {
             txn.end();
@@ -3153,12 +3179,12 @@ public Bundle doHistory(MultivaluedMap<String, String> queryParameters, String r
             }
             nextRequest.append("?");
             nextRequest.append("_count=").append(count);
-            
+
             if (resourceType == null && historyContext.getResourceTypes().size() > 0) {
                 nextRequest.append("&_type=");
                 nextRequest.append(String.join(",", historyContext.getResourceTypes()));
             }
-            
+
             if (historyContext.isExcludeTransactionTimeoutWindow()) {
                 nextRequest.append("&_excludeTransactionTimeoutWindow=true");
             }
@@ -3171,7 +3197,7 @@ public Bundle doHistory(MultivaluedMap<String, String> queryParameters, String r
                     // make sure we keep including the before filter specified in the original request
                     nextRequest.append("&_before=").append(historyContext.getBefore().getValue().format(DateTime.PARSER_FORMATTER));
                 }
-                
+
                 if (changeIdMarker != null) {
                     // good way to exclude this resource on the next call
                     nextRequest.append("&_changeIdMarker=").append(changeIdMarker);
@@ -3224,7 +3250,7 @@ public Bundle doHistory(MultivaluedMap<String, String> queryParameters, String r
         if (historyContext.getChangeIdMarker() != null) {
             selfRequest.append("&_changeIdMarker=").append(historyContext.getChangeIdMarker());
         }
-        
+
         if (historyContext.getSince() != null && historyContext.getSince().getValue() != null) {
             selfRequest.append("&_since=").append(historyContext.getSince().getValue().format(DateTime.PARSER_FORMATTER));
         }
diff --git a/fhir-server/src/test/java/com/ibm/fhir/server/test/BundleValidationTest.java b/fhir-server/src/test/java/com/ibm/fhir/server/test/BundleValidationTest.java
index e0143e39ea5..a5ebbddb2b4 100644
--- a/fhir-server/src/test/java/com/ibm/fhir/server/test/BundleValidationTest.java
+++ b/fhir-server/src/test/java/com/ibm/fhir/server/test/BundleValidationTest.java
@@ -664,7 +664,7 @@ public void testValidBundle() throws Exception {
                         .build())
                     .build())
                 .build();
-        
+
         // Process request
         FHIRRequestContext.get().setOriginalRequestUri("test");
         FHIRRequestContext.get().setReturnPreference(HTTPReturnPreference.OPERATION_OUTCOME);
diff --git a/fhir-server/src/test/java/com/ibm/fhir/server/test/CapabilitiesTest.java b/fhir-server/src/test/java/com/ibm/fhir/server/test/CapabilitiesTest.java
index 6f6cd7474bb..781d430eabc 100644
--- a/fhir-server/src/test/java/com/ibm/fhir/server/test/CapabilitiesTest.java
+++ b/fhir-server/src/test/java/com/ibm/fhir/server/test/CapabilitiesTest.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2020, 2021
+ * (C) Copyright IBM Corp. 2020, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -20,6 +20,7 @@
 
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.exception.FHIRException;
 import com.ibm.fhir.model.resource.CapabilityStatement;
 import com.ibm.fhir.model.resource.CapabilityStatement.Rest.Resource.Interaction;
@@ -42,9 +43,9 @@ void tearDown() throws FHIRException {
     void testBuildCapabilityStatement_resources_omitted() throws Exception {
         FHIRRequestContext.get().setTenantId("omitted");
         FHIRRequestContext.get().setOriginalRequestUri("http://example.com/metadata");
-        CapabilitiesChild c = new CapabilitiesChild();
+        CapabilitiesChild c = new CapabilitiesChild(FHIRVersionParam.VERSION_40);
 
-        Response capabilities = c.capabilities("full", null);
+        Response capabilities = c.capabilities("full");
         CapabilityStatement capabilityStatement = capabilities.readEntity(CapabilityStatement.class);
 
         assertEquals(capabilityStatement.getRest().size(), 1, "Number of REST Elements");
@@ -57,9 +58,9 @@ void testBuildCapabilityStatement_resources_omitted() throws Exception {
     void testBuildCapabilityStatement_resources_empty_r4() throws Exception {
         FHIRRequestContext.get().setTenantId("empty");
         FHIRRequestContext.get().setOriginalRequestUri("http://example.com/metadata");
-        CapabilitiesChild c = new CapabilitiesChild();
+        CapabilitiesChild c = new CapabilitiesChild(FHIRVersionParam.VERSION_40);
 
-        Response capabilities = c.capabilities("full", "application/fhir+json;fhirVersion=4.0");
+        Response capabilities = c.capabilities("full");
         CapabilityStatement capabilityStatement = capabilities.readEntity(CapabilityStatement.class);
 
         assertEquals(capabilityStatement.getRest().size(), 1, "Number of REST Elements");
@@ -72,9 +73,9 @@ void testBuildCapabilityStatement_resources_empty_r4() throws Exception {
     void testBuildCapabilityStatement_resources_empty_r4b() throws Exception {
         FHIRRequestContext.get().setTenantId("empty");
         FHIRRequestContext.get().setOriginalRequestUri("http://example.com/metadata");
-        CapabilitiesChild c = new CapabilitiesChild();
+        CapabilitiesChild c = new CapabilitiesChild(FHIRVersionParam.VERSION_43);
 
-        Response capabilities = c.capabilities("full", "application/fhir+json;fhirVersion=4.3");
+        Response capabilities = c.capabilities("full");
         CapabilityStatement capabilityStatement = capabilities.readEntity(CapabilityStatement.class);
 
         assertEquals(capabilityStatement.getRest().size(), 1, "Number of REST Elements");
@@ -87,9 +88,9 @@ void testBuildCapabilityStatement_resources_empty_r4b() throws Exception {
     void testBuildCapabilityStatement_resources_filtered() throws Exception {
         FHIRRequestContext.get().setTenantId("smart-enabled");
         FHIRRequestContext.get().setOriginalRequestUri("http://example.com/metadata");
-        CapabilitiesChild c = new CapabilitiesChild();
+        CapabilitiesChild c = new CapabilitiesChild(FHIRVersionParam.VERSION_43);
 
-        Response capabilities = c.capabilities("full", "");
+        Response capabilities = c.capabilities("full");
         CapabilityStatement capabilityStatement = capabilities.readEntity(CapabilityStatement.class);
 
         assertEquals(capabilityStatement.getRest().size(), 1, "Number of REST Elements");
@@ -129,15 +130,14 @@ private void assertResourceDefinition(CapabilityStatement.Rest restDefinition, R
      * that are normally injected by JAX-RS and so this is the only way to set them.
      */
     private static class CapabilitiesChild extends Capabilities {
-        public CapabilitiesChild() throws Exception {
-            super();
+        /**
+         * @implNote Under "normal" operation, the FHIRVersionParam is set via the
+         *          FHIRVersionRequestFilter. To simulate that, use a different
+         *          CapabilitesChild for each request with a new fhirVersion value
+         */
+        public CapabilitiesChild(FHIRVersionParam fhirVersion) throws Exception {
             this.context = new MockServletContext();
-        }
-
-        @Override
-        public Response capabilities(String mode, String acceptHeaderValue) {
-            httpServletRequest = new MockHttpServletRequest();
-            return super.capabilities(mode, acceptHeaderValue);
+            this.httpServletRequest = new MockHttpServletRequest(fhirVersion);
         }
     }
 }
diff --git a/fhir-server/src/test/java/com/ibm/fhir/server/test/InteractionValidationConfigTest.java b/fhir-server/src/test/java/com/ibm/fhir/server/test/InteractionValidationConfigTest.java
index 2f215a5eec7..45b62d7146a 100644
--- a/fhir-server/src/test/java/com/ibm/fhir/server/test/InteractionValidationConfigTest.java
+++ b/fhir-server/src/test/java/com/ibm/fhir/server/test/InteractionValidationConfigTest.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2021
+ * (C) Copyright IBM Corp. 2021, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -20,6 +20,7 @@
 
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.core.HTTPReturnPreference;
 import com.ibm.fhir.exception.FHIRException;
 import com.ibm.fhir.exception.FHIROperationException;
@@ -71,7 +72,7 @@ void setup() throws FHIRException {
         FHIRConfiguration.setConfigHome("src/test/resources");
         FHIRRegistry.getInstance().addProvider(new MockRegistryResourceProvider());
         persistence = new MockPersistenceImpl();
-        helper = new FHIRRestHelper(persistence);
+        helper = new FHIRRestHelper(persistence, FHIRVersionParam.VERSION_43);
     }
 
     @AfterClass
diff --git a/fhir-server/src/test/java/com/ibm/fhir/server/test/MockHttpServletRequest.java b/fhir-server/src/test/java/com/ibm/fhir/server/test/MockHttpServletRequest.java
index 4931ff44c82..5c5aba8610e 100644
--- a/fhir-server/src/test/java/com/ibm/fhir/server/test/MockHttpServletRequest.java
+++ b/fhir-server/src/test/java/com/ibm/fhir/server/test/MockHttpServletRequest.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2020
+ * (C) Copyright IBM Corp. 2020, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -29,17 +29,30 @@
 import javax.servlet.http.HttpUpgradeHandler;
 import javax.servlet.http.Part;
 
+import com.ibm.fhir.core.FHIRVersionParam;
+import com.ibm.fhir.server.resources.filters.FHIRVersionRequestFilter;
+
 public class MockHttpServletRequest implements HttpServletRequest {
+    FHIRVersionParam fhirVersion;
+
+    public MockHttpServletRequest(FHIRVersionParam fhirVersion) {
+        this.fhirVersion = fhirVersion;
+    }
 
     @Override
     public StringBuffer getRequestURL() {
         return new StringBuffer("http://example.com");
     }
 
-    // All below methods are auto-generated stubs
     @Override
-    public Object getAttribute(String name) { return null; }
+    public Object getAttribute(String name) {
+        if (FHIRVersionRequestFilter.FHIR_VERSION_PROP.equals(name)) {
+            return fhirVersion;
+        }
+        return null;
+    }
 
+    // All below methods are auto-generated stubs
     @Override
     public Enumeration<String> getAttributeNames() { return null; }
 
diff --git a/fhir-server/src/test/java/com/ibm/fhir/server/test/ProfileValidationConfigTest.java b/fhir-server/src/test/java/com/ibm/fhir/server/test/ProfileValidationConfigTest.java
index 6faf2bffc44..54a264c5a36 100644
--- a/fhir-server/src/test/java/com/ibm/fhir/server/test/ProfileValidationConfigTest.java
+++ b/fhir-server/src/test/java/com/ibm/fhir/server/test/ProfileValidationConfigTest.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2020, 2021
+ * (C) Copyright IBM Corp. 2020, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -18,6 +18,7 @@
 
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.core.HTTPReturnPreference;
 import com.ibm.fhir.exception.FHIRException;
 import com.ibm.fhir.exception.FHIROperationException;
@@ -86,7 +87,7 @@ void setup() throws FHIRException {
         FHIRRequestContext.get().setTenantId("profileValidationConfigTest");
         FHIRRegistry.getInstance().addProvider(new MockRegistryResourceProvider());
         persistence = new MockPersistenceImpl();
-        helper = new FHIRRestHelper(persistence);
+        helper = new FHIRRestHelper(persistence, FHIRVersionParam.VERSION_43);
     }
 
     @AfterClass
@@ -1215,7 +1216,7 @@ public void testBundleWithNonAllowedProfileSpecified() throws Exception {
             assertEquals(issues.get(0).getDetails().getText().getValue(), "One or more errors were encountered while validating a 'transaction' request bundle.");
             assertEquals(issues.get(0).getSeverity(), IssueSeverity.FATAL);
             assertEquals(issues.get(0).getCode(), IssueType.INVALID);
-            assertTrue(issues.get(1).getDetails().getText().getValue().startsWith( 
+            assertTrue(issues.get(1).getDetails().getText().getValue().startsWith(
                 "A profile was specified which is not allowed. Resources of type 'CarePlan' are not allowed to declare conformance to any of the following profiles: ["));
             assertEquals(issues.get(1).getSeverity(), IssueSeverity.ERROR);
             assertEquals(issues.get(1).getCode(), IssueType.BUSINESS_RULE);
diff --git a/fhir-server/src/test/java/com/ibm/fhir/server/test/WellKnownTest.java b/fhir-server/src/test/java/com/ibm/fhir/server/test/WellKnownTest.java
index 551cb009d1e..7fde8f9d4f4 100644
--- a/fhir-server/src/test/java/com/ibm/fhir/server/test/WellKnownTest.java
+++ b/fhir-server/src/test/java/com/ibm/fhir/server/test/WellKnownTest.java
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright IBM Corp. 2020, 2021
+ * (C) Copyright IBM Corp. 2020, 2022
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -9,7 +9,6 @@
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
-import jakarta.json.JsonObject;
 import javax.ws.rs.core.Response;
 
 import org.testng.annotations.AfterClass;
@@ -18,9 +17,12 @@
 
 import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.exception.FHIRException;
 import com.ibm.fhir.server.resources.WellKnown;
 
+import jakarta.json.JsonObject;
+
 public class WellKnownTest {
 
     @BeforeClass
@@ -89,7 +91,7 @@ public WellKnownChild() throws Exception {
 
         @Override
         public Response smartConfig() throws ClassNotFoundException {
-            httpServletRequest = new MockHttpServletRequest();
+            httpServletRequest = new MockHttpServletRequest(FHIRVersionParam.VERSION_43);
             return super.smartConfig();
         }
     }
diff --git a/operation/fhir-operation-everything/src/main/java/com/ibm/fhir/operation/everything/EverythingOperation.java b/operation/fhir-operation-everything/src/main/java/com/ibm/fhir/operation/everything/EverythingOperation.java
index 852886d2742..9302261fd1b 100644
--- a/operation/fhir-operation-everything/src/main/java/com/ibm/fhir/operation/everything/EverythingOperation.java
+++ b/operation/fhir-operation-everything/src/main/java/com/ibm/fhir/operation/everything/EverythingOperation.java
@@ -22,8 +22,13 @@
 import javax.ws.rs.core.MultivaluedMap;
 
 import com.ibm.fhir.config.FHIRConfigHelper;
+import com.ibm.fhir.config.FHIRConfiguration;
 import com.ibm.fhir.config.FHIRRequestContext;
+import com.ibm.fhir.config.Interaction;
+import com.ibm.fhir.config.PropertyGroup;
+import com.ibm.fhir.config.ResourcesConfigAdapter;
 import com.ibm.fhir.core.FHIRConstants;
+import com.ibm.fhir.core.FHIRVersionParam;
 import com.ibm.fhir.core.HTTPHandlingPreference;
 import com.ibm.fhir.exception.FHIROperationException;
 import com.ibm.fhir.model.resource.Bundle;
@@ -186,11 +191,12 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
 
         List<String> defaultResourceTypes = new ArrayList<String>(0);
         try {
-            defaultResourceTypes = getDefaultIncludedResourceTypes(resourceHelper);
+            FHIRVersionParam fhirVersion = (FHIRVersionParam) operationContext.getProperty(FHIROperationContext.PROPNAME_FHIR_VERSION);
+            defaultResourceTypes = getDefaultIncludedResourceTypes(resourceHelper, fhirVersion);
         } catch (FHIRSearchException e) {
             throw new Error("There has been an error retrieving the list of included resources of the $everything operation.", e);
         }
-        
+
         List<String> resourceTypesOverride = getOverridenIncludedResourceTypes(parameters, defaultResourceTypes);
         List<String> resourceTypes = resourceTypesOverride.isEmpty() ? defaultResourceTypes : resourceTypesOverride;
 
@@ -203,9 +209,9 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
             }
 
             // Need to construct a new version of the map each time through the loop to edit
-            MultivaluedMap<String, String> tempSearchParameters = 
+            MultivaluedMap<String, String> tempSearchParameters =
                     new MultivaluedHashMap<String, String>(searchParameters);
-            
+
             Bundle results = null;
             int currentResourceCount = 0;
             try {
@@ -339,22 +345,14 @@ protected List<String> getOverridenIncludedResourceTypes(Parameters parameters,
      * @return the list of patient subresources that will be included in the $everything operation
      * @throws FHIRSearchException
      */
-    private List<String> getDefaultIncludedResourceTypes(FHIRResourceHelpers resourceHelper) throws FHIRSearchException {
+    private List<String> getDefaultIncludedResourceTypes(FHIRResourceHelpers resourceHelper, FHIRVersionParam fhirVersion) throws FHIRSearchException {
         List<String> resourceTypes = new ArrayList<>(CompartmentUtil.getCompartmentResourceTypes(PATIENT));
-        
+
         try {
-            List<String> supportedResourceTypes = FHIRConfigHelper.getSupportedResourceTypes();
-            // Examine the resource types to see if they support SEARCH
-            for (String resourceType: supportedResourceTypes) {
-                try {
-                    resourceHelper.validateInteraction(FHIRResourceHelpers.Interaction.SEARCH, resourceType);
-                } catch (FHIROperationException e) {
-                    if (LOG.isLoggable(Level.FINE)) {
-                        LOG.fine("Removing resourceType " + resourceType + " because it does not support SEARCH");
-                    }
-                    supportedResourceTypes.remove(resourceType);
-                }
-            }
+            PropertyGroup resourcesGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
+            ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(resourcesGroup, fhirVersion);
+            Set<String> supportedResourceTypes = configAdapter.getSupportedResourceTypes(Interaction.SEARCH);
+
             if (LOG.isLoggable(Level.FINE)) {
                 StringBuilder resourceTypeBuilder = new StringBuilder(supportedResourceTypes.size());
                 resourceTypeBuilder.append("supportedResourceTypes are: ");
@@ -364,17 +362,15 @@ private List<String> getDefaultIncludedResourceTypes(FHIRResourceHelpers resourc
                 }
                 LOG.fine(resourceTypeBuilder.toString());
             }
-            
-            // Need to have this if check to support server config files that do not specify resources
-            if (!supportedResourceTypes.isEmpty()) {
-                resourceTypes.retainAll(supportedResourceTypes);
-            }
+
+            resourceTypes.retainAll(supportedResourceTypes);
         } catch (Exception e) {
-            FHIRSearchException exceptionWithIssue = new FHIRSearchException("There has been an error retrieving the list of supported resource types of the $everything operation.", e);
+            FHIRSearchException exceptionWithIssue = new FHIRSearchException("There has been an error retrieving the list "
+                    + "of supported resource types for the $everything operation.", e);
             LOG.throwing(this.getClass().getName(), "doInvoke", exceptionWithIssue);
             throw exceptionWithIssue;
         }
-        
+
         if (LOG.isLoggable(Level.FINE)) {
             StringBuilder resourceTypeBuilder = new StringBuilder(resourceTypes.size());
             resourceTypeBuilder.append("resourceTypes are: ");
@@ -420,23 +416,23 @@ private static Uri uri(FHIROperationContext operationContext, String uriPath) {
                 .value(requestBaseURI + "/" + uriPath)
                 .build();
     }
-    
+
     private void addIncludesSearchParameters(String compartmentMemberType, MultivaluedMap<String, String> searchParameters)
     throws Exception {
         // Add in Location, Medication, Organization, and Practitioner resources which are pointed to
-        // from search parameters only if the request does not have a _type parameter or it does have a 
+        // from search parameters only if the request does not have a _type parameter or it does have a
         // _type parameter that includes these
-        
+
         List<String> allowedIncludes = new ArrayList<String>(10);
-        
+
         try {
             allowedIncludes = FHIRConfigHelper.getSearchPropertyRestrictions(compartmentMemberType, FHIRConfigHelper.SEARCH_PROPERTY_TYPE_INCLUDE);
         } catch (Exception e) {
             FHIRSearchException exceptionWithIssue = new FHIRSearchException("There has been an error retrieving the list of supported search parameters for the $everything operation.", e);
             LOG.throwing(this.getClass().getName(), "doInvoke", exceptionWithIssue);
-            throw exceptionWithIssue;      
+            throw exceptionWithIssue;
         }
-        
+
         // Add in _includes for all search parameters that are Location, Medication, Organization, or Practitioner
         if (compartmentMemberType.equals(ResourceType.Value.ADVERSE_EVENT.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "location", ResourceType.Value.LOCATION, searchParameters, allowedIncludes);
@@ -469,7 +465,7 @@ private void addIncludesSearchParameters(String compartmentMemberType, Multivalu
             addSearchParameterIfNotExcluded(compartmentMemberType, "author", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.CARE_PLAN.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "performer", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
-            addSearchParameterIfNotExcluded(compartmentMemberType, "performer", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes); 
+            addSearchParameterIfNotExcluded(compartmentMemberType, "performer", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.CARE_TEAM.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "participant", ResourceType.Value.ORGANIZATION,searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "participant", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
@@ -516,7 +512,7 @@ private void addIncludesSearchParameters(String compartmentMemberType, Multivalu
             addSearchParameterIfNotExcluded(compartmentMemberType, "organization", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.COVERAGE.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "payor", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
-            addSearchParameterIfNotExcluded(compartmentMemberType, "policy-holder", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes); 
+            addSearchParameterIfNotExcluded(compartmentMemberType, "policy-holder", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.COVERAGE_ELIGIBILITY_REQUEST.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "enterer", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "facility", ResourceType.Value.LOCATION, searchParameters, allowedIncludes);
@@ -552,7 +548,7 @@ private void addIncludesSearchParameters(String compartmentMemberType, Multivalu
             addSearchParameterIfNotExcluded(compartmentMemberType, "participant", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.EPISODE_OF_CARE.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "care-manager", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
-            addSearchParameterIfNotExcluded(compartmentMemberType, "organization", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes); 
+            addSearchParameterIfNotExcluded(compartmentMemberType, "organization", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.EXPLANATION_OF_BENEFIT.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "care-team", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "care-team", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
@@ -570,7 +566,7 @@ private void addIncludesSearchParameters(String compartmentMemberType, Multivalu
             addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.GOAL.value())) {
-            addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes); 
+            addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.GROUP.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "member", ResourceType.Value.MEDICATION, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "member", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
@@ -669,7 +665,7 @@ private void addIncludesSearchParameters(String compartmentMemberType, Multivalu
             addSearchParameterIfNotExcluded(compartmentMemberType, "performer", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "requester", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "requester", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
-            addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.LOCATION, searchParameters, allowedIncludes); 
+            addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.LOCATION, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.SPECIMEN.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "collector", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
             addSearchParameterIfNotExcluded(compartmentMemberType, "subject", ResourceType.Value.LOCATION, searchParameters, allowedIncludes);
@@ -685,19 +681,19 @@ private void addIncludesSearchParameters(String compartmentMemberType, Multivalu
             addSearchParameterIfNotExcluded(compartmentMemberType, "supplier", ResourceType.Value.ORGANIZATION, searchParameters, allowedIncludes);
         } else if (compartmentMemberType.equals(ResourceType.Value.VISION_PRESCRIPTION.value())) {
             addSearchParameterIfNotExcluded(compartmentMemberType, "prescriber", ResourceType.Value.PRACTITIONER, searchParameters, allowedIncludes);
-        } 
-            
+        }
+
         // BodyStructure, ResearchSubject, and RelatedPerson have no references to:
         // Location, Medication, Organization, and Practitioner
-        
-        // DeviceUseStatement, EnrollmentRequest, FamilyMemberHistory, ChargeItem, 
-        // ImmunizationEvaluation, ImmunizationRecommendation, MolecularSequence, 
-        // and NutritionOrder have no search parameters that reference: 
+
+        // DeviceUseStatement, EnrollmentRequest, FamilyMemberHistory, ChargeItem,
+        // ImmunizationEvaluation, ImmunizationRecommendation, MolecularSequence,
+        // and NutritionOrder have no search parameters that reference:
         // Location, Medication, Organization, and Practitioner
     }
-    
-    private void addSearchParameterIfNotExcluded(String compartmentMemberType, String code, 
-        ResourceType.Value subResourceType, MultivaluedMap<String, String> searchParameters, 
+
+    private void addSearchParameterIfNotExcluded(String compartmentMemberType, String code,
+        ResourceType.Value subResourceType, MultivaluedMap<String, String> searchParameters,
         List<String> allowedIncludes) {
         // Need to make sure the search parameter has not been excluded
         String parameterName = compartmentMemberType + ":" + code + ":" + subResourceType.value();
