Search in sources :

Example 21 with IndexOf

use of org.hl7.elm.r1.IndexOf in project org.hl7.fhir.core by hapifhir.

the class InstanceValidator method checkChildByDefinition.

public void checkChildByDefinition(ValidatorHostContext hostContext, List<ValidationMessage> errors, StructureDefinition profile, ElementDefinition definition, Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept, boolean checkDisplayInContext, ElementInfo ei, String extensionUrl, ElementDefinition checkDefn, boolean isSlice) {
    List<String> profiles = new ArrayList<String>();
    String type = null;
    ElementDefinition typeDefn = null;
    checkMustSupport(profile, ei);
    if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode()) && !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) {
        type = checkDefn.getType().get(0).getWorkingCode();
        String stype = ei.getElement().fhirType();
        if (checkDefn.isChoice() && !stype.equals(type)) {
            if ("Extension".equals(profile.getType())) {
            // error will be raised elsewhere
            } else {
                rule(errors, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getUrl(), type, stype);
            }
        }
        // Excluding reference is a kludge to get around versioning issues
        if (checkDefn.getType().get(0).hasProfile()) {
            for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
                profiles.add(p.getValue());
            }
        }
    } else if (checkDefn.getType().size() == 1 && "*".equals(checkDefn.getType().get(0).getWorkingCode())) {
        String prefix = tail(checkDefn.getPath());
        assert prefix.endsWith("[x]");
        type = ei.getName().substring(prefix.length() - 3);
        if (isPrimitiveType(type))
            type = Utilities.uncapitalize(type);
        if (checkDefn.getType().get(0).hasProfile()) {
            for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
                profiles.add(p.getValue());
            }
        }
    } else if (checkDefn.getType().size() > 1) {
        String prefix = tail(checkDefn.getPath());
        assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") || isResourceAndTypes(checkDefn) : "Multiple Types allowed, but name is wrong @ " + checkDefn.getPath() + ": " + checkDefn.typeSummaryVB();
        if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) {
            type = ei.getElement().getType();
        } else if (ei.getElement().isResource()) {
            type = ei.getElement().fhirType();
        } else {
            prefix = prefix.substring(0, prefix.length() - 3);
            for (TypeRefComponent t : checkDefn.getType()) if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) {
                type = t.getWorkingCode();
                // Excluding reference is a kludge to get around versioning issues
                if (t.hasProfile() && !type.equals("Reference"))
                    profiles.add(t.getProfile().get(0).getValue());
            }
        }
        if (type == null) {
            TypeRefComponent trc = checkDefn.getType().get(0);
            if (trc.getWorkingCode().equals("Reference"))
                type = "Reference";
            else
                rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType()));
        }
    } else if (checkDefn.getContentReference() != null) {
        typeDefn = resolveNameReference(profile.getSnapshot(), checkDefn.getContentReference());
    } else if (checkDefn.getType().size() == 1 && ("Element".equals(checkDefn.getType().get(0).getWorkingCode()) || "BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode()))) {
        if (checkDefn.getType().get(0).hasProfile()) {
            CanonicalType pu = checkDefn.getType().get(0).getProfile().get(0);
            if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT))
                profiles.add(pu.getValue() + "#" + pu.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT));
            else
                profiles.add(pu.getValue());
        }
    }
    if (type != null) {
        if (type.startsWith("@")) {
            checkDefn = findElement(profile, type.substring(1));
            if (isSlice) {
                ei.slice = ei.definition;
            } else {
                ei.definition = ei.definition;
            }
            type = null;
        }
    }
    NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
    // if (debug) {
    // System.out.println("  check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl());
    // }
    String localStackLiteralPath = localStack.getLiteralPath();
    String eiPath = ei.getPath();
    if (!eiPath.equals(localStackLiteralPath)) {
        assert (eiPath.equals(localStackLiteralPath)) : "ei.path: " + ei.getPath() + "  -  localStack.getLiteralPath: " + localStackLiteralPath;
    }
    boolean thisIsCodeableConcept = false;
    String thisExtension = null;
    boolean checkDisplay = true;
    SpecialElement special = ei.getElement().getSpecial();
    if (special == SpecialElement.BUNDLE_ENTRY || special == SpecialElement.BUNDLE_OUTCOME || special == SpecialElement.PARAMETER) {
        checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : checkDefn, ei.getElement(), ei.getElement(), localStack, false);
    } else {
        checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : checkDefn, resource, ei.getElement(), localStack, false);
    }
    ei.getElement().markValidation(profile, checkDefn);
    boolean elementValidated = false;
    if (type != null) {
        if (isPrimitiveType(type)) {
            checkPrimitive(hostContext, errors, ei.getPath(), type, checkDefn, ei.getElement(), profile, stack);
        } else {
            if (checkDefn.hasFixed()) {
                checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null, false);
            }
            if (checkDefn.hasPattern()) {
                checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getPattern(), profile.getUrl(), checkDefn.getSliceName(), null, true);
            }
        }
        if (type.equals("Identifier")) {
            checkIdentifier(errors, ei.getPath(), ei.getElement(), checkDefn);
        } else if (type.equals("Coding")) {
            checkCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack);
        } else if (type.equals("Quantity")) {
            checkQuantity(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack);
        } else if (type.equals("Attachment")) {
            checkAttachment(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack);
        } else if (type.equals("CodeableConcept")) {
            checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack);
            thisIsCodeableConcept = true;
        } else if (type.equals("Reference")) {
            checkReference(hostContext, errors, ei.getPath(), ei.getElement(), profile, checkDefn, actualType, localStack);
        // We only check extensions if we're not in a complex extension or if the element we're dealing with is not defined as part of that complex extension
        } else if (type.equals("Extension")) {
            Element eurl = ei.getElement().getNamedChild("url");
            if (rule(errors, IssueType.INVALID, ei.getPath(), eurl != null, I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) {
                String url = eurl.primitiveValue();
                thisExtension = url;
                if (rule(errors, IssueType.INVALID, ei.getPath(), !Utilities.noString(url), I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) {
                    if (rule(errors, IssueType.INVALID, ei.getPath(), (extensionUrl != null) || Utilities.isAbsoluteUrl(url), I18nConstants.EXTENSION_EXT_URL_ABSOLUTE)) {
                        checkExtension(hostContext, errors, ei.getPath(), resource, element, ei.getElement(), checkDefn, profile, localStack, stack, extensionUrl);
                    }
                }
            }
        } else if (type.equals("Resource") || isResource(type)) {
            validateContains(hostContext, errors, ei.getPath(), checkDefn, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei), // if
            profile);
            elementValidated = true;
        // (str.matches(".*([.,/])work\\1$"))
        } else if (Utilities.isAbsoluteUrl(type)) {
            StructureDefinition defn = context.fetchTypeDefinition(type);
            if (defn != null && hasMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep())) {
                List<String> txtype = getMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep());
                if (txtype.contains("CodeableConcept")) {
                    checkTerminologyCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack, defn);
                    thisIsCodeableConcept = true;
                } else if (txtype.contains("Coding")) {
                    checkTerminologyCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack, defn);
                }
            }
        }
    } else {
        if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), checkDefn != null, I18nConstants.VALIDATION_VAL_CONTENT_UNKNOWN, ei.getName()))
            validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, false, true, null);
    }
    StructureDefinition p = null;
    String tail = null;
    if (profiles.isEmpty()) {
        if (type != null) {
            p = getProfileForType(type, checkDefn.getType());
            // If dealing with a primitive type, then we need to check the current child against
            // the invariants (constraints) on the current element, because otherwise it only gets
            // checked against the primary type's invariants: LLoyd
            // if (p.getKind() == StructureDefinitionKind.PRIMITIVETYPE) {
            // checkInvariants(hostContext, errors, ei.path, profile, ei.definition, null, null, resource, ei.element);
            // }
            rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_NOTYPE, type);
        }
    } else if (profiles.size() == 1) {
        String url = profiles.get(0);
        if (url.contains("#")) {
            tail = url.substring(url.indexOf("#") + 1);
            url = url.substring(0, url.indexOf("#"));
        }
        p = this.context.fetchResource(StructureDefinition.class, url);
        rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, profiles.get(0));
    } else {
        elementValidated = true;
        HashMap<String, List<ValidationMessage>> goodProfiles = new HashMap<String, List<ValidationMessage>>();
        HashMap<String, List<ValidationMessage>> badProfiles = new HashMap<String, List<ValidationMessage>>();
        for (String typeProfile : profiles) {
            String url = typeProfile;
            tail = null;
            if (url.contains("#")) {
                tail = url.substring(url.indexOf("#") + 1);
                url = url.substring(0, url.indexOf("#"));
            }
            p = this.context.fetchResource(StructureDefinition.class, typeProfile);
            if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, typeProfile)) {
                List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
                validateElement(hostContext, profileErrors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
                if (hasErrors(profileErrors))
                    badProfiles.put(typeProfile, profileErrors);
                else
                    goodProfiles.put(typeProfile, profileErrors);
            }
        }
        if (goodProfiles.size() == 1) {
            errors.addAll(goodProfiles.values().iterator().next());
        } else if (goodProfiles.size() == 0) {
            rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOMATCH, StringUtils.join("; ", profiles));
            for (String m : badProfiles.keySet()) {
                p = this.context.fetchResource(StructureDefinition.class, m);
                for (ValidationMessage message : badProfiles.get(m)) {
                    message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])");
                    errors.add(message);
                }
            }
        } else {
            warning(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MULTIPLEMATCHES, StringUtils.join("; ", goodProfiles.keySet()));
            for (String m : goodProfiles.keySet()) {
                p = this.context.fetchResource(StructureDefinition.class, m);
                for (ValidationMessage message : goodProfiles.get(m)) {
                    message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])");
                    errors.add(message);
                }
            }
        }
    }
    if (p != null) {
        trackUsage(p, hostContext, element);
        if (!elementValidated) {
            if (ei.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || ei.getElement().getSpecial() == SpecialElement.BUNDLE_OUTCOME || ei.getElement().getSpecial() == SpecialElement.PARAMETER)
                validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, ei.getElement(), ei.getElement(), type, localStack.resetIds(), thisIsCodeableConcept, checkDisplay, thisExtension);
            else
                validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
        }
        int index = profile.getSnapshot().getElement().indexOf(checkDefn);
        if (index < profile.getSnapshot().getElement().size() - 1) {
            String nextPath = profile.getSnapshot().getElement().get(index + 1).getPath();
            if (!nextPath.equals(checkDefn.getPath()) && nextPath.startsWith(checkDefn.getPath()))
                validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
        }
    }
}
Also used : ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) HashMap(java.util.HashMap) NamedElement(org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement) IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) SpecialElement(org.hl7.fhir.r5.elementmodel.Element.SpecialElement) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) SpecialElement(org.hl7.fhir.r5.elementmodel.Element.SpecialElement) NodeStack(org.hl7.fhir.validation.instance.utils.NodeStack) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) ContactPoint(org.hl7.fhir.r5.model.ContactPoint) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) ArrayList(java.util.ArrayList) List(java.util.List) TypedElementDefinition(org.hl7.fhir.r5.utils.FHIRPathEngine.TypedElementDefinition) ElementDefinition(org.hl7.fhir.r5.model.ElementDefinition)

Example 22 with IndexOf

use of org.hl7.elm.r1.IndexOf in project org.hl7.fhir.core by hapifhir.

the class ProfileUtilities method processPaths.

/**
 * @param trimDifferential
 * @param srcSD
 * @throws DefinitionException, FHIRException
 * @throws Exception
 */
private ElementDefinition processPaths(String indent, StructureDefinitionSnapshotComponent result, StructureDefinitionSnapshotComponent base, StructureDefinitionDifferentialComponent differential, int baseCursor, int diffCursor, int baseLimit, int diffLimit, String url, String webUrl, String profileName, String contextPathSrc, String contextPathDst, boolean trimDifferential, String contextName, String resultPathBase, boolean slicingDone, List<ElementRedirection> redirector, StructureDefinition srcSD) throws DefinitionException, FHIRException {
    if (debug)
        System.out.println(indent + "PP @ " + resultPathBase + " / " + contextPathSrc + " : base = " + baseCursor + " to " + baseLimit + ", diff = " + diffCursor + " to " + diffLimit + " (slicing = " + slicingDone + ", redirector = " + (redirector == null ? "null" : redirector.toString()) + ")");
    ElementDefinition res = null;
    List<TypeSlice> typeList = new ArrayList<>();
    // just repeat processing entries until we run out of our allowed scope (1st entry, the allowed scope is all the entries)
    while (baseCursor <= baseLimit) {
        // get the current focus of the base, and decide what to do
        ElementDefinition currentBase = base.getElement().get(baseCursor);
        String cpath = fixedPathSource(contextPathSrc, currentBase.getPath(), redirector);
        if (debug)
            System.out.println(indent + " - " + cpath + ": base = " + baseCursor + " (" + descED(base.getElement(), baseCursor) + ") to " + baseLimit + " (" + descED(base.getElement(), baseLimit) + "), diff = " + diffCursor + " (" + descED(differential.getElement(), diffCursor) + ") to " + diffLimit + " (" + descED(differential.getElement(), diffLimit) + ") " + "(slicingDone = " + slicingDone + ") (diffpath= " + (differential.getElement().size() > diffCursor ? differential.getElement().get(diffCursor).getPath() : "n/a") + ")");
        // get a list of matching elements in scope
        List<ElementDefinition> diffMatches = getDiffMatches(differential, cpath, diffCursor, diffLimit, profileName);
        // in the simple case, source is not sliced.
        if (!currentBase.hasSlicing()) {
            if (diffMatches.isEmpty()) {
                // the differential doesn't say anything about this item
                // so we just copy it in
                ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
                outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                updateFromBase(outcome, currentBase);
                markDerived(outcome);
                if (resultPathBase == null)
                    resultPathBase = outcome.getPath();
                else if (!outcome.getPath().startsWith(resultPathBase))
                    throw new DefinitionException("Adding wrong path");
                result.getElement().add(outcome);
                if (hasInnerDiffMatches(differential, cpath, diffCursor, diffLimit, base.getElement(), true)) {
                    // did we implicitly step into a new type?
                    if (baseHasChildren(base, currentBase)) {
                        // not a new type here
                        processPaths(indent + "  ", result, base, differential, baseCursor + 1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, redirector, srcSD);
                        baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor + 1, baseLimit);
                    } else {
                        if (outcome.getType().size() == 0) {
                            throw new DefinitionException(diffMatches.get(0).getPath() + " has no children (" + differential.getElement().get(diffCursor).getPath() + ") and no types in profile " + profileName);
                        }
                        if (outcome.getType().size() > 1) {
                            for (TypeRefComponent t : outcome.getType()) {
                                if (!t.getWorkingCode().equals("Reference"))
                                    throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") and multiple types (" + typeCode(outcome.getType()) + ") in profile " + profileName);
                            }
                        }
                        StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
                        if (dt == null)
                            throw new DefinitionException("Unknown type " + outcome.getType().get(0) + " at " + diffMatches.get(0).getPath());
                        contextName = dt.getUrl();
                        int start = diffCursor;
                        while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath + ".")) diffCursor++;
                        processPaths(indent + "  ", result, dt.getSnapshot(), differential, 1, /* starting again on the data type, but skip the root */
                        start, dt.getSnapshot().getElement().size() - 1, diffCursor - 1, url, webUrl, profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, redirector, srcSD);
                    }
                }
                baseCursor++;
            } else if (diffMatches.size() == 1 && (slicingDone || (!isImplicitSlicing(diffMatches.get(0), cpath) && !(diffMatches.get(0).hasSlicing() || (isExtension(diffMatches.get(0)) && diffMatches.get(0).hasSliceName()))))) {
                // one matching element in the differential
                ElementDefinition template = null;
                if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
                    CanonicalType p = diffMatches.get(0).getType().get(0).getProfile().get(0);
                    StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue());
                    if (sd != null) {
                        if (!sd.hasSnapshot()) {
                            StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
                            if (sdb == null)
                                throw new DefinitionException("no base for " + sd.getBaseDefinition());
                            generateSnapshot(sdb, sd, sd.getUrl(), (sdb.hasUserData("path")) ? Utilities.extractBaseUrl(sdb.getUserString("path")) : webUrl, sd.getName());
                        }
                        ElementDefinition src;
                        if (p.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT)) {
                            src = null;
                            String eid = p.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT);
                            for (ElementDefinition t : sd.getSnapshot().getElement()) {
                                if (eid.equals(t.getId()))
                                    src = t;
                            }
                            if (src == null)
                                throw new DefinitionException("Unable to find element " + eid + " in " + p.getValue());
                        } else
                            src = sd.getSnapshot().getElement().get(0);
                        template = src.copy().setPath(currentBase.getPath());
                        template.setSliceName(null);
                        // temporary work around
                        if (!"Extension".equals(diffMatches.get(0).getType().get(0).getCode())) {
                            template.setMin(currentBase.getMin());
                            template.setMax(currentBase.getMax());
                        }
                    }
                }
                if (template == null)
                    template = currentBase.copy();
                else
                    // some of what's in currentBase overrides template
                    template = overWriteWithCurrent(template, currentBase);
                ElementDefinition outcome = updateURLs(url, webUrl, template);
                outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                if (res == null)
                    res = outcome;
                updateFromBase(outcome, currentBase);
                if (diffMatches.get(0).hasSliceName())
                    outcome.setSliceName(diffMatches.get(0).getSliceName());
                updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD);
                removeStatusExtensions(outcome);
                // if (outcome.getPath().endsWith("[x]") && outcome.getType().size() == 1 && !outcome.getType().get(0).getCode().equals("*") && !diffMatches.get(0).hasSlicing()) // if the base profile allows multiple types, but the profile only allows one, rename it
                // outcome.setPath(outcome.getPath().substring(0, outcome.getPath().length()-3)+Utilities.capitalize(outcome.getType().get(0).getCode()));
                outcome.setSlicing(null);
                if (resultPathBase == null)
                    resultPathBase = outcome.getPath();
                else if (!outcome.getPath().startsWith(resultPathBase))
                    throw new DefinitionException("Adding wrong path");
                result.getElement().add(outcome);
                baseCursor++;
                diffCursor = differential.getElement().indexOf(diffMatches.get(0)) + 1;
                if (differential.getElement().size() > diffCursor && outcome.getPath().contains(".") && (isDataType(outcome.getType()) || outcome.hasContentReference())) {
                    // don't want to do this for the root, since that's base, and we're already processing it
                    if (pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".") && !baseWalksInto(base.getElement(), baseCursor)) {
                        if (outcome.getType().size() > 1) {
                            if (outcome.getPath().endsWith("[x]") && !diffMatches.get(0).getPath().endsWith("[x]")) {
                                String en = tail(outcome.getPath());
                                String tn = tail(diffMatches.get(0).getPath());
                                String t = tn.substring(en.length() - 3);
                                if (isPrimitive(Utilities.uncapitalize(t)))
                                    t = Utilities.uncapitalize(t);
                                // keep any additional information
                                List<TypeRefComponent> ntr = getByTypeName(outcome.getType(), t);
                                if (ntr.isEmpty())
                                    ntr.add(new TypeRefComponent().setCode(t));
                                outcome.getType().clear();
                                outcome.getType().addAll(ntr);
                            }
                            if (outcome.getType().size() > 1)
                                for (TypeRefComponent t : outcome.getType()) {
                                    if (!t.getCode().equals("Reference")) {
                                        boolean nonExtension = false;
                                        for (ElementDefinition ed : diffMatches) if (ed != diffMatches.get(0) && !ed.getPath().endsWith(".extension"))
                                            nonExtension = true;
                                        if (nonExtension)
                                            throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") and multiple types (" + typeCode(outcome.getType()) + ") in profile " + profileName);
                                    }
                                }
                        }
                        int start = diffCursor;
                        while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".")) diffCursor++;
                        if (outcome.hasContentReference()) {
                            ElementDefinition tgt = getElementById(base.getElement(), outcome.getContentReference());
                            if (tgt == null)
                                throw new DefinitionException("Unable to resolve reference to " + outcome.getContentReference());
                            replaceFromContentReference(outcome, tgt);
                            int nbc = base.getElement().indexOf(tgt) + 1;
                            int nbl = nbc;
                            while (nbl < base.getElement().size() && base.getElement().get(nbl).getPath().startsWith(tgt.getPath() + ".")) nbl++;
                            processPaths(indent + "  ", result, base, differential, nbc, start - 1, nbl - 1, diffCursor - 1, url, webUrl, profileName, tgt.getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, redirectorStack(redirector, outcome, cpath), srcSD);
                        } else {
                            StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0)) : getProfileForDataType("Element");
                            if (dt == null)
                                throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") for type " + typeCode(outcome.getType()) + " in profile " + profileName + ", but can't find type");
                            contextName = dt.getUrl();
                            processPaths(indent + "  ", result, dt.getSnapshot(), differential, 1, /* starting again on the data type, but skip the root */
                            start, dt.getSnapshot().getElement().size() - 1, diffCursor - 1, url, webUrl, profileName + pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, new ArrayList<ElementRedirection>(), srcSD);
                        }
                    }
                }
            } else if (diffsConstrainTypes(diffMatches, cpath, typeList)) {
                int start = 0;
                int nbl = findEndOfElement(base, baseCursor);
                int ndc = differential.getElement().indexOf(diffMatches.get(0));
                ElementDefinition elementToRemove = null;
                // we come here whether they are sliced in the diff, or whether the short cut is used.
                if (typeList.get(0).type != null) {
                    // in R3 (and unpatched R4, as a workaround right now...
                    if (!FHIRVersion.isR4Plus(context.getVersion()) || !newSlicingProcessing) {
                        // newSlicingProcessing is a work around for editorial loop dependency
                        // we insert a cloned element with the right types at the start of the diffMatches
                        ElementDefinition ed = new ElementDefinition();
                        ed.setPath(determineTypeSlicePath(diffMatches.get(0).getPath(), cpath));
                        for (TypeSlice ts : typeList) ed.addType().setCode(ts.type);
                        ed.setSlicing(new ElementDefinitionSlicingComponent());
                        ed.getSlicing().addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this");
                        ed.getSlicing().setRules(SlicingRules.CLOSED);
                        ed.getSlicing().setOrdered(false);
                        diffMatches.add(0, ed);
                        differential.getElement().add(ndc, ed);
                        elementToRemove = ed;
                    } else {
                        // as of R4, this changed; if there's no slice, there's no constraint on the slice types, only one the type.
                        // so the element we insert specifies no types (= all types) allowed in the base, not just the listed type.
                        // see also discussion here: https://chat.fhir.org/#narrow/stream/179177-conformance/topic/Slicing.20a.20non-repeating.20element
                        ElementDefinition ed = new ElementDefinition();
                        ed.setPath(determineTypeSlicePath(diffMatches.get(0).getPath(), cpath));
                        ed.setSlicing(new ElementDefinitionSlicingComponent());
                        ed.getSlicing().addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this");
                        ed.getSlicing().setRules(SlicingRules.CLOSED);
                        ed.getSlicing().setOrdered(false);
                        diffMatches.add(0, ed);
                        differential.getElement().add(ndc, ed);
                        elementToRemove = ed;
                    }
                }
                int ndl = findEndOfElement(differential, ndc);
                // the first element is setting up the slicing
                if (diffMatches.get(0).getSlicing().hasRules())
                    if (diffMatches.get(0).getSlicing().getRules() != SlicingRules.CLOSED)
                        throw new FHIRException("Error at path " + contextPathSrc + ": Type slicing with slicing.rules != closed");
                if (diffMatches.get(0).getSlicing().hasOrdered())
                    if (diffMatches.get(0).getSlicing().getOrdered())
                        throw new FHIRException("Error at path " + contextPathSrc + ": Type slicing with slicing.ordered = true");
                if (diffMatches.get(0).getSlicing().hasDiscriminator()) {
                    if (diffMatches.get(0).getSlicing().getDiscriminator().size() != 1)
                        throw new FHIRException("Error at path " + contextPathSrc + ": Type slicing with slicing.discriminator.count() > 1");
                    if (!"$this".equals(diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getPath()))
                        throw new FHIRException("Error at path " + contextPathSrc + ": Type slicing with slicing.discriminator.path != '$this'");
                    if (diffMatches.get(0).getSlicing().getDiscriminatorFirstRep().getType() != DiscriminatorType.TYPE)
                        throw new FHIRException("Error at path " + contextPathSrc + ": Type slicing with slicing.discriminator.type != 'type'");
                }
                // check the slice names too while we're at it...
                for (TypeSlice ts : typeList) if (ts.type != null) {
                    String tn = rootName(cpath) + Utilities.capitalize(ts.type);
                    if (!ts.defn.hasSliceName())
                        ts.defn.setSliceName(tn);
                    else if (!ts.defn.getSliceName().equals(tn))
                        throw new FHIRException("Error at path " + (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath) + ": Slice name must be '" + tn + "' but is '" + ts.defn.getSliceName() + "'");
                    if (!ts.defn.hasType())
                        ts.defn.addType().setCode(ts.type);
                    else if (ts.defn.getType().size() > 1)
                        throw new FHIRException("Error at path " + (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath) + ": Slice for type '" + tn + "' has more than one type '" + ts.defn.typeSummary() + "'");
                    else if (!ts.defn.getType().get(0).getCode().equals(ts.type))
                        throw new FHIRException("Error at path " + (!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath) + ": Slice for type '" + tn + "' has wrong type '" + ts.defn.typeSummary() + "'");
                }
                // ok passed the checks.
                // copy the root diff, and then process any children it has
                ElementDefinition e = processPaths(indent + "  ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName + pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, redirector, srcSD);
                if (e == null)
                    throw new FHIRException("Did not find type root: " + diffMatches.get(0).getPath());
                // now set up slicing on the e (cause it was wiped by what we called.
                e.setSlicing(new ElementDefinitionSlicingComponent());
                e.getSlicing().addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this");
                e.getSlicing().setRules(SlicingRules.CLOSED);
                e.getSlicing().setOrdered(false);
                start++;
                // now we process the base scope repeatedly for each instance of the item in the differential list
                for (int i = start; i < diffMatches.size(); i++) {
                    // our processing scope for the differential is the item in the list, and all the items before the next one in the list
                    ndc = differential.getElement().indexOf(diffMatches.get(i));
                    ndl = findEndOfElement(differential, ndc);
                    processPaths(indent + "  ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName + pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, redirector, srcSD);
                }
                if (elementToRemove != null) {
                    differential.getElement().remove(elementToRemove);
                    ndl--;
                }
                // ok, done with that - next in the base list
                baseCursor = nbl + 1;
                diffCursor = ndl + 1;
            } else {
                // ok, the differential slices the item. Let's check our pre-conditions to ensure that this is correct
                if (!unbounded(currentBase) && !isSlicedToOneOnly(diffMatches.get(0)))
                    // (but you might do that in order to split up constraints by type)
                    throw new DefinitionException("Attempt to a slice an element that does not repeat: " + currentBase.getPath() + "/" + currentBase.getPath() + " from " + contextName + " in " + url);
                if (// well, the diff has set up a slice, but hasn't defined it. this is an error
                !diffMatches.get(0).hasSlicing() && !isExtension(currentBase))
                    throw new DefinitionException("Differential does not have a slice: " + currentBase.getPath() + "/ (b:" + baseCursor + " of " + baseLimit + " / " + diffCursor + "/ " + diffLimit + ") in profile " + url);
                // well, if it passed those preconditions then we slice the dest.
                int start = 0;
                int nbl = findEndOfElement(base, baseCursor);
                // if (diffMatches.size() > 1 && diffMatches.get(0).hasSlicing() && differential.getElement().indexOf(diffMatches.get(1)) > differential.getElement().indexOf(diffMatches.get(0))+1) {
                if (diffMatches.size() > 1 && diffMatches.get(0).hasSlicing() && (nbl > baseCursor || differential.getElement().indexOf(diffMatches.get(1)) > differential.getElement().indexOf(diffMatches.get(0)) + 1)) {
                    // there's a default set before the slices
                    int ndc = differential.getElement().indexOf(diffMatches.get(0));
                    int ndl = findEndOfElement(differential, ndc);
                    ElementDefinition e = processPaths(indent + "  ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName + pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, redirector, srcSD);
                    if (e == null)
                        throw new FHIRException("Did not find single slice: " + diffMatches.get(0).getPath());
                    e.setSlicing(diffMatches.get(0).getSlicing());
                    start++;
                } else {
                    // we're just going to accept the differential slicing at face value
                    ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
                    outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                    updateFromBase(outcome, currentBase);
                    if (!diffMatches.get(0).hasSlicing())
                        outcome.setSlicing(makeExtensionSlicing());
                    else
                        outcome.setSlicing(diffMatches.get(0).getSlicing().copy());
                    if (!outcome.getPath().startsWith(resultPathBase))
                        throw new DefinitionException("Adding wrong path");
                    result.getElement().add(outcome);
                    // differential - if the first one in the list has a name, we'll process it. Else we'll treat it as the base definition of the slice.
                    if (!diffMatches.get(0).hasSliceName()) {
                        updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD);
                        removeStatusExtensions(outcome);
                        if (!outcome.hasContentReference() && !outcome.hasType()) {
                            throw new DefinitionException("not done yet");
                        }
                        start++;
                    // result.getElement().remove(result.getElement().size()-1);
                    } else
                        checkExtensionDoco(outcome);
                }
                // now, for each entry in the diff matches, we're going to process the base item
                // our processing scope for base is all the children of the current path
                int ndc = diffCursor;
                int ndl = diffCursor;
                for (int i = start; i < diffMatches.size(); i++) {
                    // our processing scope for the differential is the item in the list, and all the items before the next one in the list
                    ndc = differential.getElement().indexOf(diffMatches.get(i));
                    ndl = findEndOfElement(differential, ndc);
                    /*            if (skipSlicingElement && i == 0) {
              ndc = ndc + 1;
              if (ndc > ndl)
                continue;
            }*/
                    // now we process the base scope repeatedly for each instance of the item in the differential list
                    processPaths(indent + "  ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName + pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, redirector, srcSD);
                }
                // ok, done with that - next in the base list
                baseCursor = nbl + 1;
                diffCursor = ndl + 1;
            }
        } else {
            // the item is already sliced in the base profile.
            // here's the rules
            // 1. irrespective of whether the slicing is ordered or not, the definition order must be maintained
            // 2. slice element names have to match.
            // 3. new slices must be introduced at the end
            // corallory: you can't re-slice existing slices. is that ok?
            // we're going to need this:
            String path = currentBase.getPath();
            ElementDefinition original = currentBase;
            if (diffMatches.isEmpty()) {
                // copy across the currentbase, and all of its children and siblings
                while (baseCursor < base.getElement().size() && base.getElement().get(baseCursor).getPath().startsWith(path)) {
                    ElementDefinition outcome = updateURLs(url, webUrl, base.getElement().get(baseCursor).copy());
                    outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                    if (!outcome.getPath().startsWith(resultPathBase))
                        throw new DefinitionException("Adding wrong path in profile " + profileName + ": " + outcome.getPath() + " vs " + resultPathBase);
                    // so we just copy it in
                    result.getElement().add(outcome);
                    baseCursor++;
                }
            } else {
                // first - check that the slicing is ok
                boolean closed = currentBase.getSlicing().getRules() == SlicingRules.CLOSED;
                int diffpos = 0;
                boolean isExtension = cpath.endsWith(".extension") || cpath.endsWith(".modifierExtension");
                if (diffMatches.get(0).hasSlicing()) {
                    // it might be null if the differential doesn't want to say anything about slicing
                    // if (!isExtension)
                    // diffpos++; // if there's a slice on the first, we'll ignore any content it has
                    ElementDefinitionSlicingComponent dSlice = diffMatches.get(0).getSlicing();
                    ElementDefinitionSlicingComponent bSlice = currentBase.getSlicing();
                    if (dSlice.hasOrderedElement() && bSlice.hasOrderedElement() && !orderMatches(dSlice.getOrderedElement(), bSlice.getOrderedElement()))
                        throw new DefinitionException("Slicing rules on differential (" + summarizeSlicing(dSlice) + ") do not match those on base (" + summarizeSlicing(bSlice) + ") - order @ " + path + " (" + contextName + ")");
                    if (!discriminatorMatches(dSlice.getDiscriminator(), bSlice.getDiscriminator()))
                        throw new DefinitionException("Slicing rules on differential (" + summarizeSlicing(dSlice) + ") do not match those on base (" + summarizeSlicing(bSlice) + ") - disciminator @ " + path + " (" + contextName + ")");
                    if (!ruleMatches(dSlice.getRules(), bSlice.getRules()))
                        throw new DefinitionException("Slicing rules on differential (" + summarizeSlicing(dSlice) + ") do not match those on base (" + summarizeSlicing(bSlice) + ") - rule @ " + path + " (" + contextName + ")");
                }
                ElementDefinition outcome = updateURLs(url, webUrl, currentBase.copy());
                outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                updateFromBase(outcome, currentBase);
                if (diffMatches.get(0).hasSlicing() || !diffMatches.get(0).hasSliceName()) {
                    updateFromSlicing(outcome.getSlicing(), diffMatches.get(0).getSlicing());
                    // if there's no slice, we don't want to update the unsliced description
                    updateFromDefinition(outcome, diffMatches.get(0), profileName, closed, url, srcSD);
                    removeStatusExtensions(outcome);
                } else if (!diffMatches.get(0).hasSliceName())
                    // because of updateFromDefinition isn't called
                    diffMatches.get(0).setUserData(GENERATED_IN_SNAPSHOT, outcome);
                result.getElement().add(outcome);
                if (!diffMatches.get(0).hasSliceName()) {
                    // it's not real content, just the slice
                    diffpos++;
                }
                if (hasInnerDiffMatches(differential, cpath, diffpos, diffLimit, base.getElement(), false)) {
                    int nbl = findEndOfElement(base, baseCursor);
                    int ndc = differential.getElement().indexOf(diffMatches.get(0)) + 1;
                    int ndl = findEndOfElement(differential, ndc);
                    processPaths(indent + "  ", result, base, differential, baseCursor + 1, ndc, nbl, ndl, url, webUrl, profileName + pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, srcSD);
                // throw new Error("Not done yet");
                // } else if (currentBase.getType().get(0).getCode().equals("BackboneElement") && diffMatches.size() > 0 && diffMatches.get(0).hasSliceName()) {
                } else if (currentBase.getType().get(0).getCode().equals("BackboneElement")) {
                    // We need to copy children of the backbone element before we start messing around with slices
                    int nbl = findEndOfElement(base, baseCursor);
                    for (int i = baseCursor + 1; i <= nbl; i++) {
                        outcome = updateURLs(url, webUrl, base.getElement().get(i).copy());
                        result.getElement().add(outcome);
                    }
                }
                // now, we have two lists, base and diff. we're going to work through base, looking for matches in diff.
                List<ElementDefinition> baseMatches = getSiblings(base.getElement(), currentBase);
                for (ElementDefinition baseItem : baseMatches) {
                    baseCursor = base.getElement().indexOf(baseItem);
                    outcome = updateURLs(url, webUrl, baseItem.copy());
                    updateFromBase(outcome, currentBase);
                    outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                    outcome.setSlicing(null);
                    if (!outcome.getPath().startsWith(resultPathBase))
                        throw new DefinitionException("Adding wrong path");
                    if (diffpos < diffMatches.size() && diffMatches.get(diffpos).getSliceName().equals(outcome.getSliceName())) {
                        // if there's a diff, we update the outcome with diff
                        // no? updateFromDefinition(outcome, diffMatches.get(diffpos), profileName, closed, url);
                        // then process any children
                        int nbl = findEndOfElement(base, baseCursor);
                        int ndc = differential.getElement().indexOf(diffMatches.get(diffpos));
                        int ndl = findEndOfElement(differential, ndc);
                        // now we process the base scope repeatedly for each instance of the item in the differential list
                        processPaths(indent + "  ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName + pathTail(diffMatches, diffpos), contextPathSrc, contextPathDst, closed, contextName, resultPathBase, true, redirector, srcSD);
                        // ok, done with that - now set the cursors for if this is the end
                        baseCursor = nbl;
                        diffCursor = ndl + 1;
                        diffpos++;
                    } else {
                        result.getElement().add(outcome);
                        baseCursor++;
                        // just copy any children on the base
                        while (baseCursor < base.getElement().size() && base.getElement().get(baseCursor).getPath().startsWith(path) && !base.getElement().get(baseCursor).getPath().equals(path)) {
                            outcome = updateURLs(url, webUrl, base.getElement().get(baseCursor).copy());
                            outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                            if (!outcome.getPath().startsWith(resultPathBase))
                                throw new DefinitionException("Adding wrong path");
                            result.getElement().add(outcome);
                            baseCursor++;
                        }
                        // Lloyd - add this for test T15
                        baseCursor--;
                    }
                }
                // finally, we process any remaining entries in diff, which are new (and which are only allowed if the base wasn't closed
                if (closed && diffpos < diffMatches.size())
                    throw new DefinitionException("The base snapshot marks a slicing as closed, but the differential tries to extend it in " + profileName + " at " + path + " (" + cpath + ")");
                if (diffpos == diffMatches.size()) {
                // Lloyd This was causing problems w/ Telus
                // diffCursor++;
                } else {
                    while (diffpos < diffMatches.size()) {
                        ElementDefinition diffItem = diffMatches.get(diffpos);
                        for (ElementDefinition baseItem : baseMatches) if (baseItem.getSliceName().equals(diffItem.getSliceName()))
                            throw new DefinitionException("Named items are out of order in the slice");
                        outcome = updateURLs(url, webUrl, currentBase.copy());
                        // outcome = updateURLs(url, diffItem.copy());
                        outcome.setPath(fixedPathDest(contextPathDst, outcome.getPath(), redirector, contextPathSrc));
                        updateFromBase(outcome, currentBase);
                        outcome.setSlicing(null);
                        if (!outcome.getPath().startsWith(resultPathBase))
                            throw new DefinitionException("Adding wrong path");
                        result.getElement().add(outcome);
                        updateFromDefinition(outcome, diffItem, profileName, trimDifferential, url, srcSD);
                        removeStatusExtensions(outcome);
                        // --- LM Added this
                        diffCursor = differential.getElement().indexOf(diffItem) + 1;
                        if (!outcome.getType().isEmpty() && (/*outcome.getType().get(0).getCode().equals("Extension") || */
                        differential.getElement().size() > diffCursor) && outcome.getPath().contains(".") && isDataType(outcome.getType())) {
                            // don't want to do this for the root, since that's base, and we're already processing it
                            if (!baseWalksInto(base.getElement(), baseCursor)) {
                                if (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".")) {
                                    if (outcome.getType().size() > 1)
                                        for (TypeRefComponent t : outcome.getType()) {
                                            if (!t.getCode().equals("Reference"))
                                                throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") and multiple types (" + typeCode(outcome.getType()) + ") in profile " + profileName);
                                        }
                                    TypeRefComponent t = outcome.getType().get(0);
                                    if (t.getCode().equals("BackboneElement")) {
                                        int baseStart = base.getElement().indexOf(currentBase) + 1;
                                        int baseMax = baseStart + 1;
                                        while (baseMax < base.getElement().size() && base.getElement().get(baseMax).getPath().startsWith(currentBase.getPath() + ".")) baseMax++;
                                        int start = diffCursor;
                                        while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".")) diffCursor++;
                                        processPaths(indent + "  ", result, base, differential, baseStart, start - 1, baseMax - 1, diffCursor - 1, url, webUrl, profileName + pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, redirector, srcSD);
                                    } else {
                                        StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
                                        // }
                                        if (dt == null)
                                            throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") for type " + typeCode(outcome.getType()) + " in profile " + profileName + ", but can't find type");
                                        contextName = dt.getUrl();
                                        int start = diffCursor;
                                        while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".")) diffCursor++;
                                        processPaths(indent + "  ", result, dt.getSnapshot(), differential, 1, /* starting again on the data type, but skip the root */
                                        start - 1, dt.getSnapshot().getElement().size() - 1, diffCursor - 1, url, webUrl, profileName + pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, redirector, srcSD);
                                    }
                                } else if (outcome.getType().get(0).getCode().equals("Extension")) {
                                    // Force URL to appear if we're dealing with an extension.  (This is a kludge - may need to drill down in other cases where we're slicing and the type has a profile declaration that could be setting the fixed value)
                                    StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
                                    for (ElementDefinition extEd : dt.getSnapshot().getElement()) {
                                        // We only want the children that aren't the root
                                        if (extEd.getPath().contains(".")) {
                                            ElementDefinition extUrlEd = updateURLs(url, webUrl, extEd.copy());
                                            extUrlEd.setPath(fixedPathDest(outcome.getPath(), extUrlEd.getPath(), redirector, null));
                                            // updateFromBase(extUrlEd, currentBase);
                                            markDerived(extUrlEd);
                                            result.getElement().add(extUrlEd);
                                        }
                                    }
                                }
                            }
                        }
                        // ---
                        diffpos++;
                    }
                }
                baseCursor++;
            }
        }
    }
    int i = 0;
    for (ElementDefinition e : result.getElement()) {
        i++;
        if (e.hasMinElement() && e.getMinElement().getValue() == null)
            throw new Error("null min");
    }
    return res;
}
Also used : ArrayList(java.util.ArrayList) FHIRFormatError(org.hl7.fhir.exceptions.FHIRFormatError) CanonicalType(org.hl7.fhir.r4.model.CanonicalType) FHIRException(org.hl7.fhir.exceptions.FHIRException) StructureDefinition(org.hl7.fhir.r4.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent) ElementDefinitionSlicingComponent(org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionSlicingComponent) List(java.util.List) ArrayList(java.util.ArrayList) ElementDefinition(org.hl7.fhir.r4.model.ElementDefinition) DefinitionException(org.hl7.fhir.exceptions.DefinitionException)

Example 23 with IndexOf

use of org.hl7.elm.r1.IndexOf in project org.hl7.fhir.core by hapifhir.

the class ProfileUtilities method closeChildren.

private void closeChildren(StructureDefinition base, ElementDefinition edb, StructureDefinition derived, ElementDefinition edm) {
    String path = edb.getPath() + ".";
    int baseStart = base.getSnapshot().getElement().indexOf(edb);
    int baseEnd = findEnd(base.getSnapshot().getElement(), edb, baseStart + 1);
    int diffStart = derived.getDifferential().getElement().indexOf(edm);
    int diffEnd = findEnd(derived.getDifferential().getElement(), edm, diffStart + 1);
    for (int cBase = baseStart; cBase < baseEnd; cBase++) {
        ElementDefinition edBase = base.getSnapshot().getElement().get(cBase);
        if (isImmediateChild(edBase, edb)) {
            ElementDefinition edMatch = getMatchInDerived(edBase, derived.getDifferential().getElement(), diffStart, diffEnd);
            if (edMatch == null) {
                ElementDefinition edd = derived.getDifferential().addElement();
                edd.setPath(edBase.getPath());
                edd.setMax("0");
            } else {
                closeChildren(base, edBase, derived, edMatch);
            }
        }
    }
}
Also used : ElementDefinition(org.hl7.fhir.r4.model.ElementDefinition)

Example 24 with IndexOf

use of org.hl7.elm.r1.IndexOf in project clinical_quality_language by cqframework.

the class SystemLibraryHelper method load.

public static CompiledLibrary load(SystemModel systemModel, TypeBuilder tb) {
    CompiledLibrary system = new CompiledLibrary();
    system.setIdentifier(new VersionedIdentifier().withId("System").withVersion("1.0"));
    // Logical Operators
    add(system, tb, new Operator("And", new Signature(systemModel.getBoolean(), systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("Or", new Signature(systemModel.getBoolean(), systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("Xor", new Signature(systemModel.getBoolean(), systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("Not", new Signature(systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("Implies", new Signature(systemModel.getBoolean(), systemModel.getBoolean()), systemModel.getBoolean()));
    // Nullological Operators
    add(system, tb, new Operator("IsNull", new Signature(systemModel.getAny()), systemModel.getBoolean()));
    add(system, tb, new Operator("IsTrue", new Signature(systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("IsFalse", new Signature(systemModel.getBoolean()), systemModel.getBoolean()));
    // Coalesce<T>(list<T>)
    // Coalesce<T>(T, T)
    // Coalesce<T>(T, T, T)
    // Coalesce<T>(T, T, T, T)
    // Coalesce<T>(T, T, T, T, T)
    add(system, tb, new GenericOperator("Coalesce", new Signature(new ListType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    add(system, tb, new GenericOperator("Coalesce", new Signature(new TypeParameter("T"), new TypeParameter("T")), new TypeParameter("T"), new TypeParameter("T")));
    add(system, tb, new GenericOperator("Coalesce", new Signature(new TypeParameter("T"), new TypeParameter("T"), new TypeParameter("T")), new TypeParameter("T"), new TypeParameter("T")));
    add(system, tb, new GenericOperator("Coalesce", new Signature(new TypeParameter("T"), new TypeParameter("T"), new TypeParameter("T"), new TypeParameter("T")), new TypeParameter("T"), new TypeParameter("T")));
    add(system, tb, new GenericOperator("Coalesce", new Signature(new TypeParameter("T"), new TypeParameter("T"), new TypeParameter("T"), new TypeParameter("T"), new TypeParameter("T")), new TypeParameter("T"), new TypeParameter("T")));
    // Conversion Operators
    // ToString(Boolean) : String
    // ToString(Integer) : String
    // ToString(Long) : String
    // ToString(Decimal) : String
    // ToString(DateTime) : String
    // ToString(Date) : String
    // ToString(Time) : String
    // ToString(Quantity) : String
    // ToString(Ratio) : String
    // ToString(String) : String
    Operator booleanToString = new Operator("ToString", new Signature(systemModel.getBoolean()), systemModel.getString());
    add(system, tb, booleanToString);
    add(system, tb, new Conversion(booleanToString, false));
    Operator integerToString = new Operator("ToString", new Signature(systemModel.getInteger()), systemModel.getString());
    add(system, tb, integerToString);
    add(system, tb, new Conversion(integerToString, false));
    Operator longToString = new Operator("ToString", new Signature(systemModel.getLong()), systemModel.getString());
    add(system, tb, longToString);
    add(system, tb, new Conversion(longToString, false));
    Operator decimalToString = new Operator("ToString", new Signature(systemModel.getDecimal()), systemModel.getString());
    add(system, tb, decimalToString);
    add(system, tb, new Conversion(decimalToString, false));
    Operator dateTimeToString = new Operator("ToString", new Signature(systemModel.getDateTime()), systemModel.getString());
    add(system, tb, dateTimeToString);
    add(system, tb, new Conversion(dateTimeToString, false));
    Operator dateToString = new Operator("ToString", new Signature(systemModel.getDate()), systemModel.getString());
    add(system, tb, dateToString);
    add(system, tb, new Conversion(dateToString, false));
    Operator timeToString = new Operator("ToString", new Signature(systemModel.getTime()), systemModel.getString());
    add(system, tb, timeToString);
    add(system, tb, new Conversion(timeToString, false));
    Operator quantityToString = new Operator("ToString", new Signature(systemModel.getQuantity()), systemModel.getString());
    add(system, tb, quantityToString);
    add(system, tb, new Conversion(quantityToString, false));
    Operator ratioToString = new Operator("ToString", new Signature(systemModel.getRatio()), systemModel.getString());
    add(system, tb, ratioToString);
    add(system, tb, new Conversion(ratioToString, false));
    // Operator stringToString = new Operator("ToString", new Signature(systemModel.getString()), systemModel.getString());
    // add(system, tb, stringToString);
    // add(system, tb, new Conversion(stringToString, false));
    // ToBoolean(Boolean) : Boolean
    // ToBoolean(Integer) : Boolean
    // ToBoolean(Decimal) : Boolean
    // ToBoolean(Long) : Boolean
    // ToBoolean(String) : Boolean
    Operator stringToBoolean = new Operator("ToBoolean", new Signature(systemModel.getString()), systemModel.getBoolean());
    add(system, tb, stringToBoolean);
    add(system, tb, new Conversion(stringToBoolean, false));
    Operator integerToBoolean = new Operator("ToBoolean", new Signature(systemModel.getInteger()), systemModel.getBoolean());
    add(system, tb, integerToBoolean);
    add(system, tb, new Conversion(integerToBoolean, false));
    Operator decimalToBoolean = new Operator("ToBoolean", new Signature(systemModel.getDecimal()), systemModel.getBoolean());
    add(system, tb, decimalToBoolean);
    add(system, tb, new Conversion(decimalToBoolean, false));
    Operator longToBoolean = new Operator("ToBoolean", new Signature(systemModel.getLong()), systemModel.getBoolean());
    add(system, tb, longToBoolean);
    add(system, tb, new Conversion(longToBoolean, false));
    // Operator booleanToBoolean = new Operator("ToBoolean", new Signature(systemModel.getBoolean()), systemModel.getBoolean());
    // add(system, tb, booleanToBoolean);
    // add(system, tb, new Conversion(booleanToBoolean, false));
    // ToChars(String) : List(String)
    Operator toChars = new Operator("ToChars", new Signature(systemModel.getString()), new ListType(systemModel.getString()));
    add(system, tb, toChars);
    add(system, tb, new Conversion(toChars, false));
    // ToInteger(String) : Integer
    // ToInteger(Boolean) : Integer
    // ToInteger(Long) : Integer
    // ToInteger(Integer) : Integer
    Operator stringToInteger = new Operator("ToInteger", new Signature(systemModel.getString()), systemModel.getInteger());
    add(system, tb, stringToInteger);
    add(system, tb, new Conversion(stringToInteger, false));
    Operator longToInteger = new Operator("ToInteger", new Signature(systemModel.getLong()), systemModel.getInteger());
    add(system, tb, longToInteger);
    add(system, tb, new Conversion(longToInteger, false));
    Operator booleanToInteger = new Operator("ToInteger", new Signature(systemModel.getBoolean()), systemModel.getInteger());
    add(system, tb, booleanToInteger);
    add(system, tb, new Conversion(booleanToInteger, false));
    // Operator integerToInteger = new Operator("ToInteger", new Signature(systemModel.getInteger()), systemModel.getInteger());
    // add(system, tb, integerToInteger);
    // add(system, tb, new Conversion(integerToInteger, false));
    // ToLong(Boolean) : Long
    // ToLong(String) : Long
    // ToLong(Integer) : Long
    // ToLong(Long) : Long
    Operator stringToLong = new Operator("ToLong", new Signature(systemModel.getString()), systemModel.getLong());
    add(system, tb, stringToLong);
    add(system, tb, new Conversion(stringToLong, false));
    Operator integerToLong = new Operator("ToLong", new Signature(systemModel.getInteger()), systemModel.getLong());
    add(system, tb, integerToLong);
    add(system, tb, new Conversion(integerToLong, true));
    // Operator longToLong = new Operator("ToLong", new Signature(systemModel.getLong()), systemModel.getLong());
    // add(system, tb, longToLong);
    // add(system, tb, new Conversion(longToLong, false));
    Operator booleanToLong = new Operator("ToLong", new Signature(systemModel.getBoolean()), systemModel.getLong());
    add(system, tb, booleanToLong);
    add(system, tb, new Conversion(booleanToLong, false));
    // ToDecimal(Boolean) : Decimal
    // ToDecimal(String) : Decimal
    // ToDecimal(Integer) : Decimal
    // ToDecimal(Long) : Decimal
    // ToDecimal(Decimal) : Decimal
    Operator stringToDecimal = new Operator("ToDecimal", new Signature(systemModel.getString()), systemModel.getDecimal());
    add(system, tb, stringToDecimal);
    add(system, tb, new Conversion(stringToDecimal, false));
    Operator integerToDecimal = new Operator("ToDecimal", new Signature(systemModel.getInteger()), systemModel.getDecimal());
    add(system, tb, integerToDecimal);
    add(system, tb, new Conversion(integerToDecimal, true));
    Operator longToDecimal = new Operator("ToDecimal", new Signature(systemModel.getLong()), systemModel.getDecimal());
    add(system, tb, longToDecimal);
    add(system, tb, new Conversion(longToDecimal, true));
    // Operator decimalToDecimal = new Operator("ToDecimal", new Signature(systemModel.getDecimal()), systemModel.getDecimal());
    // add(system, tb, decimalToDecimal);
    // add(system, tb, new Conversion(decimalToDecimal, false));
    Operator booleanToDecimal = new Operator("ToDecimal", new Signature(systemModel.getBoolean()), systemModel.getDecimal());
    add(system, tb, booleanToDecimal);
    add(system, tb, new Conversion(booleanToDecimal, false));
    // ToDateTime(String) : DateTime
    // ToDateTime(Date) : DateTime
    // ToDateTime(DateTime) : DateTime
    Operator stringToDateTime = new Operator("ToDateTime", new Signature(systemModel.getString()), systemModel.getDateTime());
    add(system, tb, stringToDateTime);
    add(system, tb, new Conversion(stringToDateTime, false));
    Operator dateToDateTime = new Operator("ToDateTime", new Signature(systemModel.getDate()), systemModel.getDateTime());
    add(system, tb, dateToDateTime);
    add(system, tb, new Conversion(dateToDateTime, true));
    // Operator dateTimeToDateTime = new Operator("ToDateTime", new Signature(systemModel.getDateTime()), systemModel.getDateTime());
    // add(system, tb, dateTimeToDateTime);
    // add(system, tb, new Conversion(dateTimeToDateTime, false));
    // ToDate(DateTime) : Date
    // ToDate(String) : Date
    // ToDate(Date) : Date
    Operator stringToDate = new Operator("ToDate", new Signature(systemModel.getString()), systemModel.getDate());
    add(system, tb, stringToDate);
    add(system, tb, new Conversion(stringToDate, false));
    Operator dateTimeToDate = new Operator("ToDate", new Signature(systemModel.getDateTime()), systemModel.getDate());
    add(system, tb, dateTimeToDate);
    add(system, tb, new Conversion(dateTimeToDate, false));
    // Operator dateToDate = new Operator("ToDate", new Signature(systemModel.getDate()), systemModel.getDate());
    // add(system, tb, dateToDate);
    // add(system, tb, new Conversion(dateToDate, false));
    // ToTime(String) : Time
    // ToTime(Time) : Time
    Operator stringToTime = new Operator("ToTime", new Signature(systemModel.getString()), systemModel.getTime());
    add(system, tb, stringToTime);
    add(system, tb, new Conversion(stringToTime, false));
    // Operator timeToTime = new Operator("ToTime", new Signature(systemModel.getTime()), systemModel.getTime());
    // add(system, tb, timeToTime);
    // add(system, tb, new Conversion(timeToTime, false));
    // ToQuantity(String) : Quantity
    // ToQuantity(Integer) : Quantity
    // ToQuantity(Ratio) : Quantity
    // ToQuantity(Decimal) : Quantity
    // ToQuantity(Quantity) : Quantity
    Operator stringToQuantity = new Operator("ToQuantity", new Signature(systemModel.getString()), systemModel.getQuantity());
    add(system, tb, stringToQuantity);
    add(system, tb, new Conversion(stringToQuantity, false));
    Operator ratioToQuantity = new Operator("ToQuantity", new Signature(systemModel.getRatio()), systemModel.getQuantity());
    add(system, tb, ratioToQuantity);
    add(system, tb, new Conversion(ratioToQuantity, false));
    Operator integerToQuantity = new Operator("ToQuantity", new Signature(systemModel.getInteger()), systemModel.getQuantity());
    add(system, tb, integerToQuantity);
    add(system, tb, new Conversion(integerToQuantity, true));
    Operator decimalToQuantity = new Operator("ToQuantity", new Signature(systemModel.getDecimal()), systemModel.getQuantity());
    add(system, tb, decimalToQuantity);
    add(system, tb, new Conversion(decimalToQuantity, true));
    // Operator quantityToQuantity = new Operator("ToQuantity", new Signature(systemModel.getQuantity()), systemModel.getQuantity());
    // add(system, tb, quantityToQuantity);
    // add(system, tb, new Conversion(quantityToQuantity, false));
    // ToRatio(String) : Ratio
    // ToRatio(Ratio) : Ratio
    Operator stringToRatio = new Operator("ToRatio", new Signature(systemModel.getString()), systemModel.getRatio());
    add(system, tb, stringToRatio);
    add(system, tb, new Conversion(stringToRatio, false));
    // Operator ratioToRatio = new Operator("ToRatio", new Signature(systemModel.getRatio()), systemModel.getRatio());
    // add(system, tb, ratioToRatio);
    // add(system, tb, new Conversion(ratioToRatio, false));
    // ConvertsToBoolean(Any): Boolean
    Operator convertsTo = new Operator("ConvertsToBoolean", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToInteger(Any): Boolean
    convertsTo = new Operator("ConvertsToInteger", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToLong(Any): Boolean
    convertsTo = new Operator("ConvertsToLong", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToDecimal
    convertsTo = new Operator("ConvertsToDecimal", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToDateTime
    convertsTo = new Operator("ConvertsToDateTime", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToDate
    convertsTo = new Operator("ConvertsToDate", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToTime
    convertsTo = new Operator("ConvertsToTime", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToString
    convertsTo = new Operator("ConvertsToString", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToQuantity
    convertsTo = new Operator("ConvertsToQuantity", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // ConvertsToRatio
    convertsTo = new Operator("ConvertsToRatio", new Signature(systemModel.getAny()), systemModel.getBoolean());
    add(system, tb, convertsTo);
    // CanConvertQuantity
    Operator canConvertToQuantity = new Operator("CanConvertQuantity", new Signature(systemModel.getQuantity(), systemModel.getString()), systemModel.getBoolean());
    add(system, tb, canConvertToQuantity);
    // ConvertQuantity
    Operator convertToQuantity = new Operator("ConvertQuantity", new Signature(systemModel.getQuantity(), systemModel.getString()), systemModel.getQuantity());
    add(system, tb, convertToQuantity);
    // Comparison Operators
    // Equal<T : value>(T, T) : Boolean
    // TypeParameter T = new TypeParameter("T", TypeParameter.TypeParameterConstraint.VALUE, null);
    // add(system, tb, new GenericOperator("Equal", new Signature(T, T), systemModel.getBoolean(), T));
    // Equal<C : class>(C, C) : Boolean
    TypeParameter C = new TypeParameter("C", TypeParameter.TypeParameterConstraint.CLASS, null);
    add(system, tb, new GenericOperator("Equal", new Signature(C, C), systemModel.getBoolean(), C));
    // Equal<R : tuple>(R, R) : Boolean
    TypeParameter R = new TypeParameter("R", TypeParameter.TypeParameterConstraint.TUPLE, null);
    add(system, tb, new GenericOperator("Equal", new Signature(R, R), systemModel.getBoolean(), R));
    // Equal<H : choice>(H, H) : Boolean
    TypeParameter H = new TypeParameter("H", TypeParameter.TypeParameterConstraint.CHOICE, null);
    add(system, tb, new GenericOperator("Equal", new Signature(H, H), systemModel.getBoolean(), H));
    // Equal(Any, Any) : Boolean
    // add(system, tb, new Operator("Equal", new Signature(systemModel.getAny(), systemModel.getAny()), systemModel.getBoolean()));
    // Equivalent<T : value>(T, T) : Boolean
    // T = new TypeParameter("T", TypeParameter.TypeParameterConstraint.VALUE, null);
    // add(system, tb, new GenericOperator("Equivalent", new Signature(T, T), systemModel.getBoolean(), T));
    // Equivalent<C : class>(C, C) : Boolean
    C = new TypeParameter("C", TypeParameter.TypeParameterConstraint.CLASS, null);
    add(system, tb, new GenericOperator("Equivalent", new Signature(C, C), systemModel.getBoolean(), C));
    // Equivalent<R : tuple>(R, R) : Boolean
    R = new TypeParameter("R", TypeParameter.TypeParameterConstraint.TUPLE, null);
    add(system, tb, new GenericOperator("Equivalent", new Signature(R, R), systemModel.getBoolean(), R));
    // Equivalent<H : choice>(H, H) : Boolean
    H = new TypeParameter("H", TypeParameter.TypeParameterConstraint.CHOICE, null);
    add(system, tb, new GenericOperator("Equivalent", new Signature(H, H), systemModel.getBoolean(), H));
    // Equivalent(Any, Any) : Boolean
    // add(system, tb, new Operator("Equivalent", new Signature(systemModel.getAny(), systemModel.getAny()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getBoolean(), systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getBoolean(), systemModel.getBoolean()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getBoolean()));
    add(system, tb, new Operator("Less", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getBoolean()));
    add(system, tb, new Operator("LessOrEqual", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getBoolean()));
    add(system, tb, new Operator("Greater", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getBoolean()));
    add(system, tb, new Operator("GreaterOrEqual", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getRatio(), systemModel.getRatio()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getRatio(), systemModel.getRatio()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getCode(), systemModel.getCode()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getCode(), systemModel.getCode()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equal", new Signature(systemModel.getConcept(), systemModel.getConcept()), systemModel.getBoolean()));
    add(system, tb, new Operator("Equivalent", new Signature(systemModel.getConcept(), systemModel.getConcept()), systemModel.getBoolean()));
    // Arithmetic Operators
    add(system, tb, new Operator("Abs", new Signature(systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Abs", new Signature(systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Abs", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Abs", new Signature(systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Add", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Add", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Add", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Add", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Ceiling", new Signature(systemModel.getDecimal()), systemModel.getInteger()));
    add(system, tb, new Operator("Divide", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    // add(system, tb, new Operator("Divide", new Signature(systemModel.getQuantity(), systemModel.getDecimal()), systemModel.getQuantity()));
    add(system, tb, new Operator("Divide", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Exp", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Floor", new Signature(systemModel.getDecimal()), systemModel.getInteger()));
    add(system, tb, new Operator("HighBoundary", new Signature(systemModel.getDecimal(), systemModel.getInteger()), systemModel.getDecimal()));
    add(system, tb, new Operator("HighBoundary", new Signature(systemModel.getDate(), systemModel.getInteger()), systemModel.getDate()));
    add(system, tb, new Operator("HighBoundary", new Signature(systemModel.getDateTime(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("HighBoundary", new Signature(systemModel.getTime(), systemModel.getInteger()), systemModel.getTime()));
    add(system, tb, new Operator("Log", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("LowBoundary", new Signature(systemModel.getDecimal(), systemModel.getInteger()), systemModel.getDecimal()));
    add(system, tb, new Operator("LowBoundary", new Signature(systemModel.getDate(), systemModel.getInteger()), systemModel.getDate()));
    add(system, tb, new Operator("LowBoundary", new Signature(systemModel.getDateTime(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("LowBoundary", new Signature(systemModel.getTime(), systemModel.getInteger()), systemModel.getTime()));
    add(system, tb, new Operator("Ln", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    // MaxValue<T>() : T
    // MinValue<T>() : T
    add(system, tb, new Operator("Modulo", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Modulo", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Modulo", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Modulo", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Multiply", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Multiply", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Multiply", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Multiply", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Negate", new Signature(systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Negate", new Signature(systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Negate", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Negate", new Signature(systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Precision", new Signature(systemModel.getDecimal()), systemModel.getInteger()));
    add(system, tb, new Operator("Precision", new Signature(systemModel.getDate()), systemModel.getInteger()));
    add(system, tb, new Operator("Precision", new Signature(systemModel.getDateTime()), systemModel.getInteger()));
    add(system, tb, new Operator("Precision", new Signature(systemModel.getTime()), systemModel.getInteger()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getDate()), systemModel.getDate()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getDateTime()), systemModel.getDateTime()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getTime()), systemModel.getTime()));
    add(system, tb, new Operator("Predecessor", new Signature(systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Power", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Power", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Power", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Round", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Round", new Signature(systemModel.getDecimal(), systemModel.getInteger()), systemModel.getDecimal()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getDate()), systemModel.getDate()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getDateTime()), systemModel.getDateTime()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getTime()), systemModel.getTime()));
    add(system, tb, new Operator("Successor", new Signature(systemModel.getQuantity()), systemModel.getQuantity()));
    add(system, tb, new Operator("Truncate", new Signature(systemModel.getDecimal()), systemModel.getInteger()));
    add(system, tb, new Operator("TruncatedDivide", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getInteger()));
    add(system, tb, new Operator("TruncatedDivide", new Signature(systemModel.getLong(), systemModel.getLong()), systemModel.getLong()));
    add(system, tb, new Operator("TruncatedDivide", new Signature(systemModel.getDecimal(), systemModel.getDecimal()), systemModel.getDecimal()));
    add(system, tb, new Operator("TruncatedDivide", new Signature(systemModel.getQuantity(), systemModel.getQuantity()), systemModel.getQuantity()));
    // String operators
    add(system, tb, new Operator("Add", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getString()));
    add(system, tb, new Operator("Combine", new Signature(new ListType(systemModel.getString())), systemModel.getString()));
    add(system, tb, new Operator("Combine", new Signature(new ListType(systemModel.getString()), systemModel.getString()), systemModel.getString()));
    add(system, tb, new Operator("Concatenate", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getString()));
    add(system, tb, new Operator("EndsWith", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("Indexer", new Signature(systemModel.getString(), systemModel.getInteger()), systemModel.getString()));
    add(system, tb, new Operator("LastPositionOf", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getInteger()));
    add(system, tb, new Operator("Length", new Signature(systemModel.getString()), systemModel.getInteger()));
    add(system, tb, new Operator("Lower", new Signature(systemModel.getString()), systemModel.getString()));
    add(system, tb, new Operator("Matches", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("PositionOf", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getInteger()));
    add(system, tb, new Operator("ReplaceMatches", new Signature(systemModel.getString(), systemModel.getString(), systemModel.getString()), systemModel.getString()));
    add(system, tb, new Operator("Split", new Signature(systemModel.getString(), systemModel.getString()), new ListType(systemModel.getString())));
    add(system, tb, new Operator("SplitOnMatches", new Signature(systemModel.getString(), systemModel.getString()), new ListType(systemModel.getString())));
    add(system, tb, new Operator("StartsWith", new Signature(systemModel.getString(), systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("Substring", new Signature(systemModel.getString(), systemModel.getInteger()), systemModel.getString()));
    add(system, tb, new Operator("Substring", new Signature(systemModel.getString(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getString()));
    add(system, tb, new Operator("Upper", new Signature(systemModel.getString()), systemModel.getString()));
    // Date/Time Operators
    add(system, tb, new Operator("Add", new Signature(systemModel.getDateTime(), systemModel.getQuantity()), systemModel.getDateTime()));
    add(system, tb, new Operator("Add", new Signature(systemModel.getDate(), systemModel.getQuantity()), systemModel.getDate()));
    add(system, tb, new Operator("Add", new Signature(systemModel.getTime(), systemModel.getQuantity()), systemModel.getTime()));
    add(system, tb, new Operator("After", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("After", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("After", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Before", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Before", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("Before", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getDateTime()));
    add(system, tb, new Operator("DateTime", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getDecimal()), systemModel.getDateTime()));
    add(system, tb, new Operator("Date", new Signature(systemModel.getInteger()), systemModel.getDate()));
    add(system, tb, new Operator("Date", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getDate()));
    add(system, tb, new Operator("Date", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getDate()));
    add(system, tb, new Operator("DateFrom", new Signature(systemModel.getDateTime()), systemModel.getDate()));
    add(system, tb, new Operator("TimeFrom", new Signature(systemModel.getDateTime()), systemModel.getTime()));
    add(system, tb, new Operator("TimezoneFrom", new Signature(systemModel.getDateTime()), systemModel.getDecimal()));
    add(system, tb, new Operator("TimezoneOffsetFrom", new Signature(systemModel.getDateTime()), systemModel.getDecimal()));
    add(system, tb, new Operator("DateTimeComponentFrom", new Signature(systemModel.getDateTime()), systemModel.getInteger()));
    add(system, tb, new Operator("DateTimeComponentFrom", new Signature(systemModel.getDate()), systemModel.getInteger()));
    add(system, tb, new Operator("DateTimeComponentFrom", new Signature(systemModel.getTime()), systemModel.getInteger()));
    add(system, tb, new Operator("DifferenceBetween", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getInteger()));
    add(system, tb, new Operator("DifferenceBetween", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getInteger()));
    add(system, tb, new Operator("DifferenceBetween", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getInteger()));
    add(system, tb, new Operator("DurationBetween", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getInteger()));
    add(system, tb, new Operator("DurationBetween", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getInteger()));
    add(system, tb, new Operator("DurationBetween", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getInteger()));
    add(system, tb, new Operator("Now", new Signature(), systemModel.getDateTime()));
    add(system, tb, new Operator("SameAs", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameAs", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameAs", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameOrAfter", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameOrAfter", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameOrAfter", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameOrBefore", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameOrBefore", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getBoolean()));
    add(system, tb, new Operator("SameOrBefore", new Signature(systemModel.getTime(), systemModel.getTime()), systemModel.getBoolean()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getDateTime(), systemModel.getQuantity()), systemModel.getDateTime()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getDate(), systemModel.getQuantity()), systemModel.getDate()));
    add(system, tb, new Operator("Subtract", new Signature(systemModel.getTime(), systemModel.getQuantity()), systemModel.getTime()));
    add(system, tb, new Operator("Today", new Signature(), systemModel.getDate()));
    add(system, tb, new Operator("Time", new Signature(systemModel.getInteger()), systemModel.getTime()));
    add(system, tb, new Operator("Time", new Signature(systemModel.getInteger(), systemModel.getInteger()), systemModel.getTime()));
    add(system, tb, new Operator("Time", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getTime()));
    add(system, tb, new Operator("Time", new Signature(systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger(), systemModel.getInteger()), systemModel.getTime()));
    add(system, tb, new Operator("TimeOfDay", new Signature(), systemModel.getTime()));
    // Interval Operators
    // After<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("After", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Before<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Before", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Collapse<T>(list<interval<T>>) : list<interval<T>>
    // Collapse<T>(list<interval<T>>, Quantity) : list<interval<T>>
    add(system, tb, new GenericOperator("Collapse", new Signature(new ListType(new IntervalType(new TypeParameter("T"))), systemModel.getQuantity()), new ListType(new IntervalType(new TypeParameter("T"))), new TypeParameter("T")));
    // Contains<T>(interval<T>, T) : Boolean
    add(system, tb, new GenericOperator("Contains", new Signature(new IntervalType(new TypeParameter("T")), new TypeParameter("T")), systemModel.getBoolean(), new TypeParameter("T")));
    // End<T>(interval<T>) : T
    add(system, tb, new GenericOperator("End", new Signature(new IntervalType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    // Ends<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Ends", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Equal<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Equal", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Equivalent<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Equivalent", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Except<T>(interval<T>, interval<T>) : interval<T>
    add(system, tb, new GenericOperator("Except", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), new IntervalType(new TypeParameter("T")), new TypeParameter("T")));
    // Expand<T>(list<interval<T>>) : list<interval<T>>
    // Expand<T>(list<interval<T>>, Quantity) : list<interval<T>>
    // Expand<T>(interval<T>) : List<T>
    // Expand<T>(interval<T>, Quantity) : list<T>
    add(system, tb, new GenericOperator("Expand", new Signature(new ListType(new IntervalType(new TypeParameter("T"))), systemModel.getQuantity()), new ListType(new IntervalType(new TypeParameter("T"))), new TypeParameter("T")));
    add(system, tb, new GenericOperator("Expand", new Signature(new IntervalType(new TypeParameter("T")), systemModel.getQuantity()), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // In<T>(T, interval<T>) : Boolean
    add(system, tb, new GenericOperator("In", new Signature(new TypeParameter("T"), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Includes<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Includes", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // IncludedIn<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("IncludedIn", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Intersect<T>(interval<T>, interval<T>) : interval<T>
    add(system, tb, new GenericOperator("Intersect", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), new IntervalType(new TypeParameter("T")), new TypeParameter("T")));
    // Meets<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Meets", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // MeetsBefore<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("MeetsBefore", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // MeetsAfter<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("MeetsAfter", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Overlaps<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Overlaps", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // OverlapsBefore<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("OverlapsBefore", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // OverlapsAfter<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("OverlapsAfter", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // PointFrom<T>(interval<T>) : T
    GenericOperator pointFrom = new GenericOperator("PointFrom", new Signature(new IntervalType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T"));
    add(system, tb, pointFrom);
    // ProperContains<T>(interval<T>, T) : Boolean
    add(system, tb, new GenericOperator("ProperContains", new Signature(new IntervalType(new TypeParameter("T")), new TypeParameter("T")), systemModel.getBoolean(), new TypeParameter("T")));
    // ProperIn<T>(T, interval<T>) : Boolean
    add(system, tb, new GenericOperator("ProperIn", new Signature(new TypeParameter("T"), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // ProperIncludes<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("ProperIncludes", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // ProperIncludedIn<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("ProperIncludedIn", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // SameAs<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("SameAs", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // SameOrAfter<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("SameOrAfter", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // SameOrBefore<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("SameOrBefore", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Size<T>(interval<T>) : T
    add(system, tb, new GenericOperator("Size", new Signature(new IntervalType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    // Start<T>(interval<T>) : T
    add(system, tb, new GenericOperator("Start", new Signature(new IntervalType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    // Starts<T>(interval<T>, interval<T>) : Boolean
    add(system, tb, new GenericOperator("Starts", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Union<T>(interval<T>, interval<T>) : interval<T>
    add(system, tb, new GenericOperator("Union", new Signature(new IntervalType(new TypeParameter("T")), new IntervalType(new TypeParameter("T"))), new IntervalType(new TypeParameter("T")), new TypeParameter("T")));
    // Width<T>(interval<T>) : T
    add(system, tb, new GenericOperator("Width", new Signature(new IntervalType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    // List Operators
    // Contains<T>(list<T>, T) : Boolean
    add(system, tb, new GenericOperator("Contains", new Signature(new ListType(new TypeParameter("T")), new TypeParameter("T")), systemModel.getBoolean(), new TypeParameter("T")));
    // Distinct<T>(list<T>) : list<T>
    add(system, tb, new GenericOperator("Distinct", new Signature(new ListType(new TypeParameter("T"))), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // Equal<T>(list<T>, list<T>) : Boolean
    add(system, tb, new GenericOperator("Equal", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Equivalent<T>(list<T>, list<T>) : Boolean
    add(system, tb, new GenericOperator("Equivalent", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Except<T>(list<T>, list<T>) : list<T>
    add(system, tb, new GenericOperator("Except", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // Exists<T>(list<T>) : Boolean
    add(system, tb, new GenericOperator("Exists", new Signature(new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Flatten<T>(list<list<T>>) : list<T>
    add(system, tb, new GenericOperator("Flatten", new Signature(new ListType(new ListType(new TypeParameter("T")))), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // First<T>(list<T>) : T
    add(system, tb, new GenericOperator("First", new Signature(new ListType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    // In<T>(T, list<T>) : Boolean
    add(system, tb, new GenericOperator("In", new Signature(new TypeParameter("T"), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Includes<T>(list<T>, list<T>) : Boolean
    add(system, tb, new GenericOperator("Includes", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // IncludedIn<T>(list<T>, list<T>) : Boolean
    add(system, tb, new GenericOperator("IncludedIn", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // Indexer<T>(list<T>, integer) : T
    add(system, tb, new GenericOperator("Indexer", new Signature(new ListType(new TypeParameter("T")), systemModel.getInteger()), new TypeParameter("T"), new TypeParameter("T")));
    // IndexOf<T>(list<T>, T) : Integer
    add(system, tb, new GenericOperator("IndexOf", new Signature(new ListType(new TypeParameter("T")), new TypeParameter("T")), systemModel.getInteger(), new TypeParameter("T")));
    // Intersect<T>(list<T>, list<T>) : list<T>
    add(system, tb, new GenericOperator("Intersect", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // Last<T>(list<T>) : T
    add(system, tb, new GenericOperator("Last", new Signature(new ListType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    // Length<T>(list<T>) : Integer
    add(system, tb, new GenericOperator("Length", new Signature(new ListType(new TypeParameter("T"))), systemModel.getInteger(), new TypeParameter("T")));
    // ProperContains<T>(list<T>, T) : Boolean
    add(system, tb, new GenericOperator("ProperContains", new Signature(new ListType(new TypeParameter("T")), new TypeParameter("T")), systemModel.getBoolean(), new TypeParameter("T")));
    // ProperIn<T>(T, list<T>) : Boolean
    add(system, tb, new GenericOperator("ProperIn", new Signature(new TypeParameter("T"), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // ProperIncludes<T>(list<T>, list<T>) : Boolean
    add(system, tb, new GenericOperator("ProperIncludes", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // ProperIncludedIn<T>(list<T>, list<T>) : Boolean
    add(system, tb, new GenericOperator("ProperIncludedIn", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), systemModel.getBoolean(), new TypeParameter("T")));
    // SingletonFrom<T>(list<T>) : T
    GenericOperator singletonFrom = new GenericOperator("SingletonFrom", new Signature(new ListType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T"));
    add(system, tb, singletonFrom);
    // // NOTE: FHIRPath Implicit List Demotion
    // Generic conversions turned out to be computationally expensive, so we added explicit list promotion/demotion in the conversion map directly instead.
    // add(system, tb, new Conversion(singletonFrom, true));
    // Skip(list<T>, Integer): list<T>
    add(system, tb, new GenericOperator("Skip", new Signature(new ListType(new TypeParameter("T")), systemModel.getInteger()), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // Tail(list<T>): list<T>
    add(system, tb, new GenericOperator("Tail", new Signature(new ListType(new TypeParameter("T"))), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // Take(list<T>, Integer): list<T>
    add(system, tb, new GenericOperator("Take", new Signature(new ListType(new TypeParameter("T")), systemModel.getInteger()), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // Union<T>(list<T>, list<T>) : list<T>
    add(system, tb, new GenericOperator("Union", new Signature(new ListType(new TypeParameter("T")), new ListType(new TypeParameter("T"))), new ListType(new TypeParameter("T")), new TypeParameter("T")));
    // NOTE: FHIRPath Implicit List Promotion operator
    // GenericOperator toList = new GenericOperator("List", new Signature(new TypeParameter("T")), new ListType(new TypeParameter("T")), new TypeParameter("T"));
    // add(system, tb, toList);
    // add(system, tb, new Conversion(toList, true));
    // Aggregate Operators
    add(system, tb, new Operator("AllTrue", new Signature(new ListType(systemModel.getBoolean())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyTrue", new Signature(new ListType(systemModel.getBoolean())), systemModel.getBoolean()));
    add(system, tb, new Operator("Avg", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Avg", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    // Count<T>(list<T>) : Integer
    add(system, tb, new GenericOperator("Count", new Signature(new ListType(new TypeParameter("T"))), systemModel.getInteger(), new TypeParameter("T")));
    // // Count(list<Any>) : Integer
    // add(system, tb, new Operator("Count", new Signature(new ListType(systemModel.getAny())), systemModel.getInteger()));
    add(system, tb, new Operator("GeometricMean", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getInteger())), systemModel.getInteger()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getLong())), systemModel.getLong()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getDateTime())), systemModel.getDateTime()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getDate())), systemModel.getDate()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getTime())), systemModel.getTime()));
    add(system, tb, new Operator("Max", new Signature(new ListType(systemModel.getString())), systemModel.getString()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getInteger())), systemModel.getInteger()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getLong())), systemModel.getLong()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getDateTime())), systemModel.getDateTime()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getDate())), systemModel.getDate()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getTime())), systemModel.getTime()));
    add(system, tb, new Operator("Min", new Signature(new ListType(systemModel.getString())), systemModel.getString()));
    add(system, tb, new Operator("Median", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Median", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    // Mode<T>(list<T>) : T
    add(system, tb, new GenericOperator("Mode", new Signature(new ListType(new TypeParameter("T"))), new TypeParameter("T"), new TypeParameter("T")));
    add(system, tb, new Operator("PopulationStdDev", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("PopulationStdDev", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("PopulationVariance", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("PopulationVariance", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("Product", new Signature(new ListType(systemModel.getInteger())), systemModel.getInteger()));
    add(system, tb, new Operator("Product", new Signature(new ListType(systemModel.getLong())), systemModel.getLong()));
    add(system, tb, new Operator("Product", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Product", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("StdDev", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("StdDev", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("Sum", new Signature(new ListType(systemModel.getInteger())), systemModel.getInteger()));
    add(system, tb, new Operator("Sum", new Signature(new ListType(systemModel.getLong())), systemModel.getLong()));
    add(system, tb, new Operator("Sum", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Sum", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    add(system, tb, new Operator("Variance", new Signature(new ListType(systemModel.getDecimal())), systemModel.getDecimal()));
    add(system, tb, new Operator("Variance", new Signature(new ListType(systemModel.getQuantity())), systemModel.getQuantity()));
    // Clinical
    // ToConcept(Code)
    Operator codeToConcept = new Operator("ToConcept", new Signature(systemModel.getCode()), systemModel.getConcept());
    add(system, tb, codeToConcept);
    add(system, tb, new Conversion(codeToConcept, true));
    // ToConcept(list<Code>)
    Operator codesToConcept = new Operator("ToConcept", new Signature(new ListType(systemModel.getCode())), systemModel.getConcept());
    add(system, tb, codesToConcept);
    add(system, tb, new Conversion(codesToConcept, false));
    add(system, tb, new Operator("CalculateAge", new Signature(systemModel.getDateTime()), systemModel.getInteger()));
    add(system, tb, new Operator("CalculateAge", new Signature(systemModel.getDate()), systemModel.getInteger()));
    add(system, tb, new Operator("CalculateAgeAt", new Signature(systemModel.getDateTime(), systemModel.getDateTime()), systemModel.getInteger()));
    add(system, tb, new Operator("CalculateAgeAt", new Signature(systemModel.getDate(), systemModel.getDate()), systemModel.getInteger()));
    add(system, tb, new Operator("InValueSet", new Signature(systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("InValueSet", new Signature(systemModel.getCode()), systemModel.getBoolean()));
    add(system, tb, new Operator("InValueSet", new Signature(systemModel.getConcept()), systemModel.getBoolean()));
    add(system, tb, new Operator("InValueSet", new Signature(systemModel.getString(), systemModel.getValueSet()), systemModel.getBoolean()));
    add(system, tb, new Operator("InValueSet", new Signature(systemModel.getCode(), systemModel.getValueSet()), systemModel.getBoolean()));
    add(system, tb, new Operator("InValueSet", new Signature(systemModel.getConcept(), systemModel.getValueSet()), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInValueSet", new Signature(new ListType(systemModel.getString())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInValueSet", new Signature(new ListType(systemModel.getCode())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInValueSet", new Signature(new ListType(systemModel.getConcept())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInValueSet", new Signature(new ListType(systemModel.getString()), systemModel.getValueSet()), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInValueSet", new Signature(new ListType(systemModel.getCode()), systemModel.getValueSet()), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInValueSet", new Signature(new ListType(systemModel.getConcept()), systemModel.getValueSet()), systemModel.getBoolean()));
    add(system, tb, new Operator("InCodeSystem", new Signature(systemModel.getString()), systemModel.getBoolean()));
    add(system, tb, new Operator("InCodeSystem", new Signature(systemModel.getCode()), systemModel.getBoolean()));
    add(system, tb, new Operator("InCodeSystem", new Signature(systemModel.getConcept()), systemModel.getBoolean()));
    add(system, tb, new Operator("InCodeSystem", new Signature(systemModel.getString(), systemModel.getCodeSystem()), systemModel.getBoolean()));
    add(system, tb, new Operator("InCodeSystem", new Signature(systemModel.getCode(), systemModel.getCodeSystem()), systemModel.getBoolean()));
    add(system, tb, new Operator("InCodeSystem", new Signature(systemModel.getConcept(), systemModel.getCodeSystem()), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInCodeSystem", new Signature(new ListType(systemModel.getString())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInCodeSystem", new Signature(new ListType(systemModel.getCode())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInCodeSystem", new Signature(new ListType(systemModel.getConcept())), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInCodeSystem", new Signature(new ListType(systemModel.getString()), systemModel.getCodeSystem()), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInCodeSystem", new Signature(new ListType(systemModel.getCode()), systemModel.getCodeSystem()), systemModel.getBoolean()));
    add(system, tb, new Operator("AnyInCodeSystem", new Signature(new ListType(systemModel.getConcept()), systemModel.getCodeSystem()), systemModel.getBoolean()));
    Operator expandValueSet = new Operator("ExpandValueSet", new Signature(systemModel.getValueSet()), new ListType(systemModel.getCode()));
    add(system, tb, expandValueSet);
    add(system, tb, new Conversion(expandValueSet, true));
    add(system, tb, new Operator("Subsumes", new Signature(systemModel.getCode(), systemModel.getCode()), systemModel.getBoolean()));
    add(system, tb, new Operator("Subsumes", new Signature(systemModel.getConcept(), systemModel.getConcept()), systemModel.getBoolean()));
    add(system, tb, new Operator("SubsumedBy", new Signature(systemModel.getCode(), systemModel.getCode()), systemModel.getBoolean()));
    add(system, tb, new Operator("SubsumedBy", new Signature(systemModel.getConcept(), systemModel.getConcept()), systemModel.getBoolean()));
    // Errors
    // Message(source T, condition Boolean, code String, severity String, message String) T
    add(system, tb, new GenericOperator("Message", new Signature(new TypeParameter("T"), systemModel.getBoolean(), systemModel.getString(), systemModel.getString(), systemModel.getString()), new TypeParameter("T"), new TypeParameter("T")));
    return system;
}
Also used : VersionedIdentifier(org.hl7.elm.r1.VersionedIdentifier)

Example 25 with IndexOf

use of org.hl7.elm.r1.IndexOf in project clinical_quality_language by cqframework.

the class IndexOfInvocation method setOperands.

@Override
public void setOperands(Iterable<Expression> operands) {
    Iterator<Expression> it = operands.iterator();
    if (!it.hasNext()) {
        throw new IllegalArgumentException("IndexOf operation requires two operands.");
    }
    IndexOf indexOf = (IndexOf) expression;
    indexOf.setSource(it.next());
    if (!it.hasNext()) {
        throw new IllegalArgumentException("IndexOf operation requires two operands.");
    }
    indexOf.setElement(it.next());
    if (it.hasNext()) {
        throw new IllegalArgumentException("IndexOf operation requires two operands.");
    }
}
Also used : Expression(org.hl7.elm.r1.Expression) IndexOf(org.hl7.elm.r1.IndexOf)

Aggregations

DefinitionException (org.hl7.fhir.exceptions.DefinitionException)12 ArrayList (java.util.ArrayList)11 FHIRException (org.hl7.fhir.exceptions.FHIRException)11 ElementDefinition (org.hl7.fhir.r5.model.ElementDefinition)9 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)8 FHIRFormatError (org.hl7.fhir.exceptions.FHIRFormatError)7 FileNotFoundException (java.io.FileNotFoundException)6 IOException (java.io.IOException)6 ContactPoint (org.hl7.fhir.r5.model.ContactPoint)6 XhtmlNode (org.hl7.fhir.utilities.xhtml.XhtmlNode)6 List (java.util.List)5 ElementDefinition (org.hl7.fhir.r4.model.ElementDefinition)5 ElementDefinition (org.hl7.fhir.r4b.model.ElementDefinition)5 File (java.io.File)4 NotImplementedException (org.apache.commons.lang3.NotImplementedException)4 ElementDefinition (org.hl7.fhir.dstu3.model.ElementDefinition)4 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)4 URISyntaxException (java.net.URISyntaxException)3 ParseException (java.text.ParseException)3 IndexOf (io.atlasmap.v2.IndexOf)2