From 8e6e915e2f4b0b73c604ea52e1fb417e5319fb61 Mon Sep 17 00:00:00 2001
From: Bryn Rhodes <bryn@databaseconsultinggroup.com>
Date: Tue, 24 Oct 2023 16:18:40 -0600
Subject: [PATCH] #1202: Fixed extension access reporting as a code filter
 instead of a property access #1202: Fixed property access not being reported
 correctly when it occurred after the initial query context for a retrieve
 #1202: Fixed data requirements not being reported correctly when a query
 source was itself a nested query #1202: Fixed duplicate data requirements
 being reported for property access not directly related to a retrieve #1202:
 Fixed enableResultTypes not working in some cases

---
 .../cql/cql2elm/Cql2ElmVisitor.java           | 105 +---------
 .../CqlPreprocessorElmCommonVisitor.java      | 110 ++++++++++
 .../elm/requirements/ElmDataRequirement.java  |  16 +-
 .../cql/elm/requirements/ElmRequirements.java |  36 +++-
 .../requirements/ElmRequirementsContext.java  |  65 ++++--
 .../requirements/ElmRequirementsVisitor.java  |  13 +-
 .../cql/elm/requirements/TypeResolver.java    |  59 ++++++
 .../fhir/DataRequirementsProcessor.java       |  72 ++++++-
 .../fhir/DataRequirementsProcessorTest.java   | 147 +++++++++++++-
 .../cql/SupplementalDataElements-3.1.000.cql  |   9 +-
 .../fhir/CMS143/cql/TestUnion.cql             |  41 ++++
 .../Library-EffectiveDataRequirements.json    | 189 ++++++++----------
 ...EncounterMP-EffectiveDataRequirements.json | 108 ++++++++++
 ...DEEthnicity-EffectiveDataRequirements.json |  31 +++
 ...ry-SDEPayer-EffectiveDataRequirements.json |  39 ++++
 ...ary-SDERace-EffectiveDataRequirements.json |  31 +++
 ...rary-SDESex-EffectiveDataRequirements.json |  46 +++++
 .../Library-EffectiveDataRequirements.json    |  79 +++++---
 .../CMS645-ModuleDefinitionLibrary.json       |  10 +-
 ...DeviceOrder-EffectiveDataRequirements.json |  89 +++++++++
 .../Library-EXMLogic-data-requirements.json   |  25 +--
 21 files changed, 1031 insertions(+), 289 deletions(-)
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/TestUnion.cql
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-QualifyingEncounterMP-EffectiveDataRequirements.json
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEEthnicity-EffectiveDataRequirements.json
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEPayer-EffectiveDataRequirements.json
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDERace-EffectiveDataRequirements.json
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDESex-EffectiveDataRequirements.json
 create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/DeviceOrder/Library-TestDeviceOrder-EffectiveDataRequirements.json

diff --git a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java
index 0f1c82a28..3a13ad5dc 100755
--- a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java
+++ b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java
@@ -27,14 +27,6 @@
 
 public class Cql2ElmVisitor extends CqlPreprocessorElmCommonVisitor {
     static final Logger logger = LoggerFactory.getLogger(Cql2ElmVisitor.class);
-    private boolean locate = false;
-    private boolean resultTypes = false;
-    private boolean dateRangeOptimization = false;
-    private boolean detailedErrors = false;
-    private boolean methodInvocation = true;
-    private boolean includeDeprecatedElements = false;
-    private boolean fromKeywordRequired = false;
-
     private final SystemMethodResolver systemMethodResolver;
 
     public void setLibraryInfo(LibraryInfo libraryInfo) {
@@ -65,91 +57,6 @@ public Cql2ElmVisitor(LibraryBuilder libraryBuilder) {
         this.systemMethodResolver = new SystemMethodResolver(this, libraryBuilder);
     }
 
-    public void enableLocators() {
-        locate = true;
-    }
-
-    public void disableLocators() {
-        locate = false;
-    }
-
-    public void enableResultTypes() {
-        resultTypes = true;
-    }
-
-    public void disableResultTypes() {
-        resultTypes = false;
-    }
-
-    public void enableDateRangeOptimization() {
-        dateRangeOptimization = true;
-    }
-
-    public void disableDateRangeOptimization() {
-        dateRangeOptimization = false;
-    }
-
-    public boolean getDateRangeOptimization() {
-        return dateRangeOptimization;
-    }
-
-    public void enableDetailedErrors() {
-        detailedErrors = true;
-    }
-
-    public void disableDetailedErrors() {
-        detailedErrors = false;
-    }
-
-    public boolean isDetailedErrorsEnabled() {
-        return detailedErrors;
-    }
-
-    public void enableMethodInvocation() {
-        methodInvocation = true;
-    }
-
-    public void disableMethodInvocation() {
-        methodInvocation = false;
-    }
-
-    public boolean isFromKeywordRequired() {
-        return fromKeywordRequired;
-    }
-
-    public void enableFromKeywordRequired() {
-        fromKeywordRequired = true;
-    }
-
-    public void disableFromKeywordRequired() {
-        fromKeywordRequired = false;
-    }
-
-    public void setTranslatorOptions(CqlCompilerOptions options) {
-        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableDateRangeOptimization)) {
-            this.enableDateRangeOptimization();
-        }
-        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableAnnotations)) {
-            this.enableAnnotations();
-        }
-        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableLocators)) {
-            this.enableLocators();
-        }
-        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableResultTypes)) {
-            this.enableResultTypes();
-        }
-        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableDetailedErrors)) {
-            this.enableDetailedErrors();
-        }
-        if (options.getOptions().contains(CqlCompilerOptions.Options.DisableMethodInvocation)) {
-            this.disableMethodInvocation();
-        }
-        if (options.getOptions().contains(CqlCompilerOptions.Options.RequireFromKeyword)) {
-            this.enableFromKeywordRequired();
-        }
-        libraryBuilder.setCompatibilityLevel(options.getCompatibilityLevel());
-    }
-
     public List<Retrieve> getRetrieves() {
         return retrieves;
     }
@@ -335,7 +242,7 @@ public TupleElementDefinition visitTupleElementDefinition(cqlParser.TupleElement
                 .withName(parseString(ctx.referentialIdentifier()))
                 .withElementType(parseTypeSpecifier(ctx.typeSpecifier()));
 
-        if (includeDeprecatedElements) {
+        if (getIncludeDeprecatedElements()) {
             result.setType(result.getElementType());
         }
 
@@ -3123,7 +3030,7 @@ else if (libraryBuilder.isCompatibleWith("1.5")) {
     @Override
     public Object visitSourceClause(cqlParser.SourceClauseContext ctx) {
         boolean hasFrom = "from".equals(ctx.getChild(0).getText());
-        if (!hasFrom && fromKeywordRequired) {
+        if (!hasFrom && isFromKeywordRequired()) {
             throw new IllegalArgumentException("The from keyword is required for queries.");
         }
 
@@ -3177,7 +3084,7 @@ public Object visitQuery(cqlParser.QueryContext ctx) {
                 }
 
                 Expression where = ctx.whereClause() != null ? (Expression) visit(ctx.whereClause()) : null;
-                if (dateRangeOptimization && where != null) {
+                if (getDateRangeOptimization() && where != null) {
                     for (AliasedQuerySource aqs : sources) {
                         where = optimizeDateRangeInQuery(where, aqs);
                     }
@@ -3960,7 +3867,7 @@ public Expression resolveFunctionOrQualifiedFunction(String identifier, cqlParse
 
                 // NOTE: FHIRPath method invocation
                 // If the target is an expression, resolve as a method invocation
-                if (target instanceof Expression && methodInvocation) {
+                if (target instanceof Expression && isMethodInvocationEnabled()) {
                     return systemMethodResolver.resolveMethod((Expression)target, identifier, paramListCtx, true);
                 }
 
@@ -4219,11 +4126,11 @@ private TrackBack getTrackBack(ParserRuleContext ctx) {
     }
 
     private void decorate(Element element, TrackBack tb) {
-        if (locate && tb != null) {
+        if (locatorsEnabled() && tb != null) {
             element.setLocator(tb.toLocator());
         }
 
-        if (resultTypes && element.getResultType() != null) {
+        if (resultTypesEnabled() && element.getResultType() != null) {
             if (element.getResultType() instanceof NamedType) {
                 element.setResultTypeName(libraryBuilder.dataTypeToQName(element.getResultType()));
             }
diff --git a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/preprocessor/CqlPreprocessorElmCommonVisitor.java b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/preprocessor/CqlPreprocessorElmCommonVisitor.java
index 9a49c8c02..6891a5ecf 100644
--- a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/preprocessor/CqlPreprocessorElmCommonVisitor.java
+++ b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/preprocessor/CqlPreprocessorElmCommonVisitor.java
@@ -45,6 +45,10 @@ public class CqlPreprocessorElmCommonVisitor extends cqlBaseVisitor {
     private int nextLocalId = 1;
     private boolean locate = false;
     private boolean resultTypes = false;
+    private boolean dateRangeOptimization = false;
+    private boolean methodInvocation = true;
+    private boolean fromKeywordRequired = false;
+
     private final List<Expression> expressions = new ArrayList<>();
     private boolean includeDeprecatedElements = false;
 
@@ -783,4 +787,110 @@ public static String normalizeWhitespace(String input) {
     public static boolean isStartingWithDigit(String header, int index) {
         return (index < header.length()) && Character.isDigit(header.charAt(index));
     }
+
+
+    public void enableLocators() {
+        locate = true;
+    }
+
+    public boolean locatorsEnabled() {
+        return locate;
+    }
+
+    public void disableLocators() {
+        locate = false;
+    }
+
+    public void enableResultTypes() {
+        resultTypes = true;
+    }
+
+    public void disableResultTypes() {
+        resultTypes = false;
+    }
+
+    public boolean resultTypesEnabled() {
+        return resultTypes;
+    }
+
+    public void enableDateRangeOptimization() {
+        dateRangeOptimization = true;
+    }
+
+    public void disableDateRangeOptimization() {
+        dateRangeOptimization = false;
+    }
+
+    public boolean getDateRangeOptimization() {
+        return dateRangeOptimization;
+    }
+
+    public void enableDetailedErrors() {
+        detailedErrors = true;
+    }
+
+    public void disableDetailedErrors() {
+        detailedErrors = false;
+    }
+
+    public boolean isDetailedErrorsEnabled() {
+        return detailedErrors;
+    }
+
+    public void enableMethodInvocation() {
+        methodInvocation = true;
+    }
+
+    public void disableMethodInvocation() {
+        methodInvocation = false;
+    }
+
+    public boolean isMethodInvocationEnabled() {
+        return methodInvocation;
+    }
+
+    public boolean isFromKeywordRequired() {
+        return fromKeywordRequired;
+    }
+
+    public void enableFromKeywordRequired() {
+        fromKeywordRequired = true;
+    }
+
+    public void disableFromKeywordRequired() {
+        fromKeywordRequired = false;
+    }
+
+    public boolean getIncludeDeprecatedElements() {
+        return includeDeprecatedElements;
+    }
+
+    public void setIncludeDeprecatedElements(boolean includeDeprecatedElements) {
+        this.includeDeprecatedElements = includeDeprecatedElements;
+    }
+
+    public void setTranslatorOptions(CqlCompilerOptions options) {
+        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableDateRangeOptimization)) {
+            this.enableDateRangeOptimization();
+        }
+        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableAnnotations)) {
+            this.enableAnnotations();
+        }
+        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableLocators)) {
+            this.enableLocators();
+        }
+        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableResultTypes)) {
+            this.enableResultTypes();
+        }
+        if (options.getOptions().contains(CqlCompilerOptions.Options.EnableDetailedErrors)) {
+            this.enableDetailedErrors();
+        }
+        if (options.getOptions().contains(CqlCompilerOptions.Options.DisableMethodInvocation)) {
+            this.disableMethodInvocation();
+        }
+        if (options.getOptions().contains(CqlCompilerOptions.Options.RequireFromKeyword)) {
+            this.enableFromKeywordRequired();
+        }
+        libraryBuilder.setCompatibilityLevel(options.getCompatibilityLevel());
+    }
 }
diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmDataRequirement.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmDataRequirement.java
index 012d2d68f..7c3384c0f 100644
--- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmDataRequirement.java
+++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmDataRequirement.java
@@ -79,7 +79,11 @@ else if (querySource instanceof LetClause) {
     private static ElmDataRequirement inferFrom(ElmDataRequirement requirement) {
         Retrieve inferredRetrieve = ElmCloner.clone(requirement.getRetrieve());
         ElmDataRequirement result = new ElmDataRequirement(requirement.libraryIdentifier, inferredRetrieve, requirement.getRetrieve());
-        result.propertySet = requirement.propertySet;
+        if (requirement.hasProperties()) {
+            for (Property p : requirement.getProperties()) {
+                result.addProperty(p);
+            }
+        }
         return result;
     }
 
@@ -127,6 +131,10 @@ public Iterable<Property> getProperties() {
         return propertySet;
     }
 
+    public boolean hasProperties() {
+        return propertySet != null;
+    }
+
     public void addProperty(Property property) {
         if (propertySet == null) {
             propertySet = new LinkedHashSet<Property>();
@@ -134,6 +142,12 @@ public void addProperty(Property property) {
         propertySet.add(property);
     }
 
+    public void removeProperty(Property property) {
+        if (propertySet != null) {
+            propertySet.remove(property);
+        }
+    }
+
     public void reportProperty(ElmPropertyRequirement propertyRequirement) {
         if (propertySet == null) {
             propertySet = new LinkedHashSet<Property>();
diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirements.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirements.java
index 01266b2e6..afa84ae59 100644
--- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirements.java
+++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirements.java
@@ -78,7 +78,7 @@ public Iterable<ElmRequirement> getRetrieves() {
     For expressions, unique by qualified name
     For data requirements, collapse according to the CQL specification: https://cql.hl7.org/05-languagesemantics.html#artifact-data-requirements
      */
-    public ElmRequirements collapse() {
+    public ElmRequirements collapse(ElmRequirementsContext context) {
         ElmRequirements result = new ElmRequirements(this.libraryIdentifier, this.element);
 
         // UsingDefs
@@ -243,6 +243,7 @@ public ElmRequirements collapse() {
         // Retrieves
         // Sort retrieves by type/profile to reduce search space
         LinkedHashMap<String, List<ElmRequirement>> retrievesByType = new LinkedHashMap<String, List<ElmRequirement>>();
+        List<ElmRequirement> unboundRequirements = new ArrayList<>();
         for (ElmRequirement r : getRetrieves()) {
             Retrieve retrieve = (Retrieve)r.getElement();
             if (retrieve.getDataType() != null) {
@@ -257,9 +258,40 @@ public ElmRequirements collapse() {
                 }
                 typeRetrieves.add(r);
             }
-            // TODO: What to do with data requirements that are captured to track unbound element references
+            else {
+                unboundRequirements.add(r);
+            }
+        }
+
+        // Distribute unbound property requirements
+        // If an ElmDataRequirement has a retrieve that does not have a dataType (i.e. it is not a direct data access layer retrieve
+        // but rather is the result of requirements inference), then distribute the property references it contains to
+        // all data layer-bound retrieves of the same type
+        // In other words, we can't unambiguously tie the property reference to any particular retrieve of that type,
+        // so apply it to all of them
+        for (ElmRequirement requirement : unboundRequirements) {
+            if (requirement instanceof ElmDataRequirement) {
+                ElmDataRequirement dataRequirement = (ElmDataRequirement)requirement;
+                if (dataRequirement.hasProperties()) {
+                    String typeUri =  context.getTypeResolver().getTypeUri(dataRequirement.getRetrieve().getResultType());
+                    if (typeUri != null) {
+                        List<ElmRequirement> typeRequirements = retrievesByType.get(typeUri);
+                        if (typeRequirements != null) {
+                            for (ElmRequirement typeRequirement : typeRequirements) {
+                                if (typeRequirement instanceof ElmDataRequirement) {
+                                    ElmDataRequirement typeDataRequirement = (ElmDataRequirement)typeRequirement;
+                                    for (Property p : dataRequirement.getProperties()) {
+                                        typeDataRequirement.addProperty(p);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
         }
 
+
         // Equivalent
             // Has the same context, type/profile, code path and date path
         // If two retrieves are "equivalent" they can be merged
diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsContext.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsContext.java
index ca9cff0d9..bab42ac7e 100644
--- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsContext.java
+++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsContext.java
@@ -3,7 +3,9 @@
 import org.cqframework.cql.cql2elm.*;
 import org.cqframework.cql.cql2elm.model.LibraryRef;
 import org.cqframework.cql.cql2elm.model.CompiledLibrary;
+import org.hl7.cql.model.ClassType;
 import org.hl7.cql.model.DataType;
+import org.hl7.cql.model.NamedType;
 import org.hl7.cql.model.NamespaceManager;
 import org.hl7.elm.r1.*;
 
@@ -467,6 +469,14 @@ else if (requirement instanceof ElmQueryRequirement) {
                 }
             }
         }
+        else if (requirement instanceof ElmOperatorRequirement) {
+            ElmOperatorRequirement operatorRequirement = (ElmOperatorRequirement)requirement;
+            for (ElmRequirement r : operatorRequirement.getRequirements()) {
+                if (inferredRequirements == null || !inferredRequirements.hasRequirement(r)) {
+                    reportRequirements(r, inferredRequirements);
+                }
+            }
+        }
         else {
             reportRequirement(requirement);
         }
@@ -485,22 +495,43 @@ else if (expression.getResultTypeSpecifier() instanceof NamedTypeSpecifier) {
         return null;
     }
 
+    private QName getProfiledType(DataType type) {
+        return typeResolver.dataTypeToProfileQName(type);
+    }
+
     private Map<QName, ElmDataRequirement> unboundDataRequirements = new LinkedHashMap<QName, ElmDataRequirement>();
 
-    private ElmDataRequirement getDataRequirementForTypeName(QName typeName) {
-        ElmDataRequirement requirement = unboundDataRequirements.get(typeName);
-        if (requirement == null) {
-            Retrieve retrieve = new Retrieve();
-            retrieve.setDataType(typeName);
-            if (typeName.getNamespaceURI() != null && typeName.getLocalPart() != null) {
-                retrieve.setTemplateId(typeName.getNamespaceURI() + "/" + typeName.getLocalPart());
+    private ElmDataRequirement getDataRequirementForTypeName(QName typeName, QName profiledTypeName) {
+        DataType type = null;
+        try {
+            type = typeResolver.resolveTypeName(typeName);
+        }
+        catch (Exception e) {
+            // ignore an exception resolving the type, just don't attempt to build an unbound requirement
+            // We should only be building unbound requirements for retrievable types, so if we can't determine
+            // retrievability, ignore the requirement
+        }
+
+        if (type != null && type instanceof ClassType && ((ClassType)type).isRetrievable()) {
+            ElmDataRequirement requirement = unboundDataRequirements.get(profiledTypeName != null ? profiledTypeName : typeName);
+            if (requirement == null) {
+                Retrieve retrieve = new Retrieve();
+                retrieve.setDataType(typeName);
+                if (profiledTypeName != null && profiledTypeName.getNamespaceURI() != null && profiledTypeName.getLocalPart() != null) {
+                    retrieve.setTemplateId(profiledTypeName.getNamespaceURI() + "/" + profiledTypeName.getLocalPart());
+                }
+                else if (typeName.getNamespaceURI() != null && typeName.getLocalPart() != null) {
+                    retrieve.setTemplateId(typeName.getNamespaceURI() + "/" + typeName.getLocalPart());
+                }
+                requirement = new ElmDataRequirement(getCurrentLibraryIdentifier(), retrieve);
+                unboundDataRequirements.put(typeName, requirement);
+                reportRequirement(requirement);
             }
-            requirement = new ElmDataRequirement(getCurrentLibraryIdentifier(), retrieve);
-            unboundDataRequirements.put(typeName, requirement);
-            reportRequirement(requirement);
+
+            return requirement;
         }
 
-        return requirement;
+        return null;
     }
 
     public ElmPropertyRequirement reportProperty(Property property) {
@@ -556,11 +587,13 @@ public ElmPropertyRequirement reportProperty(Property property) {
         else {
             QName typeName = getType(property.getSource());
             if (typeName != null) {
-                ElmDataRequirement requirement = getDataRequirementForTypeName(typeName);
-                ElmPropertyRequirement propertyRequirement = new ElmPropertyRequirement(getCurrentLibraryIdentifier(),
-                        property, property.getSource(), false);
-                requirement.reportProperty(propertyRequirement);
-                return propertyRequirement;
+                ElmDataRequirement requirement = getDataRequirementForTypeName(typeName, getProfiledType(property.getSource().getResultType()));
+                if (requirement != null) {
+                    ElmPropertyRequirement propertyRequirement = new ElmPropertyRequirement(getCurrentLibraryIdentifier(),
+                            property, property.getSource(), false);
+                    requirement.reportProperty(propertyRequirement);
+                    return propertyRequirement;
+                }
             }
         }
 
diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java
index e164538d5..fcd532ec6 100644
--- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java
+++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java
@@ -424,14 +424,14 @@ public ElmRequirement visitBinaryExpression(BinaryExpression elm, ElmRequirement
 
     @Override
     public ElmRequirement visitTernaryExpression(TernaryExpression elm, ElmRequirementsContext context) {
-        super.visitTernaryExpression(elm, context);
-        return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm);
+        ElmRequirement requirements = super.visitTernaryExpression(elm, context);
+        return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm).combine(requirements);
     }
 
     @Override
     public ElmRequirement visitNaryExpression(NaryExpression elm, ElmRequirementsContext context) {
-        super.visitNaryExpression(elm, context);
-        return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm);
+        ElmRequirement requirements = super.visitNaryExpression(elm, context);
+        return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm).combine(requirements);
     }
 
     @Override
@@ -1276,6 +1276,11 @@ public ElmRequirement visitChildren(AliasedQuerySource elm, ElmRequirementsConte
         finally {
             aliasContext = context.getCurrentQueryContext().exitAliasDefinitionContext(result);
         }
+        // If this is an operator requirement, report it directly to the context, otherwise the context it contains will not be reported
+        // since query requirements are abstracted to an ElmDataRequirement
+        if (result instanceof ElmOperatorRequirement) {
+            context.reportRequirements(result, null);
+        }
         return aliasContext.getRequirements();
     }
 
diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/TypeResolver.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/TypeResolver.java
index da088ff57..9cf116b5d 100644
--- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/TypeResolver.java
+++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/TypeResolver.java
@@ -4,6 +4,7 @@
 import org.cqframework.cql.cql2elm.model.Model;
 import org.hl7.cql.model.*;
 import org.hl7.elm.r1.*;
+import org.hl7.elm_modelinfo.r1.ModelInfo;
 
 import javax.xml.namespace.QName;
 import java.util.ArrayList;
@@ -21,6 +22,64 @@ public LibraryManager getLibraryManager() {
         return libraryManager;
     }
 
+    public String getTypeUri(DataType type) {
+        if (type instanceof ListType) {
+            return getTypeUri(((ListType)type).getElementType());
+        }
+        if (type instanceof ClassType) {
+            ClassType classType = (ClassType)type;
+            if (classType.getIdentifier() != null) {
+                return classType.getIdentifier();
+            }
+        }
+
+        if (type instanceof NamedType) {
+            return dataTypeToQName(type).getLocalPart();
+        }
+
+        return null;
+    }
+
+    public QName dataTypeToProfileQName(DataType type) {
+        if (type instanceof ClassType) {
+            ClassType classType = (ClassType)type;
+            if (classType.getIdentifier() != null) {
+                int tailIndex = classType.getIdentifier().lastIndexOf('/');
+                if (tailIndex > 0) {
+                    String tail = classType.getIdentifier().substring(tailIndex + 1);
+                    String namespace = classType.getIdentifier().substring(0, tailIndex);
+                    return new QName(namespace, tail);
+                }
+            }
+        }
+
+        if (type instanceof NamedType) {
+            return dataTypeToQName(type);
+        }
+
+        return null;
+    }
+    /**
+     * Return the QName for the given type (without target mapping)
+     * This is to preserve data requirements reporting for profiled types when
+     * reported against unbound data requirements. This will only work when
+     * the ELM tree has type references (which typically means it came
+     * straight from the translator, although type resolution could be
+     * performed by a visitor on an ELM tree).
+     * @param type The data type to determine a QName for
+     * @return The QName for the given type (without target mapping)
+     */
+    public QName dataTypeToQName(DataType type) {
+        if (type instanceof NamedType) {
+            NamedType namedType = (NamedType)type;
+            ModelInfo modelInfo = libraryManager.getModelManager().resolveModel(namedType.getNamespace()).getModelInfo();
+            return new QName(modelInfo.getUrl(), namedType.getSimpleName());
+        }
+
+        // ERROR:
+        throw new IllegalArgumentException("A named type is required in this context.");
+    }
+
     public DataType resolveTypeName(QName typeName) {
         if (typeName == null) {
             throw new IllegalArgumentException("typeName is required");
diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessor.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessor.java
index d5d8e6cc9..d450d9a9c 100644
--- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessor.java
+++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessor.java
@@ -31,6 +31,7 @@
 import org.opencds.cqf.cql.engine.fhir.converter.FhirTypeConverterFactory;
 
 import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.ZonedDateTime;
@@ -175,12 +176,81 @@ public Library gatherDataRequirements(LibraryManager libraryManager, CompiledLib
 
         // Collapse the requirements
         if (options.getCollapseDataRequirements()) {
-            requirements = requirements.collapse();
+            for (ElmRequirement requirement : requirements.getRequirements()) {
+                collapseExtensionReference(context, requirement);
+            }
+            requirements = requirements.collapse(context);
         }
 
         return createLibrary(context, requirements, translatedLibrary.getIdentifier(), expressionDefs, parameters, evaluationDateTime, includeLogicDefinitions);
     }
 
+    /**
+     * If the requirement has property references to `url` and `extension`, and a code filter on `url` to a literal extension value,
+     * replace the `url` and `extension` property references with a new property reference to the tail of the extension
+     * Also remove `us-core-` and `qicore-` as wellknown prefixes
+     * TODO: Use the structure definition element slice name as the name of the property, rather than the hard-coded removal
+     * of well-known prefixes
+     * @param requirement
+     */
+    private void collapseExtensionReference(ElmRequirementsContext context, ElmRequirement requirement) {
+        if (requirement instanceof ElmDataRequirement) {
+            ElmDataRequirement dataRequirement = (ElmDataRequirement)requirement;
+            if (dataRequirement.hasProperties()) {
+                Property urlProperty = null;
+                Property extensionProperty = null;
+                for (Property p : dataRequirement.getProperties()) {
+                    if (p.getPath().equals("url")) {
+                        urlProperty = p;
+                        continue;
+                    }
+
+                    if (p.getPath().equals("extension")) {
+                        extensionProperty = p;
+                        continue;
+                    }
+                }
+
+                if (urlProperty != null) {
+                    Retrieve r = dataRequirement.getRetrieve();
+                    if (r != null) {
+                        CodeFilterElement extensionFilterElement = null;
+                        org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent extensionFilterComponent = null;
+                        for (CodeFilterElement cfe : r.getCodeFilter()) {
+                            org.hl7.fhir.r5.model.DataRequirement.DataRequirementCodeFilterComponent cfc =
+                                    toCodeFilterComponent(context, dataRequirement.getLibraryIdentifier(), cfe.getProperty(), cfe.getValue());
+
+                            if (cfc.hasPath() && cfc.hasCode() && "url".equals(cfc.getPath()) && cfc.getCodeFirstRep().hasCode() && cfc.getCodeFirstRep().getCode().startsWith("http://")) {
+                                extensionFilterElement = cfe;
+                                extensionFilterComponent = cfc;
+                                break;
+                            }
+                        }
+
+                        if (extensionFilterElement != null && extensionFilterComponent != null) {
+                            String extensionName = extensionFilterComponent.getCodeFirstRep().getCode();
+                            int tailIndex = extensionName.lastIndexOf("/");
+                            if (tailIndex > 0) {
+                                extensionName = extensionName.substring(tailIndex + 1);
+                            }
+                            if (extensionName.startsWith("us-core-")) {
+                                extensionName = extensionName.substring(8);
+                            }
+                            if (extensionName.startsWith("qicore-")) {
+                                extensionName = extensionName.substring(7);
+                            }
+                            r.getCodeFilter().remove(extensionFilterElement);
+                            dataRequirement.removeProperty(urlProperty);
+                            if (extensionProperty != null) {
+                                dataRequirement.removeProperty(extensionProperty);
+                            }
+                            dataRequirement.addProperty(new Property().withPath(extensionName));
+                        }
+                    }
+                }
+            }
+        }
+    }
     private Library createLibrary(ElmRequirementsContext context, ElmRequirements requirements,
             VersionedIdentifier libraryIdentifier, Iterable<ExpressionDef> expressionDefs,
             Map<String, Object> parameters, ZonedDateTime evaluationDateTime, boolean includeLogicDefinitions) {
diff --git a/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java b/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java
index 057e98825..29b5c8638 100644
--- a/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java
+++ b/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java
@@ -527,11 +527,34 @@ private Setup setupUncollapsedDataRequirementsGather(String fileName, CqlCompile
         return setup(fileName, cqlTranslatorOptions);
     }
 
+    private Setup setupUncollapsedDataRequirementsGather(NamespaceInfo namespace, String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
+        cqlTranslatorOptions.setCollapseDataRequirements(false);
+        cqlTranslatorOptions.setAnalyzeDataRequirements(false);
+        return setup(namespace, fileName, cqlTranslatorOptions);
+    }
+
+    private Setup setupUncollapsedDataRequirementsAnalysis(String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
+        cqlTranslatorOptions.setCollapseDataRequirements(false);
+        cqlTranslatorOptions.setAnalyzeDataRequirements(true);
+        return setup(fileName, cqlTranslatorOptions);
+    }
+
+    private Setup setupUncollapsedDataRequirementsAnalysis(NamespaceInfo namespace, String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
+        cqlTranslatorOptions.setCollapseDataRequirements(false);
+        cqlTranslatorOptions.setAnalyzeDataRequirements(true);
+        return setup(namespace, fileName, cqlTranslatorOptions);
+    }
+
     private Setup setupDataRequirementsGather(String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
         cqlTranslatorOptions.setCollapseDataRequirements(true);
         cqlTranslatorOptions.setAnalyzeDataRequirements(false);
         return setup(fileName, cqlTranslatorOptions);
+    }
 
+    private Setup setupDataRequirementsGather(NamespaceInfo namespace, String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
+        cqlTranslatorOptions.setCollapseDataRequirements(true);
+        cqlTranslatorOptions.setAnalyzeDataRequirements(false);
+        return setup(namespace, fileName, cqlTranslatorOptions);
     }
 
     private Setup setupDataRequirementsAnalysis(String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
@@ -540,6 +563,12 @@ private Setup setupDataRequirementsAnalysis(String fileName, CqlCompilerOptions
         return setup(fileName, cqlTranslatorOptions);
     }
 
+    private Setup setupDataRequirementsAnalysis(NamespaceInfo namespace, String fileName, CqlCompilerOptions cqlTranslatorOptions) throws IOException {
+        cqlTranslatorOptions.setCollapseDataRequirements(true);
+        cqlTranslatorOptions.setAnalyzeDataRequirements(true);
+        return setup(namespace, fileName, cqlTranslatorOptions);
+    }
+
     private org.hl7.fhir.r5.model.Library getModuleDefinitionLibrary(Setup setup, CqlCompilerOptions cqlTranslatorOptions, Map<String, Object> parameters) {
         DataRequirementsProcessor dqReqTrans = new DataRequirementsProcessor();
         org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = dqReqTrans.gatherDataRequirements(setup.manager(), setup.library(), cqlTranslatorOptions, null, parameters, false,false);
@@ -1684,16 +1713,123 @@ public void TestCMS645() throws IOException {
 
     @Test
     public void TestCMS143() throws IOException {
-        CqlCompilerOptions compilerOptions = getCompilerOptions();
-        compilerOptions.setAnalyzeDataRequirements(false);
-        var manager =  setupDataRequirementsAnalysis("CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
-        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, new HashMap<String, Object>(), ZonedDateTime.of(2023, 1, 16, 0, 0, 0, 0, ZoneId.of("UTC")));
+        CqlCompilerOptions compilerOptions = CqlCompilerOptions.defaultOptions();
+        compilerOptions.getOptions().add(CqlCompilerOptions.Options.EnableResultTypes);
+        Set<String> expressions = new HashSet<>();
+        //expressions.add("Qualifying Encounter");
+        //expressions.add("Qualifying Encounter During Measurement Period");
+        //expressions.add("Qualifying Encounter During Measurement Period Expanded");
+        expressions.add("Initial Population");
+        expressions.add("Denominator");
+        expressions.add("Denominator Exception");
+        expressions.add("Numerator");
+        expressions.add("SDE Ethnicity");
+        expressions.add("SDE Race");
+        expressions.add("SDE Sex");
+        expressions.add("SDE Payer");
+        //var manager = setupUncollapsedDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/TestUnion.cql", compilerOptions);
+        var manager = setupDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
+        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, expressions);
         assertNotNull(moduleDefinitionLibrary);
         assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-EffectiveDataRequirements.json");
 
         //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
     }
 
+    @Test
+    public void TestSDESex() throws IOException {
+        CqlCompilerOptions compilerOptions = CqlCompilerOptions.defaultOptions();
+        compilerOptions.getOptions().add(CqlCompilerOptions.Options.EnableResultTypes);
+        Set<String> expressions = new HashSet<>();
+        expressions.add("SDE Sex");
+        var manager = setupDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
+        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, expressions);
+        assertNotNull(moduleDefinitionLibrary);
+        assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-SDESex-EffectiveDataRequirements.json");
+
+        // Has direct reference codes to M#http://hl7.org/fhir/v3/AdministrativeGender and F#http://hl7.org/fhir/v3/AdministrativeGender
+        // Has relatedArtifact to code system http://hl7.org/fhir/v3/AdministrativeGender
+        // Has relatedArtifact to Library SDE
+        // Has one and only one DataRequirement for Patient with profile QICore Patient and mustSupport gender
+
+        //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
+    }
+
+    @Test
+    public void TestSDEPayer() throws IOException {
+        CqlCompilerOptions compilerOptions = CqlCompilerOptions.defaultOptions();
+        compilerOptions.getOptions().add(CqlCompilerOptions.Options.EnableResultTypes);
+        Set<String> expressions = new HashSet<>();
+        expressions.add("SDE Payer");
+        var manager = setupDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
+        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, expressions);
+        assertNotNull(moduleDefinitionLibrary);
+        assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-SDEPayer-EffectiveDataRequirements.json");
+
+        // Has relatedArtifact to Library SDE
+        // Has relatedArtifact to Value Set Payer
+        // Has one and only one DatRequirement for Coverage with the Payer Type value set and mustSupport type and period
+
+        //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
+    }
+
+    @Test
+    public void TestSDEEthnicity() throws IOException {
+        CqlCompilerOptions compilerOptions = CqlCompilerOptions.defaultOptions();
+        compilerOptions.getOptions().add(CqlCompilerOptions.Options.EnableResultTypes);
+        Set<String> expressions = new HashSet<>();
+        expressions.add("SDE Ethnicity");
+        var manager = setupDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
+        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, expressions);
+        assertNotNull(moduleDefinitionLibrary);
+        assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-SDEEthnicity-EffectiveDataRequirements.json");
+
+        // Has relatedArtifact to Library SDE
+        // Has one and only one DatRequirement for Patient with the QICore Profile and mustSupport ethnicity
+
+        //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
+    }
+
+    @Test
+    public void TestSDERace() throws IOException {
+        CqlCompilerOptions compilerOptions = CqlCompilerOptions.defaultOptions();
+        compilerOptions.getOptions().add(CqlCompilerOptions.Options.EnableResultTypes);
+        Set<String> expressions = new HashSet<>();
+        expressions.add("SDE Race");
+        var manager = setupDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
+        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, expressions);
+        assertNotNull(moduleDefinitionLibrary);
+        assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-SDERace-EffectiveDataRequirements.json");
+
+        // Has relatedArtifact to Library SDE
+        // Has one and only one DatRequirement for Patient with the QICore Profile and mustSupport race
+
+        //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
+    }
+
+    @Test
+    public void TestQualifyingEncounterMP() throws IOException {
+        CqlCompilerOptions compilerOptions = CqlCompilerOptions.defaultOptions();
+        compilerOptions.getOptions().add(CqlCompilerOptions.Options.EnableResultTypes);
+        Set<String> expressions = new HashSet<>();
+        expressions.add("Qualifying Encounter During Measurement Period");
+        var manager = setupDataRequirementsAnalysis(new NamespaceInfo("gov.healthit.ecqi.ecqms", "http://ecqi.healthit.gov/ecqms"), "CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", compilerOptions);
+        org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, expressions);
+        assertNotNull(moduleDefinitionLibrary);
+        assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-QualifyingEncounterMP-EffectiveDataRequirements.json");
+
+        // Has direct reference codes to VR and AMB
+        // Has relatedArtifact to ActCode code system
+        // Has relatedArtifact to Office Visit ValueSet
+        // Has relatedArtifact to Opthalmological Services ValueSet
+        // Has relatedArtifact to Outpatient Consultation ValueSet
+        // Has relatedArtifact to Nursing Facility Visit ValueSet
+        // Has relatedArtifact to Care Services in Long-Term Residentail Facility ValueSet
+        // Has 5 DataRequirements for Encounter with the QICore Encounter Profile and mustSupport type, period, and class, one for each ValueSet
+
+        //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
+    }
+
     @Test
     public void TestCMS149() throws IOException {
         CqlCompilerOptions compilerOptions = getCompilerOptions();
@@ -1725,7 +1861,8 @@ public void TestDeviceOrder() throws IOException {
         var manager = setupDataRequirementsGather("DeviceOrder/TestDeviceOrder.cql", compilerOptions);
         org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(manager, compilerOptions, new HashMap<String, Object>(), ZonedDateTime.of(2023, 1, 16, 0, 0, 0, 0, ZoneId.of("UTC")), true);
         assertNotNull(moduleDefinitionLibrary);
-        outputModuleDefinitionLibrary(moduleDefinitionLibrary);
+        assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "DeviceOrder/Library-TestDeviceOrder-EffectiveDataRequirements.json");
+        //outputModuleDefinitionLibrary(moduleDefinitionLibrary);
 
         List<Extension> logicDefinitions = moduleDefinitionLibrary.getExtensionsByUrl("http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-logicDefinition");
         assertTrue(logicDefinitions != null);
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql
index 04be4f8a1..09f156fe8 100644
--- a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql
@@ -13,11 +13,16 @@ using QICore version '4.1.1'
 
 include FHIRHelpers version '4.1.000' called FHIRHelpers
 
+codesystem "AdministrativeGender": 'http://hl7.org/fhir/v3/AdministrativeGender'
+
 valueset "Ethnicity": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.837'
 valueset "ONC Administrative Sex": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1'
 valueset "Payer": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591'
 valueset "Race": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.836'
 
+code "M": 'M' from "AdministrativeGender" display 'Male'
+code "F": 'F' from "AdministrativeGender" display 'Female'
+
 context Patient
 
 define "SDE Ethnicity":
@@ -43,7 +48,7 @@ define "SDE Race":
 
 define "SDE Sex":
   case
-      when Patient.gender = 'male' then Code { code: 'M', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Male' }
-      when Patient.gender = 'female' then Code { code: 'F', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Female' }
+      when Patient.gender = 'male' then "M"
+      when Patient.gender = 'female' then "F"
       else null
     end
\ No newline at end of file
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/TestUnion.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/TestUnion.cql
new file mode 100644
index 000000000..e2ebae52a
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/TestUnion.cql
@@ -0,0 +1,41 @@
+library TestUnion version '0.0.003'
+
+using QICore version '4.1.1'
+
+include FHIRHelpers version '4.1.000' called FHIRHelpers
+include CQMCommon version '1.0.000' called CQMCommon
+include FHIRCommon version '4.1.000' called FHIRCommon
+include QICoreCommon version '1.2.000' called QICoreCommon
+
+codesystem "ActCode": 'http://terminology.hl7.org/CodeSystem/v3-ActCode'
+
+valueset "Office Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001'
+valueset "Ophthalmological Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285'
+valueset "Outpatient Consultation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008'
+
+code "virtual": 'VR' from "ActCode" display 'virtual'
+code "AMB": 'AMB' from "ActCode" display 'Ambulatory'
+
+parameter "Measurement Period" Interval<DateTime>
+
+context Patient
+
+define "Qualifying Encounter":
+  ["Encounter": "Office Visit"]
+    union ["Encounter": "Ophthalmological Services"]
+    union ["Encounter": "Outpatient Consultation"]
+
+define "Qualifying Encounter During Measurement Period":
+  "Qualifying Encounter" QualifyingEncounter
+    where QualifyingEncounter.period during "Measurement Period"
+      and QualifyingEncounter.class !~ "virtual"
+      and QualifyingEncounter.class ~ "AMB"
+
+define "Qualifying Encounter During Measurement Period Expanded":
+  (["Encounter": "Office Visit"]
+    union ["Encounter": "Ophthalmological Services"]
+    union ["Encounter": "Outpatient Consultation"]
+  ) QualifyingEncounter
+    where QualifyingEncounter.period during "Measurement Period"
+      and QualifyingEncounter.class !~ "virtual"
+      and QualifyingEncounter.class ~ "AMB"
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json
index 109ba8aef..5c842e31a 100644
--- a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json
@@ -1,6 +1,20 @@
 {
   "resourceType": "Library",
   "extension": [ {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
+    "valueCoding": {
+      "system": "http://hl7.org/fhir/v3/AdministrativeGender",
+      "code": "M",
+      "display": "Male"
+    }
+  }, {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
+    "valueCoding": {
+      "system": "http://hl7.org/fhir/v3/AdministrativeGender",
+      "code": "F",
+      "display": "Female"
+    }
+  }, {
     "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
     "valueCoding": {
       "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
@@ -23,73 +37,61 @@
     } ]
   },
   "relatedArtifact": [ {
-    "type": "depends-on",
-    "display": "QICore model information",
-    "resource": "http://hl7.org/fhir/Library/QICore-ModelInfo"
-  }, {
-    "type": "depends-on",
-    "display": "Library FHIRHelpers",
-    "resource": "Library/FHIRHelpers|4.1.000"
-  }, {
     "type": "depends-on",
     "display": "Library SDE",
-    "resource": "Library/SupplementalDataElements|3.1.000"
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/SupplementalDataElements|3.1.000"
   }, {
     "type": "depends-on",
-    "display": "Library CQMCommon",
-    "resource": "Library/CQMCommon|1.0.000"
+    "display": "Library FHIRHelpers",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/FHIRHelpers|4.1.000"
   }, {
     "type": "depends-on",
-    "display": "Library FHIRCommon",
-    "resource": "Library/FHIRCommon|4.1.000"
+    "display": "Library QICoreCommon",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/QICoreCommon|1.2.000"
   }, {
     "type": "depends-on",
-    "display": "Library QICoreCommon",
-    "resource": "Library/QICoreCommon|1.2.000"
+    "display": "Code system AdministrativeGender",
+    "resource": "http://hl7.org/fhir/v3/AdministrativeGender"
   }, {
     "type": "depends-on",
     "display": "Code system ActCode",
     "resource": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
-  }, {
-    "type": "depends-on",
-    "display": "Value set Care Services in Long-Term Residential Facility",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014"
   }, {
     "type": "depends-on",
     "display": "Value set Cup to Disc Ratio",
     "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1333"
   }, {
     "type": "depends-on",
-    "display": "Value set Face-to-Face Interaction",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048"
+    "display": "Value set Office Visit",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001"
   }, {
     "type": "depends-on",
-    "display": "Value set Medical Reason",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1007"
+    "display": "Value set Ophthalmological Services",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Outpatient Consultation",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008"
   }, {
     "type": "depends-on",
     "display": "Value set Nursing Facility Visit",
     "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012"
   }, {
     "type": "depends-on",
-    "display": "Value set Office Visit",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001"
+    "display": "Value set Care Services in Long-Term Residential Facility",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014"
   }, {
     "type": "depends-on",
-    "display": "Value set Ophthalmological Services",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285"
+    "display": "Value set Primary Open-Angle Glaucoma",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.326"
   }, {
     "type": "depends-on",
     "display": "Value set Optic Disc Exam for Structural Abnormalities",
     "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1334"
   }, {
     "type": "depends-on",
-    "display": "Value set Outpatient Consultation",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008"
-  }, {
-    "type": "depends-on",
-    "display": "Value set Primary Open-Angle Glaucoma",
-    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.326"
+    "display": "Value set Payer",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591"
   } ],
   "parameter": [ {
     "name": "Measurement Period",
@@ -97,30 +99,6 @@
     "min": 0,
     "max": "1",
     "type": "Period"
-  }, {
-    "name": "Patient",
-    "use": "out",
-    "min": 0,
-    "max": "1",
-    "type": "Resource"
-  }, {
-    "name": "SDE Ethnicity",
-    "use": "out",
-    "min": 0,
-    "max": "1",
-    "type": "Resource"
-  }, {
-    "name": "SDE Payer",
-    "use": "out",
-    "min": 0,
-    "max": "*",
-    "type": "Resource"
-  }, {
-    "name": "SDE Race",
-    "use": "out",
-    "min": 0,
-    "max": "1",
-    "type": "Resource"
   }, {
     "name": "SDE Sex",
     "use": "out",
@@ -128,19 +106,7 @@
     "max": "1",
     "type": "Coding"
   }, {
-    "name": "Qualifying Encounter During Measurement Period",
-    "use": "out",
-    "min": 0,
-    "max": "*",
-    "type": "Resource"
-  }, {
-    "name": "Primary Open Angle Glaucoma Encounter",
-    "use": "out",
-    "min": 0,
-    "max": "*",
-    "type": "Resource"
-  }, {
-    "name": "Initial Population",
+    "name": "Numerator",
     "use": "out",
     "min": 0,
     "max": "1",
@@ -152,72 +118,73 @@
     "max": "1",
     "type": "boolean"
   }, {
-    "name": "Medical Reason for Not Performing Cup to Disc Ratio",
-    "use": "out",
-    "min": 0,
-    "max": "*",
-    "type": "Resource"
-  }, {
-    "name": "Medical Reason for Not Performing Optic Disc Exam",
+    "name": "SDE Payer",
     "use": "out",
     "min": 0,
     "max": "*",
     "type": "Resource"
   }, {
-    "name": "Denominator Exceptions",
+    "name": "Initial Population",
     "use": "out",
     "min": 0,
     "max": "1",
     "type": "boolean"
   }, {
-    "name": "Cup to Disc Ratio Performed with Result",
-    "use": "out",
-    "min": 0,
-    "max": "*",
-    "type": "Resource"
-  }, {
-    "name": "Optic Disc Exam Performed with Result",
+    "name": "SDE Ethnicity",
     "use": "out",
     "min": 0,
-    "max": "*",
+    "max": "1",
     "type": "Resource"
   }, {
-    "name": "Numerator",
+    "name": "SDE Race",
     "use": "out",
     "min": 0,
     "max": "1",
-    "type": "boolean"
+    "type": "Resource"
   } ],
   "dataRequirement": [ {
-    "type": "Patient",
-    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ]
-  }, {
     "type": "Patient",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
-    "mustSupport": [ "url", "extension" ],
+    "mustSupport": [ "gender", "gender.value", "birthDate", "birthDate.value", "ethnicity", "race" ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
     "codeFilter": [ {
-      "path": "url",
-      "code": [ {
-        "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"
-      } ]
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001"
     } ]
   }, {
-    "type": "Patient",
-    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
-    "mustSupport": [ "url", "extension" ],
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
     "codeFilter": [ {
-      "path": "url",
-      "code": [ {
-        "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race"
-      } ]
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285"
     } ]
   }, {
-    "type": "Coverage",
-    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-coverage" ],
-    "mustSupport": [ "type", "period" ],
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
     "codeFilter": [ {
       "path": "type",
-      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591"
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008"
+    } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012"
+    } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014"
     } ]
   }, {
     "type": "Condition",
@@ -243,5 +210,13 @@
       "path": "code",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1334"
     } ]
+  }, {
+    "type": "Coverage",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-coverage" ],
+    "mustSupport": [ "type", "period" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591"
+    } ]
   } ]
 }
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-QualifyingEncounterMP-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-QualifyingEncounterMP-EffectiveDataRequirements.json
new file mode 100644
index 000000000..f44ffc722
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-QualifyingEncounterMP-EffectiveDataRequirements.json
@@ -0,0 +1,108 @@
+{
+  "resourceType": "Library",
+  "extension": [ {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
+    "valueCoding": {
+      "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+      "code": "VR",
+      "display": "virtual"
+    }
+  }, {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
+    "valueCoding": {
+      "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
+      "code": "AMB",
+      "display": "Ambulatory"
+    }
+  } ],
+  "status": "active",
+  "type": {
+    "coding": [ {
+      "system": "http://terminology.hl7.org/CodeSystem/library-type",
+      "code": "module-definition"
+    } ]
+  },
+  "relatedArtifact": [ {
+    "type": "depends-on",
+    "display": "Library FHIRHelpers",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/FHIRHelpers|4.1.000"
+  }, {
+    "type": "depends-on",
+    "display": "Code system ActCode",
+    "resource": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Office Visit",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Ophthalmological Services",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Outpatient Consultation",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Nursing Facility Visit",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Care Services in Long-Term Residential Facility",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014"
+  } ],
+  "parameter": [ {
+    "name": "Measurement Period",
+    "use": "in",
+    "min": 0,
+    "max": "1",
+    "type": "Period"
+  }, {
+    "name": "Qualifying Encounter During Measurement Period",
+    "use": "out",
+    "min": 0,
+    "max": "*",
+    "type": "Resource"
+  } ],
+  "dataRequirement": [ {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001"
+    } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285"
+    } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008"
+    } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012"
+    } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "class" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014"
+    } ]
+  } ]
+}
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEEthnicity-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEEthnicity-EffectiveDataRequirements.json
new file mode 100644
index 000000000..80c67c9ff
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEEthnicity-EffectiveDataRequirements.json
@@ -0,0 +1,31 @@
+{
+  "resourceType": "Library",
+  "status": "active",
+  "type": {
+    "coding": [ {
+      "system": "http://terminology.hl7.org/CodeSystem/library-type",
+      "code": "module-definition"
+    } ]
+  },
+  "relatedArtifact": [ {
+    "type": "depends-on",
+    "display": "Library SDE",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/SupplementalDataElements|3.1.000"
+  }, {
+    "type": "depends-on",
+    "display": "Library FHIRHelpers",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/FHIRHelpers|4.1.000"
+  } ],
+  "parameter": [ {
+    "name": "SDE Ethnicity",
+    "use": "out",
+    "min": 0,
+    "max": "1",
+    "type": "Resource"
+  } ],
+  "dataRequirement": [ {
+    "type": "Patient",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
+    "mustSupport": [ "ethnicity" ]
+  } ]
+}
\ No newline at end of file
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEPayer-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEPayer-EffectiveDataRequirements.json
new file mode 100644
index 000000000..32c4d76e2
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDEPayer-EffectiveDataRequirements.json
@@ -0,0 +1,39 @@
+{
+  "resourceType": "Library",
+  "status": "active",
+  "type": {
+    "coding": [ {
+      "system": "http://terminology.hl7.org/CodeSystem/library-type",
+      "code": "module-definition"
+    } ]
+  },
+  "relatedArtifact": [ {
+    "type": "depends-on",
+    "display": "Library SDE",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/SupplementalDataElements|3.1.000"
+  }, {
+    "type": "depends-on",
+    "display": "Library FHIRHelpers",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/FHIRHelpers|4.1.000"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Payer",
+    "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591"
+  } ],
+  "parameter": [ {
+    "name": "SDE Payer",
+    "use": "out",
+    "min": 0,
+    "max": "*",
+    "type": "Resource"
+  } ],
+  "dataRequirement": [ {
+    "type": "Coverage",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-coverage" ],
+    "mustSupport": [ "type", "period" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591"
+    } ]
+  } ]
+}
\ No newline at end of file
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDERace-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDERace-EffectiveDataRequirements.json
new file mode 100644
index 000000000..29cac7c10
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDERace-EffectiveDataRequirements.json
@@ -0,0 +1,31 @@
+{
+  "resourceType": "Library",
+  "status": "active",
+  "type": {
+    "coding": [ {
+      "system": "http://terminology.hl7.org/CodeSystem/library-type",
+      "code": "module-definition"
+    } ]
+  },
+  "relatedArtifact": [ {
+    "type": "depends-on",
+    "display": "Library SDE",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/SupplementalDataElements|3.1.000"
+  }, {
+    "type": "depends-on",
+    "display": "Library FHIRHelpers",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/FHIRHelpers|4.1.000"
+  } ],
+  "parameter": [ {
+    "name": "SDE Race",
+    "use": "out",
+    "min": 0,
+    "max": "1",
+    "type": "Resource"
+  } ],
+  "dataRequirement": [ {
+    "type": "Patient",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
+    "mustSupport": [ "race" ]
+  } ]
+}
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDESex-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDESex-EffectiveDataRequirements.json
new file mode 100644
index 000000000..b52531f3d
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-SDESex-EffectiveDataRequirements.json
@@ -0,0 +1,46 @@
+{
+  "resourceType": "Library",
+  "extension": [ {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
+    "valueCoding": {
+      "system": "http://hl7.org/fhir/v3/AdministrativeGender",
+      "code": "M",
+      "display": "Male"
+    }
+  }, {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
+    "valueCoding": {
+      "system": "http://hl7.org/fhir/v3/AdministrativeGender",
+      "code": "F",
+      "display": "Female"
+    }
+  } ],
+  "status": "active",
+  "type": {
+    "coding": [ {
+      "system": "http://terminology.hl7.org/CodeSystem/library-type",
+      "code": "module-definition"
+    } ]
+  },
+  "relatedArtifact": [ {
+    "type": "depends-on",
+    "display": "Library SDE",
+    "resource": "http://ecqi.healthit.gov/ecqms/Library/SupplementalDataElements|3.1.000"
+  }, {
+    "type": "depends-on",
+    "display": "Code system AdministrativeGender",
+    "resource": "http://hl7.org/fhir/v3/AdministrativeGender"
+  } ],
+  "parameter": [ {
+    "name": "SDE Sex",
+    "use": "out",
+    "min": 0,
+    "max": "1",
+    "type": "Coding"
+  } ],
+  "dataRequirement": [ {
+    "type": "Patient",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
+    "mustSupport": [ "gender", "gender.value" ]
+  } ]
+}
\ No newline at end of file
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json
index 056b1c2d9..aebbaf50f 100644
--- a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json
@@ -199,28 +199,9 @@
     "type": "boolean"
   } ],
   "dataRequirement": [ {
-    "type": "Patient",
-    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ]
-  }, {
-    "type": "Patient",
-    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
-    "mustSupport": [ "url", "extension" ],
-    "codeFilter": [ {
-      "path": "url",
-      "code": [ {
-        "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"
-      } ]
-    } ]
-  }, {
     "type": "Patient",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ],
-    "mustSupport": [ "url", "extension" ],
-    "codeFilter": [ {
-      "path": "url",
-      "code": [ {
-        "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race"
-      } ]
-    } ]
+    "mustSupport": [ "ethnicity", "race" ]
   }, {
     "type": "Coverage",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-coverage" ],
@@ -232,7 +213,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492"
@@ -240,7 +221,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012"
@@ -248,7 +229,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014"
@@ -256,7 +237,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016"
@@ -264,7 +245,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496"
@@ -272,7 +253,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1023"
@@ -280,7 +261,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011"
@@ -288,7 +269,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001"
@@ -296,11 +277,19 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
-    "mustSupport": [ "type" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008"
     } ]
+  }, {
+    "type": "Encounter",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ],
+    "mustSupport": [ "type", "period", "period.low", "period.lowClosed", "period.high", "period.highClosed", "class", "status", "status.value" ],
+    "codeFilter": [ {
+      "path": "type",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1012"
+    } ]
   }, {
     "type": "Condition",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition" ],
@@ -309,5 +298,37 @@
       "path": "code",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1005"
     } ]
+  }, {
+    "type": "Observation",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation" ],
+    "mustSupport": [ "code", "issued", "issued.value", "value" ],
+    "codeFilter": [ {
+      "path": "code",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1006"
+    } ]
+  }, {
+    "type": "Observation",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation" ],
+    "mustSupport": [ "code", "issued", "issued.value", "value" ],
+    "codeFilter": [ {
+      "path": "code",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1332"
+    } ]
+  }, {
+    "type": "Observation",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observationnotdone" ],
+    "mustSupport": [ "code", "issued", "issued.value", "status", "status.value", "extension" ],
+    "codeFilter": [ {
+      "path": "code",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1006"
+    } ]
+  }, {
+    "type": "Observation",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observationnotdone" ],
+    "mustSupport": [ "code", "issued", "issued.value", "status", "status.value", "extension" ],
+    "codeFilter": [ {
+      "path": "code",
+      "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1332"
+    } ]
   } ]
 }
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json
index da827ef70..f9f0d0ff9 100644
--- a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json
@@ -54,6 +54,14 @@
     "id": "G10002",
     "type": "MedicationRequest",
     "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-medicationrequest" ],
-    "mustSupport": [ "medication.reference" ]
+    "mustSupport": [ "medication.reference", "status", "status.value", "intent", "intent.value", "doNotPerform", "doNotPerform.value", "dosageInstruction" ]
+  }, {
+    "type": "MedicationRequest",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-medicationrequest" ],
+    "mustSupport": [ "medication", "status", "status.value", "intent", "intent.value", "doNotPerform", "doNotPerform.value", "dosageInstruction" ],
+    "codeFilter": [ {
+      "path": "medication",
+      "valueSet": "tbd"
+    } ]
   } ]
 }
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/DeviceOrder/Library-TestDeviceOrder-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/DeviceOrder/Library-TestDeviceOrder-EffectiveDataRequirements.json
new file mode 100644
index 000000000..32460cbed
--- /dev/null
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/DeviceOrder/Library-TestDeviceOrder-EffectiveDataRequirements.json
@@ -0,0 +1,89 @@
+{
+  "resourceType": "Library",
+  "extension": [ {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-logicDefinition",
+    "extension": [ {
+      "url": "libraryName",
+      "valueString": "TestDeviceOrder"
+    }, {
+      "url": "name",
+      "valueString": "Has Criteria Indicating Frailty"
+    }, {
+      "url": "statement",
+      "valueString": "define \"Has Criteria Indicating Frailty\":\n  exists ( (([DeviceRequest: \"Frailty Device\"]).isDeviceOrder()) FrailtyDeviceOrder\n      where FrailtyDeviceOrder.doNotPerform() is not true\n      and FrailtyDeviceOrder.authoredOn.toInterval() during day of \"Measurement Period\"\n  )"
+    }, {
+      "url": "displaySequence",
+      "valueInteger": 0
+    } ]
+  }, {
+    "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-logicDefinition",
+    "extension": [ {
+      "url": "libraryName",
+      "valueString": "TestDeviceOrder"
+    }, {
+      "url": "name",
+      "valueString": "isDeviceOrder"
+    }, {
+      "url": "statement",
+      "valueString": "define fluent function isDeviceOrder(DeviceRequest List<DeviceRequest>):\n  DeviceRequest D\n    where D.status in { 'active', 'completed' }\n      and D.intent = 'order'"
+    }, {
+      "url": "displaySequence",
+      "valueInteger": 1
+    } ]
+  } ],
+  "status": "active",
+  "type": {
+    "coding": [ {
+      "system": "http://terminology.hl7.org/CodeSystem/library-type",
+      "code": "module-definition"
+    } ]
+  },
+  "relatedArtifact": [ {
+    "type": "depends-on",
+    "display": "QICore model information",
+    "resource": "http://hl7.org/fhir/Library/QICore-ModelInfo"
+  }, {
+    "type": "depends-on",
+    "display": "Library FHIRHelpers",
+    "resource": "Library/FHIRHelpers|4.0.1"
+  }, {
+    "type": "depends-on",
+    "display": "Library QICoreCommon",
+    "resource": "Library/QICoreCommon|1.5.000"
+  }, {
+    "type": "depends-on",
+    "display": "Value set Frailty Device",
+    "resource": "http://example.org/fhir/valueset/frailty-device"
+  } ],
+  "parameter": [ {
+    "name": "Measurement Period",
+    "use": "in",
+    "min": 0,
+    "max": "1",
+    "type": "Period"
+  }, {
+    "name": "Patient",
+    "use": "out",
+    "min": 0,
+    "max": "1",
+    "type": "Resource"
+  }, {
+    "name": "Has Criteria Indicating Frailty",
+    "use": "out",
+    "min": 0,
+    "max": "1",
+    "type": "boolean"
+  } ],
+  "dataRequirement": [ {
+    "type": "Patient",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ]
+  }, {
+    "type": "DeviceRequest",
+    "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-devicerequest" ],
+    "mustSupport": [ "code", "status", "status.value", "intent", "intent.value", "authoredOn", "authoredOn.value" ],
+    "codeFilter": [ {
+      "path": "code",
+      "valueSet": "http://example.org/fhir/valueset/frailty-device"
+    } ]
+  } ]
+}
diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/EXMLogic/Library-EXMLogic-data-requirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/EXMLogic/Library-EXMLogic-data-requirements.json
index 8bcc39952..861e328f9 100644
--- a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/EXMLogic/Library-EXMLogic-data-requirements.json
+++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/EXMLogic/Library-EXMLogic-data-requirements.json
@@ -140,32 +140,13 @@
     "type": "Coding"
   } ],
   "dataRequirement": [ {
-    "type": "Patient",
-    "profile": [ "http://hl7.org/fhir/StructureDefinition/Patient" ]
-  }, {
     "type": "Patient",
     "profile": [ "http://hl7.org/fhir/StructureDefinition/Patient" ],
-    "mustSupport": [ "url", "extension", "value" ],
-    "codeFilter": [ {
-      "path": "url",
-      "code": [ {
-        "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"
-      } ]
-    } ]
-  }, {
-    "type": "Patient",
-    "profile": [ "http://hl7.org/fhir/StructureDefinition/Patient" ],
-    "mustSupport": [ "url", "extension", "value" ],
-    "codeFilter": [ {
-      "path": "url",
-      "code": [ {
-        "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race"
-      } ]
-    } ]
+    "mustSupport": [ "ethnicity", "url", "value", "race" ]
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/StructureDefinition/Encounter" ],
-    "mustSupport": [ "type", "status", "period" ],
+    "mustSupport": [ "type", "status", "period", "use", "rank", "rank.value", "condition", "condition.reference" ],
     "codeFilter": [ {
       "path": "type",
       "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.117.1.7.1.292"
@@ -178,7 +159,7 @@
   }, {
     "type": "Encounter",
     "profile": [ "http://hl7.org/fhir/StructureDefinition/Encounter" ],
-    "mustSupport": [ "period" ],
+    "mustSupport": [ "period", "use", "rank", "rank.value", "condition", "condition.reference" ],
     "dateFilter": [ {
       "path": "period",
       "valuePeriod": {