001package org.hl7.fhir.r5.utils;
002
003import java.lang.reflect.Field;
004import java.lang.reflect.Modifier;
005
006/*
007  Copyright (c) 2011+, HL7, Inc.
008  All rights reserved.
009
010  Redistribution and use in source and binary forms, with or without modification, 
011  are permitted provided that the following conditions are met:
012
013 * Redistributions of source code must retain the above copyright notice, this 
014     list of conditions and the following disclaimer.
015 * Redistributions in binary form must reproduce the above copyright notice, 
016     this list of conditions and the following disclaimer in the documentation 
017     and/or other materials provided with the distribution.
018 * Neither the name of HL7 nor the names of its contributors may be used to 
019     endorse or promote products derived from this software without specific 
020     prior written permission.
021
022  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
023  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
024  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
025  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
026  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
027  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
028  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
029  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
030  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
031  POSSIBILITY OF SUCH DAMAGE.
032
033 */
034
035
036
037/*
038Copyright (c) 2011+, HL7, Inc
039All rights reserved.
040
041Redistribution and use in source and binary forms, with or without modification, 
042are permitted provided that the following conditions are met:
043
044 * Redistributions of source code must retain the above copyright notice, this 
045   list of conditions and the following disclaimer.
046 * Redistributions in binary form must reproduce the above copyright notice, 
047   this list of conditions and the following disclaimer in the documentation 
048   and/or other materials provided with the distribution.
049 * Neither the name of HL7 nor the names of its contributors may be used to 
050   endorse or promote products derived from this software without specific 
051   prior written permission.
052
053THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
054ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
055WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
056IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
057INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
058NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
059PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
060WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
061ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
062POSSIBILITY OF SUCH DAMAGE.
063
064 */
065
066import java.util.ArrayList;
067import java.util.HashMap;
068import java.util.Iterator;
069import java.util.List;
070import java.util.Map;
071import java.util.Set;
072import java.util.HashSet;
073
074import org.apache.commons.lang3.StringUtils;
075import org.fhir.ucum.Utilities;
076import org.hl7.fhir.exceptions.FHIRException;
077import org.hl7.fhir.r5.model.BackboneElement;
078import org.hl7.fhir.r5.model.Base;
079import org.hl7.fhir.r5.model.BooleanType;
080import org.hl7.fhir.r5.model.CanonicalType;
081import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
082import org.hl7.fhir.r5.model.CodeType;
083import org.hl7.fhir.r5.model.CodeableConcept;
084import org.hl7.fhir.r5.model.Coding;
085import org.hl7.fhir.r5.model.DataType;
086import org.hl7.fhir.r5.model.DecimalType;
087import org.hl7.fhir.r5.model.DomainResource;
088import org.hl7.fhir.r5.model.Element;
089import org.hl7.fhir.r5.model.ElementDefinition;
090import org.hl7.fhir.r5.model.Extension;
091import org.hl7.fhir.r5.model.ExtensionHelper;
092import org.hl7.fhir.r5.model.Factory;
093import org.hl7.fhir.r5.model.Integer64Type;
094import org.hl7.fhir.r5.model.IntegerType;
095import org.hl7.fhir.r5.model.MarkdownType;
096import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
097import org.hl7.fhir.r5.model.PrimitiveType;
098import org.hl7.fhir.r5.model.Property;
099import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent;
100import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType;
101import org.hl7.fhir.r5.model.StringType;
102import org.hl7.fhir.r5.model.StructureDefinition;
103import org.hl7.fhir.r5.model.UriType;
104import org.hl7.fhir.r5.model.UrlType;
105import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
106import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
107import org.hl7.fhir.utilities.StandardsStatus;
108import org.hl7.fhir.utilities.validation.ValidationMessage;
109import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
110import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
111import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
112
113
114public class ToolingExtensions {
115
116  public static final String EXT_ISSUE_MSG_ID = "http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id";
117  public static final String EXT_ISSUE_LINE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line";
118  public static final String EXT_ISSUE_COL = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col";
119  public static final String EXT_OO_FILE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-file";  
120  public static final String EXT_RESOURCE_IMPLEMENTS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-implements";
121  public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; // r2 - r3
122  public static final String EXT_XML_NAME_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/elementdefinition-xml-name";  
123  public static final String EXT_XML_NAME = "http://hl7.org/fhir/tools/StructureDefinition/xml-name";  
124  public static final String EXT_EXPLICIT_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name";
125
126  public static final String EXT_IGP_RESOURCES = "http://hl7.org/fhir/StructureDefinition/igpublisher-folder-resource";
127  public static final String EXT_IGP_PAGES = "http://hl7.org/fhir/StructureDefinition/igpublisher-folder-pages"; 
128  public static final String EXT_IGP_SPREADSHEET = "http://hl7.org/fhir/StructureDefinition/igpublisher-spreadsheet";
129  public static final String EXT_IGP_MAPPING_CSV = "http://hl7.org/fhir/StructureDefinition/igpublisher-mapping-csv";
130  public static final String EXT_IGP_BUNDLE = "http://hl7.org/fhir/tools/StructureDefinition/igpublisher-bundle";
131  public static final String EXT_IGP_BASE = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-base";
132  public static final String EXT_IGP_DEFNS = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-defns";
133  public static final String EXT_IGP_FORMAT = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-format";
134  public static final String EXT_IGP_SOURCE = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-source";
135  public static final String EXT_IGP_CONTAINED_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/contained-resource-information";
136  public static final String EXT_BINARY_FORMAT_OLD = "http://hl7.org/fhir/StructureDefinition/implementationguide-resource-format";
137  public static final String EXT_BINARY_FORMAT_NEW = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-resource-format";
138  public static final String EXT_BINARY_LOGICAL = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-resource-logical";
139  public static final String EXT_IGP_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/resource-information";
140  public static final String EXT_IGP_LOADVERSION = "http://hl7.org/fhir/StructureDefinition/igpublisher-loadversion";
141  public static final String EXT_LIST_PACKAGE = "http://hl7.org/fhir/StructureDefinition/list-packageId";
142  public static final String EXT_JSON_NAME_DEPRECATED = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-json-name";   
143  public static final String EXT_JSON_NAME = "http://hl7.org/fhir/tools/StructureDefinition/json-name";  
144  public static final String EXT_BINDING_STYLE = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-binding-style";
145  public static final String EXT_EXTENSION_STYLE = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-extension-style";
146  public static final String EXT_LOGICAL_TARGET = "http://hl7.org/fhir/tools/StructureDefinition/logical-target";
147  public static final String EXT_LOGICAL_CONTAINER = "http://hl7.org/fhir/tools/StructureDefinition/logical-container";
148  public static final String EXT_PROFILE_MAPPING = "http://hl7.org/fhir/tools/StructureDefinition/profile-mapping";
149  public static final String EXT_CS_ALTERNATE_USE = "http://hl7.org/fhir/StructureDefinition/alternate-code-use";
150  public static final String EXT_CS_ALTERNATE_STATUS = "http://hl7.org/fhir/StructureDefinition/alternate-code-status";
151  public static final String EXT_OBLIGATION_PROFILE_FLAG = "http://hl7.org/fhir/tools/StructureDefinition/obligation-profile";
152  public static final String EXT_OBLIGATION_INHERITS = "http://hl7.org/fhir/tools/StructureDefinition/inherit-obligations";
153  public static final String EXT_DAR = "http://hl7.org/fhir/StructureDefinition/data-absent-reason";
154  public static final String EXT_NF = "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor";
155  public static final String EXT_OT = "http://hl7.org/fhir/StructureDefinition/originalText";
156  public static final String EXT_CQF_EXP = "http://hl7.org/fhir/StructureDefinition/cqf-expression";
157
158  public static final String EXT_PATTERN = "http://hl7.org/fhir/StructureDefinition/elementdefinition-pattern";
159  public static final String EXT_ALLOWEDRESOURCE = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource";
160  private static final String EXT_ALLOWABLE_UNITS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits";
161  private static final String EXT_FHIRTYPE = "http://hl7.org/fhir/StructureDefinition/questionnaire-fhirType";
162  public static final String EXT_ALLOWED_TYPE =  "http://hl7.org/fhir/StructureDefinition/operationdefinition-allowed-type";
163  public static final String EXT_BEST_PRACTICE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice"; 
164  public static final String EXT_BEST_PRACTICE_EXPLANATION = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice-explanation"; 
165  public static final String EXT_BINDING_NAME = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName";
166  public static final String EXT_CONTROL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl";  
167  public static final String EXT_CS_COMMENT = "http://hl7.org/fhir/StructureDefinition/codesystem-concept-comments"; 
168  public static final String EXT_CS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/codesystem-keyWord"; 
169  public static final String EXT_DEFINITION = "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition"; 
170  public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint";  
171  public static final String EXT_EXPAND_GROUP = "http://hl7.org/fhir/StructureDefinition/valueset-expand-group";
172  public static final String EXT_EXPAND_RULES = "http://hl7.org/fhir/StructureDefinition/valueset-expand-rules";
173  public static final String EXT_EXP_TOOCOSTLY = "http://hl7.org/fhir/StructureDefinition/valueset-toocostly";
174  public static final String EXT_FHIR_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type";
175  public static final String EXT_FMM_DERIVED = "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom";
176  public static final String EXT_FMM_LEVEL = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm";
177  public static final String EXT_FMM_SUPPORT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support";
178  public static final String EXT_HIERARCHY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-hierarchy"; 
179  public static final String EXT_ISSUE_SOURCE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source";  
180  public static final String EXT_MAXOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs"; 
181  public static final String EXT_MAX_DECIMALS = "http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces";
182  public static final String EXT_MAX_SIZE = "http://hl7.org/fhir/StructureDefinition/maxSize";
183  public static final String EXT_MAX_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet";
184  public static final String EXT_MINOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs";  
185  public static final String EXT_MIN_LENGTH = "http://hl7.org/fhir/StructureDefinition/minLength";
186  public static final String EXT_MIN_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-minValueSet";
187  public static final String EXT_MUST_SUPPORT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support";
188  public static final String EXT_NORMATIVE_VERSION = "http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version";
189  public static final String EXT_PROFILE_ELEMENT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-profile-element";
190  public static final String EXT_QTYPE = "http://hl7.org/fhir/StructureDefinition/questionnnaire-baseType";
191  public static final String EXT_Q_UNIT = "http://hl7.org/fhir/StructureDefinition/questionnaire-unit";
192  public static final String EXT_REFERENCEFILTER = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter"; 
193  public static final String EXT_REGEX = "http://hl7.org/fhir/StructureDefinition/regex";  
194  public static final String EXT_RENDERED_VALUE = "http://hl7.org/fhir/StructureDefinition/rendered-value";
195  public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/codesystem-replacedby";
196  public static final String EXT_RESOURCE_CATEGORY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-category";
197  public static final String EXT_RESOURCE_INTERFACE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-interface";
198  public static final String EXT_SEC_CAT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-security-category";
199  public static final String EXT_STANDARDS_STATUS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status";
200  public static final String EXT_STANDARDS_STATUS_REASON = "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status-reason";
201  public static final String EXT_TABLE_NAME = "http://hl7.org/fhir/StructureDefinition/structuredefinition-table-name";
202  public static final String EXT_TARGET_ID = "http://hl7.org/fhir/StructureDefinition/targetElement";
203  public static final String EXT_TARGET_PATH = "http://hl7.org/fhir/StructureDefinition/targetPath";
204  public static final String EXT_TRANSLATABLE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-translatable";
205  public static final String EXT_TRANSLATION = "http://hl7.org/fhir/StructureDefinition/translation"; 
206  public static final String EXT_UNCLOSED = "http://hl7.org/fhir/StructureDefinition/valueset-unclosed";
207  public static final String EXT_VALUESET_SYSTEM = "http://hl7.org/fhir/StructureDefinition/valueset-system";
208  public static final String EXT_VS_COMMENT = "http://hl7.org/fhir/StructureDefinition/valueset-concept-comments"; 
209  public static final String EXT_VS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/valueset-keyWord";  
210  public static final String EXT_WORKGROUP = "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg";
211  public static final String EXT_XML_NAMESPACE_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
212  public static final String EXT_XML_NAMESPACE = "http://hl7.org/fhir/tools/StructureDefinition/xml-namespace";
213  public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence";
214  public static final String EXT_Q_IS_SUBJ = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject"; 
215  public static final String EXT_Q_HIDDEN = "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden";
216  public static final String EXT_Q_OTP_DISP = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay"; 
217  public static final String EXT_O_LINK_PERIOD = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod"; 
218  public static final String EXT_Q_CHOICE_ORIENT = "http://hl7.org/fhir/StructureDefinition/questionnaire-choiceOrientation";
219  public static final String EXT_Q_DISPLAY_CAT = "http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory";
220  public static final String EXT_REND_MD = "http://hl7.org/fhir/StructureDefinition/rendering-markdown";
221  public static final String EXT_CAP_STMT_EXPECT = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation";
222  public static final String EXT_ED_HIERARCHY = "http://hl7.org/fhir/StructureDefinition/elementdefinition-hierarchy";
223  public static final String EXT_SD_IMPOSE_PROFILE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-imposeProfile";
224  public static final String EXT_SD_COMPLIES_WITH_PROFILE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-compliesWithProfile";
225  public static final String EXT_DEF_TYPE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaulttype";
226  public static final String EXT_TYPE_SPEC = "http://hl7.org/fhir/tools/StructureDefinition/type-specifier";
227  public static final String EXT_TYPE_CHARACTERISTICS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-type-characteristics";
228  
229  // in the tooling IG
230  public static final String EXT_PRIVATE_BASE = "http://hl7.org/fhir/tools/";
231  public static final String EXT_BINDING_ADDITIONAL = "http://hl7.org/fhir/tools/StructureDefinition/additional-binding";
232  public static final String EXT_JSON_PROP_KEY = "http://hl7.org/fhir/tools/StructureDefinition/json-property-key";
233  public static final String EXT_JSON_EMPTY = "http://hl7.org/fhir/tools/StructureDefinition/json-empty-behavior";
234  public static final String EXT_JSON_NULLABLE = "http://hl7.org/fhir/tools/StructureDefinition/json-nullable";
235  public static final String EXT_IMPLIED_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/implied-string-prefix";
236  public static final String EXT_DATE_FORMAT = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-date-format";
237  public static final String EXT_ID_EXPECTATION = "http://hl7.org/fhir/tools/StructureDefinition/id-expectation";
238  public static final String EXT_JSON_PRIMITIVE_CHOICE = "http://hl7.org/fhir/tools/StructureDefinition/json-primitive-choice";
239  public static final String EXT_SUMMARY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-summary";
240  public static final String EXT_BINDING_DEFINITION = "http://hl7.org/fhir/tools/StructureDefinition/binding-definition";
241  public static final String EXT_QUESTIONNAIRE_ITEM_TYPE_ORIGINAL = "http://hl7.org/fhir/4.0/StructureDefinition/extension-questionnaire.item.type"; 
242
243
244  // unregistered? - don't know what these are used for 
245  public static final String EXT_MAPPING_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-prefix";
246  public static final String EXT_MAPPING_SUFFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-suffix";
247
248  // for the v2 mapping project 
249  public static final String EXT_MAPPING_NAME = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-name";
250  public static final String EXT_MAPPING_TYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-type";
251  public static final String EXT_MAPPING_CARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-cardinality";
252  public static final String EXT_MAPPING_TGTTYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-type";
253  public static final String EXT_MAPPING_TGTCARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-cardinality";
254  
255  public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/format-extensions.html#extension-related-extensions";
256  public static final String WEB_BINDING_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/StructureDefinition-binding-style.html";
257  public static final String EXT_IGDEP_COMMENT = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-dependency-comment";
258  public static final String EXT_XPATH_CONSTRAINT = "http://hl7.org/fhir/4.0/StructureDefinition/extension-ElementDefinition.constraint.xpath";
259  public static final String EXT_OBLIGATION_TOOLS = "http://hl7.org/fhir/tools/StructureDefinition/obligation";
260  public static final String EXT_OBLIGATION_CORE = "http://hl7.org/fhir/StructureDefinition/obligation";
261  public static final String EXT_NO_BINDING = "http://hl7.org/fhir/tools/StructureDefinition/no-binding";
262  public static final String EXT_ID_CHOICE_GROUP = "http://hl7.org/fhir/tools/StructureDefinition/xml-choice-group";
263  public static final String EXT_DATE_RULES = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-date-rules";
264  public static final String EXT_PROFILE_STYLE = "http://hl7.org/fhir/tools/StructureDefinition/type-profile-style";
265  public static final String EXT_RESOURCE_NAME = "http://hl7.org/fhir/StructureDefinition/resource-instance-name";
266  public static final String EXT_RESOURCE_DESC = "http://hl7.org/fhir/StructureDefinition/resource-instance-description";
267  public static final String EXT_ARTIFACT_NAME = "http://hl7.org/fhir/StructureDefinition/artifact-name";
268  public static final String EXT_ARTIFACT_DESC = "http://hl7.org/fhir/StructureDefinition/artifact-description";  
269  public static final String EXT_ED_SUPPRESS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-suppress";
270  public static final String EXT_SEARCH_PARAMETER_BASE = "http://hl7.org/fhir/tools/StructureDefinition/searchparameter-base-type";
271  public static final String EXT_ISSUE_SLICE_INFO = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-slicetext";
272  public static final String EXT_ISSUE_SERVER = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server";
273  public static final String EXT_WEB_SOURCE = "http://hl7.org/fhir/tools/StructureDefinition/web-source";
274  public static final String EXT_APPLICABLE_VERSION = "http://hl7.org/fhir/StructureDefinition/version-specific-use";
275  public static final String EXT_APPLICABLE_VERSION_VALUE = "http://hl7.org/fhir/StructureDefinition/version-specific-value";
276  public static final String EXT_IG_URL = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-resource-uri";
277  public static final String EXT_VS_CS_SUPPL_NEEDED = "http://hl7.org/fhir/StructureDefinition/valueset-supplement";
278  public static final String EXT_TYPE_PARAMETER = "http://hl7.org/fhir/tools/StructureDefinition/type-parameter";
279  public static final String EXT_ALTERNATE_CANONICAL = "http://hl7.org/fhir/StructureDefinition/alternate-canonical";
280  public static final String EXT_SUPPRESSED = "http://hl7.org/fhir/StructureDefinition/elementdefinition-suppress";
281  public static final String EXT_SUPPRESS_RESOURCE_TYPE = "http://hl7.org/fhir/tools/StructureDefinition/json-suppress-resourcetype";
282  public static final String EXT_PROFILE_VIEW_HINT = "http://hl7.org/fhir/tools/StructureDefinition/view-hint";
283  public static final String EXT_SNAPSHOT_BEHAVIOR = "http://hl7.org/fhir/tools/StructureDefinition/snapshot-behavior";
284  public static final String EXT_FHIRVERSION_SPECIFIC_USE = "http://hl7.org/fhir/StructureDefinition/version-specific-use";
285  public static final String EXT_FHIRVERSION_SPECIFIC_USE_START = "startFhirVersion";
286  public static final String EXT_FHIRVERSION_SPECIFIC_USE_END = "endFhirVersion";
287  public static final String EXT_VERSION_BASE = "http://hl7.org/fhir/tools/StructureDefinition/snapshot-base-version";
288  public static final String EXT_LOAD_AS_RESOURCE = "http://hl7.org/fhir/tools/StructureDefinition/ig-load-as-resource";
289  public static final String EXT_USE_AS_RESOURCE_ID = "http://hl7.org/fhir/tools/StructureDefinition/ig-use-as-resource-id";
290  public static final String EXT_PROPERTY_VALUESET = "http://hl7.org/fhir/StructureDefinition/codesystem-property-valueset";
291  public static final String EXT_FEATURE = "http://hl7.org/fhir/uv/application-feature/StructureDefinition/feature";
292  
293  public static final String FEATURE_TX_TEST_VERSION = "http://hl7.org/fhir/uv/tx-tests/FeatureDefinition/test-version";
294  public static final String FEATURE_TX_CS_PARAMS = "http://hl7.org/fhir/uv/tx-ecosystem/FeatureDefinition/CodeSystemAsParameter";
295  public static final String EXT_VALUESET_PARAMETER = "http://hl7.org/fhir/tools/StructureDefinition/valueset-parameter";
296  public static final String EXT_BINDING_PARAMETER = "http://hl7.org/fhir/tools/StructureDefinition/binding-parameter";
297  public static final String EXT_ISSUE_INNER_MESSAGE = "http://hl7.org/fhir/tools/StructureDefinition/operationoutcome-inner-message";
298  
299  // specific extension helpers
300
301  public static Extension makeIssueSource(Source source) {
302    Extension ex = new Extension();
303    // todo: write this up and get it published with the pack (and handle the redirect?)
304    ex.setUrl(ToolingExtensions.EXT_ISSUE_SOURCE);
305    StringType c = new StringType();
306    c.setValue(source.toString());
307    ex.setValue(c);
308    return ex;
309  }
310
311  public static Extension makeIssueMessageId(String msgId) {
312    Extension ex = new Extension();
313    // todo: write this up and get it published with the pack (and handle the redirect?)
314    ex.setUrl(ToolingExtensions.EXT_ISSUE_MSG_ID);
315    CodeType c = new CodeType();
316    c.setValue(msgId);
317    ex.setValue(c);
318    return ex;
319  }
320
321  public static boolean hasExtension(DomainResource de, String url) {
322    return getExtension(de, url) != null;
323  }
324
325  public static boolean hasExtension(Element e, String url) {
326    return getExtension(e, url) != null;
327  }
328
329  //  public static void addStringExtension(DomainResource dr, String url, String content) {
330  //    if (!StringUtils.isBlank(content)) {
331  //      Extension ex = getExtension(dr, url);
332  //      if (ex != null)
333  //        ex.setValue(new StringType(content));
334  //      else
335  //        dr.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
336  //    }
337  //  }
338
339  public static void addMarkdownExtension(DomainResource dr, String url, String content) {
340    if (!StringUtils.isBlank(content)) {
341      Extension ex = getExtension(dr, url);
342      if (ex != null)
343        ex.setValue(new StringType(content));
344      else
345        dr.getExtension().add(Factory.newExtension(url, new MarkdownType(content), true));   
346    }
347  }
348
349  public static void addStringExtension(Element e, String url, String content) {
350    if (!StringUtils.isBlank(content)) {
351      Extension ex = getExtension(e, url);
352      if (ex != null)
353        ex.setValue(new StringType(content));
354      else
355        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
356    }
357  }
358
359  public static void addCodeExtension(Element e, String url, String content) {
360    if (!StringUtils.isBlank(content)) {
361      Extension ex = getExtension(e, url);
362      if (ex != null)
363        ex.setValue(new CodeType(content));
364      else
365        e.getExtension().add(Factory.newExtension(url, new CodeType(content), true));   
366    }
367  }
368
369  public static void addStringExtension(DomainResource e, String url, String content) {
370    if (!StringUtils.isBlank(content)) {
371      Extension ex = getExtension(e, url);
372      if (ex != null)
373        ex.setValue(new StringType(content));
374      else
375        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
376    }
377  }
378
379
380  public static void addBooleanExtension(Element e, String url, boolean content) {
381    Extension ex = getExtension(e, url);
382    if (ex != null)
383      ex.setValue(new BooleanType(content));
384    else
385      e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true));   
386  }
387
388  public static void addBooleanExtension(DomainResource e, String url, boolean content) {
389    Extension ex = getExtension(e, url);
390    if (ex != null)
391      ex.setValue(new BooleanType(content));
392    else
393      e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true));   
394  }
395
396  public static void addIntegerExtension(DomainResource dr, String url, int value) {
397    Extension ex = getExtension(dr, url);
398    if (ex != null)
399      ex.setValue(new IntegerType(value));
400    else
401      dr.getExtension().add(Factory.newExtension(url, new IntegerType(value), true));   
402  }
403
404  public static void addCodeExtension(DomainResource dr, String url, String value) {
405    Extension ex = getExtension(dr, url);
406    if (ex != null)
407      ex.setValue(new CodeType(value));
408    else
409      dr.getExtension().add(Factory.newExtension(url, new CodeType(value), true));   
410  }
411
412  public static void addVSComment(ConceptSetComponent nc, String comment) {
413    if (!StringUtils.isBlank(comment))
414      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
415  }
416  public static void addVSComment(ConceptReferenceComponent nc, String comment) {
417    if (!StringUtils.isBlank(comment))
418      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
419  }
420
421  public static void addCSComment(ConceptDefinitionComponent nc, String comment) {
422    if (!StringUtils.isBlank(comment))
423      nc.getExtension().add(Factory.newExtension(EXT_CS_COMMENT, Factory.newString_(comment), true));   
424  }
425
426  //  public static void markDeprecated(Element nc) {
427  //    setDeprecated(nc);   
428  //  }
429  //
430
431  public static void addDefinition(Element nc, String definition) {
432    if (!StringUtils.isBlank(definition))
433      nc.getExtension().add(Factory.newExtension(EXT_DEFINITION, Factory.newString_(definition), true));   
434  }
435
436  public static void addDisplayHint(Element def, String hint) {
437    if (!StringUtils.isBlank(hint))
438      def.getExtension().add(Factory.newExtension(EXT_DISPLAY_HINT, Factory.newString_(hint), true));   
439  }
440
441  public static String getDisplayHint(Element def) {
442    return readStringExtension(def, EXT_DISPLAY_HINT);    
443  }
444
445  public static String readStringExtension(Element c, String... uris) {
446    for (String uri : uris) {
447      if (hasExtension(c, uri)) {
448        return readStringExtension(c, uri);
449      }
450    }
451    return null;
452  }
453
454  public static String readStringFromExtension(Extension ext) {
455    if (ext.hasValue() && ext.getValue().isPrimitive()) {
456      return ext.getValue().primitiveValue();
457    }
458    return null;
459  }
460  
461  public static String readStringExtension(Element c, String uri) {
462    Extension ex = ExtensionHelper.getExtension(c, uri);
463    if (ex == null)
464      return null;
465    if (ex.getValue() instanceof UriType)
466      return ((UriType) ex.getValue()).getValue();
467    if (ex.getValue() instanceof CanonicalType)
468      return ((CanonicalType) ex.getValue()).getValue();
469    if (ex.getValue() instanceof CodeType)
470      return ((CodeType) ex.getValue()).getValue();
471    if (ex.getValue() instanceof IntegerType)
472      return ((IntegerType) ex.getValue()).asStringValue();
473    if (ex.getValue() instanceof Integer64Type)
474      return ((Integer64Type) ex.getValue()).asStringValue();
475    if (ex.getValue() instanceof DecimalType)
476      return ((DecimalType) ex.getValue()).asStringValue();
477    if ((ex.getValue() instanceof MarkdownType))
478      return ((MarkdownType) ex.getValue()).getValue();
479    if ((ex.getValue() instanceof PrimitiveType))
480      return ((PrimitiveType) ex.getValue()).primitiveValue();
481    if (!(ex.getValue() instanceof StringType))
482      return null;
483    return ((StringType) ex.getValue()).getValue();
484  }
485
486  public static String readStringExtension(DomainResource c, String... uris) {
487    for (String uri : uris) {
488      if (hasExtension(c, uri)) {
489        return readStringExtension(c, uri);
490      }
491    }
492    return null;
493  }
494  
495  public static String readStringExtension(DomainResource c, String uri) {
496    Extension ex = getExtension(c, uri);
497    if (ex == null)
498      return null;
499    if ((ex.getValue() instanceof StringType))
500      return ((StringType) ex.getValue()).getValue();
501    if ((ex.getValue() instanceof UriType))
502      return ((UriType) ex.getValue()).getValue();
503    if (ex.getValue() instanceof CodeType)
504      return ((CodeType) ex.getValue()).getValue();
505    if (ex.getValue() instanceof IntegerType)
506      return ((IntegerType) ex.getValue()).asStringValue();
507    if (ex.getValue() instanceof Integer64Type)
508      return ((Integer64Type) ex.getValue()).asStringValue();
509    if (ex.getValue() instanceof DecimalType)
510      return ((DecimalType) ex.getValue()).asStringValue();
511    if ((ex.getValue() instanceof MarkdownType))
512      return ((MarkdownType) ex.getValue()).getValue();
513    return null;
514  }
515
516  public static String readStringSubExtension(DomainResource c, String uri, String name) {
517    Extension ex = getExtension(c, uri);
518    if (ex == null)
519      return null;
520    ex = getExtension(ex, name);
521    if (ex == null)
522      return null;
523    if ((ex.getValue() instanceof StringType))
524      return ((StringType) ex.getValue()).getValue();
525    if ((ex.getValue() instanceof UriType))
526      return ((UriType) ex.getValue()).getValue();
527    if (ex.getValue() instanceof CodeType)
528      return ((CodeType) ex.getValue()).getValue();
529    if (ex.getValue() instanceof IntegerType)
530      return ((IntegerType) ex.getValue()).asStringValue();
531    if (ex.getValue() instanceof Integer64Type)
532      return ((Integer64Type) ex.getValue()).asStringValue();
533    if (ex.getValue() instanceof DecimalType)
534      return ((DecimalType) ex.getValue()).asStringValue();
535    if ((ex.getValue() instanceof MarkdownType))
536      return ((MarkdownType) ex.getValue()).getValue();
537    return null;
538  }
539
540  @SuppressWarnings("unchecked")
541  public static PrimitiveType<DataType> readPrimitiveExtension(DomainResource c, String uri) {
542    Extension ex = getExtension(c, uri);
543    if (ex == null)
544      return null;
545    return (PrimitiveType<DataType>) ex.getValue();
546  }
547
548  public static boolean findStringExtension(Element c, String uri) {
549    Extension ex = ExtensionHelper.getExtension(c, uri);
550    if (ex == null)
551      return false;
552    if (!(ex.getValue() instanceof StringType))
553      return false;
554    return !StringUtils.isBlank(((StringType) ex.getValue()).getValue());
555  }
556
557  public static Boolean readBooleanExtension(Element c, String uri) {
558    Extension ex = ExtensionHelper.getExtension(c, uri);
559    if (ex == null)
560      return null;
561    if (!(ex.getValue() instanceof BooleanType))
562      return null;
563    return ((BooleanType) ex.getValue()).getValue();
564  }
565
566  public static boolean findBooleanExtension(Element c, String uri) {
567    Extension ex = ExtensionHelper.getExtension(c, uri);
568    if (ex == null)
569      return false;
570    if (!(ex.getValue() instanceof BooleanType))
571      return false;
572    return true;
573  }
574
575  public static Boolean readBooleanExtension(DomainResource c, String uri) {
576    Extension ex = ExtensionHelper.getExtension(c, uri);
577    if (ex == null)
578      return null;
579    if (!(ex.getValue() instanceof BooleanType))
580      return null;
581    return ((BooleanType) ex.getValue()).getValue();
582  }
583
584  public static boolean readBoolExtension(DomainResource c, String uri) {
585    Extension ex = ExtensionHelper.getExtension(c, uri);
586    if (ex == null)
587      return false;
588    if (!(ex.getValue() instanceof BooleanType))
589      return false;
590    return ((BooleanType) ex.getValue()).getValue();
591  }
592
593  public static boolean readBoolExtension(DomainResource c, String... uris) {
594    Extension ex = null;
595    for (String uri : uris) {
596      ex = ExtensionHelper.getExtension(c, uri);
597      if (ex != null) {
598        break;
599      }
600    }
601    if (ex == null)
602      return false;
603    if (!(ex.getValue() instanceof BooleanType))
604      return false;
605    return ((BooleanType) ex.getValue()).getValue();
606  }
607
608  public static boolean readBoolExtension(Element e, String uri) {
609    Extension ex = ExtensionHelper.getExtension(e, uri);
610    if (ex == null)
611      return false;
612    if (!(ex.getValue() instanceof BooleanType))
613      return false;
614    if (!(ex.getValue().hasPrimitiveValue()))
615      return false;
616    return ((BooleanType) ex.getValue()).getValue();
617  }
618
619  public static boolean findBooleanExtension(DomainResource c, String uri) {
620    Extension ex = ExtensionHelper.getExtension(c, uri);
621    if (ex == null)
622      return false;
623    if (!(ex.getValue() instanceof BooleanType))
624      return false;
625    return true;
626  }
627
628  public static String getCSComment(ConceptDefinitionComponent c) {
629    return readStringExtension(c, EXT_CS_COMMENT);    
630  }
631  //
632  //  public static Boolean getDeprecated(Element c) {
633  //    return readBooleanExtension(c, EXT_DEPRECATED);    
634  //  }
635
636  public static boolean hasCSComment(ConceptDefinitionComponent c) {
637    return findStringExtension(c, EXT_CS_COMMENT);    
638  }
639
640  //  public static boolean hasDeprecated(Element c) {
641  //    return findBooleanExtension(c, EXT_DEPRECATED);    
642  //  }
643
644  public static void addFlyOver(QuestionnaireItemComponent item, String text, String linkId){
645    if (!StringUtils.isBlank(text)) {
646      QuestionnaireItemComponent display = item.addItem();
647      display.setType(QuestionnaireItemType.DISPLAY);
648      display.setText(text);
649      display.setLinkId(linkId);
650      display.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept("flyover", "http://hl7.org/fhir/questionnaire-item-control", "Fly-over"), true));
651    }
652  }
653
654  public static void addMin(QuestionnaireItemComponent item, int min) {
655    item.getExtension().add(Factory.newExtension(EXT_MINOCCURS, Factory.newInteger(min), true));
656  }
657
658  public static void addMax(QuestionnaireItemComponent item, int max) {
659    item.getExtension().add(Factory.newExtension(EXT_MAXOCCURS, Factory.newInteger(max), true));
660  }
661
662  public static void addFhirType(QuestionnaireItemComponent group, String value) {
663    group.getExtension().add(Factory.newExtension(EXT_FHIRTYPE, Factory.newString_(value), true));       
664  }
665
666  public static void addControl(QuestionnaireItemComponent group, String value) {
667    group.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept(value, "http://hl7.org/fhir/questionnaire-item-control", value), true));
668  }
669
670  public static void addAllowedResource(QuestionnaireItemComponent group, String value) {
671    group.getExtension().add(Factory.newExtension(EXT_ALLOWEDRESOURCE, Factory.newCode(value), true));       
672  }
673
674  public static void addReferenceFilter(QuestionnaireItemComponent group, String value) {
675    group.getExtension().add(Factory.newExtension(EXT_REFERENCEFILTER, Factory.newString_(value), true));       
676  }
677
678  //  public static void addIdentifier(Element element, Identifier value) {
679  //    element.getExtension().add(Factory.newExtension(EXT_IDENTIFIER, value, true));       
680  //  }
681
682  /**
683   * @param name the identity of the extension of interest
684   * @return The extension, if on this element, else null
685   */
686  public static Extension getExtension(DomainResource resource, String name) {
687    if (resource == null || name == null)
688      return null;
689    if (!resource.hasExtension())
690      return null;
691    for (Extension e : resource.getExtension()) {
692      if (name.equals(e.getUrl()))
693        return e;
694    }
695    return null;
696  }
697
698  public static Extension getExtension(Element el, String name) {
699    if (name == null)
700      return null;
701    if (!el.hasExtension())
702      return null;
703    for (Extension e : el.getExtension()) {
704      if (name.equals(e.getUrl()))
705        return e;
706    }
707    return null;
708  }
709
710  public static void setStringExtension(DomainResource resource, String uri, String value) {
711    if (Utilities.noString(value))
712      return;
713    Extension ext = getExtension(resource, uri);
714    if (ext != null)
715      ext.setValue(new StringType(value));
716    else
717      resource.getExtension().add(new Extension(uri).setValue(new StringType(value)));
718  }
719
720  public static void setStringExtension(Element resource, String uri, String value) {
721    if (Utilities.noString(value))
722      return;
723    Extension ext = getExtension(resource, uri);
724    if (ext != null)
725      ext.setValue(new StringType(value));
726    else
727      resource.getExtension().add(new Extension(uri).setValue(new StringType(value)));
728  }
729
730  public static void setUriExtension(DomainResource resource, String uri, String value) {
731    if (Utilities.noString(value))
732      return;
733    Extension ext = getExtension(resource, uri);
734    if (ext != null)
735      ext.setValue(new UriType(value));
736    else
737      resource.getExtension().add(new Extension(uri).setValue(new UriType(value)));
738  }
739
740  public static void setUriExtension(Element resource, String uri, String value) {
741    if (Utilities.noString(value))
742      return;
743    Extension ext = getExtension(resource, uri);
744    if (ext != null)
745      ext.setValue(new UriType(value));
746    else
747      resource.getExtension().add(new Extension(uri).setValue(new UriType(value)));
748  }
749
750  public static void setUrlExtension(DomainResource resource, String uri, String value) {
751    if (Utilities.noString(value))
752      return;
753    Extension ext = getExtension(resource, uri);
754    if (ext != null)
755      ext.setValue(new UrlType(value));
756    else
757      resource.getExtension().add(new Extension(uri).setValue(new UrlType(value)));
758  }
759
760  public static void setUrlExtension(Element resource, String uri, String value) {
761    if (Utilities.noString(value))
762      return;
763    Extension ext = getExtension(resource, uri);
764    if (ext != null)
765      ext.setValue(new UrlType(value));
766    else
767      resource.getExtension().add(new Extension(uri).setValue(new UrlType(value)));
768  }
769
770  public static void setCodeExtension(DomainResource resource, String uri, String value) {
771    if (Utilities.noString(value))
772      return;
773
774    Extension ext = getExtension(resource, uri);
775    if (ext != null)
776      ext.setValue(new CodeType(value));
777    else
778      resource.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
779  }
780
781  public static void setCodeExtensionMod(DomainResource resource, String uri, String value) {
782    if (Utilities.noString(value))
783      return;
784
785    Extension ext = getExtension(resource, uri);
786    if (ext != null)
787      ext.setValue(new CodeType(value));
788    else
789      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
790  }
791
792  public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) {
793    if (Utilities.noString(value))
794      return;
795
796    Extension ext = getExtension(resource, uri);
797    if (ext != null)
798      ext.setValue(new CodeType(value));
799    else
800      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
801  }
802
803  public static void setCodeExtension(Element element, String uri, String value) {
804    if (Utilities.noString(value))
805      return;
806
807    Extension ext = getExtension(element, uri);
808    if (ext != null)
809      ext.setValue(new CodeType(value));
810    else
811      element.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
812  }
813
814  public static void setMarkdownExtension(DomainResource resource, String uri, String value) {
815    if (Utilities.noString(value))
816      return;
817
818    Extension ext = getExtension(resource, uri);
819    if (ext != null)
820      ext.setValue(new MarkdownType(value));
821    else
822      resource.getExtension().add(new Extension(uri).setValue(new MarkdownType(value)));
823  }
824
825  public static void setIntegerExtension(DomainResource resource, String uri, int value) {
826    Extension ext = getExtension(resource, uri);
827    if (ext != null)
828      ext.setValue(new IntegerType(value));
829    else
830      resource.getExtension().add(new Extension(uri).setValue(new IntegerType(value)));
831  }
832
833  //  public static String getOID(CodeSystem define) {
834  //    return readStringExtension(define, EXT_OID);    
835  //  }
836  //
837  //  public static String getOID(ValueSet vs) {
838  //    return readStringExtension(vs, EXT_OID);    
839  //  }
840  //
841  //  public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException {
842  //    if (!oid.startsWith("urn:oid:"))
843  //      throw new FHIRFormatError("Error in OID format");
844  //    if (oid.startsWith("urn:oid:urn:oid:"))
845  //      throw new FHIRFormatError("Error in OID format");
846  //    if (!hasExtension(define, EXT_OID))
847  //    define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
848  //    else if (!oid.equals(readStringExtension(define, EXT_OID)))
849  //      throw new Error("Attempt to assign multiple OIDs to a code system");
850  //  }
851  //  public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException {
852  //    if (!oid.startsWith("urn:oid:"))
853  //      throw new FHIRFormatError("Error in OID format");
854  //    if (oid.startsWith("urn:oid:urn:oid:"))
855  //      throw new FHIRFormatError("Error in OID format");
856  //    if (!hasExtension(vs, EXT_OID))
857  //    vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
858  //    else if (!oid.equals(readStringExtension(vs, EXT_OID)))
859  //      throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid);
860  //  }
861
862  public static boolean hasLanguageTranslations(Element element) {
863    for (Extension e : element.getExtension()) {
864      if (e.getUrl().equals(EXT_TRANSLATION)) {
865        return true;
866      }
867    }
868    return false;
869  }
870
871  public static boolean hasLanguageTranslation(Element element, String lang) {
872    for (Extension e : element.getExtension()) {
873      if (e.getUrl().equals(EXT_TRANSLATION)) {
874        Extension e1 = ExtensionHelper.getExtension(e, "lang");
875
876        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang))
877          return true;
878      }
879    }
880    return false;
881  }
882
883  public static String getLanguageTranslation(Element element, String lang) {
884    for (Extension e : element.getExtension()) {
885      if (e.getUrl().equals(EXT_TRANSLATION)) {
886        Extension e1 = ExtensionHelper.getExtension(e, "lang");
887
888        if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
889          e1 = ExtensionHelper.getExtension(e, "content");
890          return ((StringType) e1.getValue()).getValue();
891        }
892      }
893    }
894    return null;
895  }
896
897  public static StringType getLanguageTranslationElement(Element element, String lang) {
898    for (Extension e : element.getExtension()) {
899      if (e.getUrl().equals(EXT_TRANSLATION)) {
900        Extension e1 = ExtensionHelper.getExtension(e, "lang");
901
902        if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
903          e1 = ExtensionHelper.getExtension(e, "content");
904          return ((StringType) e1.getValue());
905        }
906      }
907    }
908    return null;
909  }
910
911  public static void addLanguageTranslation(Element element, String lang, String value) {
912    if (Utilities.noString(lang) || Utilities.noString(value))
913      return;
914
915    Extension extension = new Extension().setUrl(EXT_TRANSLATION);
916    extension.addExtension().setUrl("lang").setValue(new CodeType(lang));
917    extension.addExtension().setUrl("content").setValue(new StringType(value));
918    element.getExtension().add(extension);
919  }
920
921  public static void setLanguageTranslation(Element element, String lang, String value) {
922    if (Utilities.noString(lang) || Utilities.noString(value))
923      return;
924
925    for (Extension extension : element.getExtension()) {
926      if (EXT_TRANSLATION.equals(extension.getUrl())) {
927        String l = extension.getExtensionString("lang");
928        if (lang.equals(l)) {
929          setStringExtension(extension, "content", value);
930          return;
931        }
932      }
933    }
934    
935    Extension extension = new Extension().setUrl(EXT_TRANSLATION);
936    extension.addExtension().setUrl("lang").setValue(new CodeType(lang));
937    extension.addExtension().setUrl("content").setValue(new StringType(value));
938    element.getExtension().add(extension);
939  }
940
941  public static boolean hasAllowedUnits(ElementDefinition eld) {
942    for (Extension e : eld.getExtension()) 
943      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 
944        return true;
945    return false;
946  }
947
948  public static DataType getAllowedUnits(ElementDefinition eld) {
949    for (Extension e : eld.getExtension()) 
950      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 
951        return e.getValue();
952    return null;
953  }
954
955  public static void setAllowableUnits(ElementDefinition eld, CodeableConcept cc) {
956    for (Extension e : eld.getExtension()) 
957      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) {
958        e.setValue(cc);
959        return;
960      }
961    eld.getExtension().add(new Extension().setUrl(EXT_ALLOWABLE_UNITS).setValue(cc));
962  }
963
964  public static List<Extension> getExtensions(Element element, String url) {
965    List<Extension> results = new ArrayList<Extension>();
966    for (Extension ex : element.getExtension())
967      if (ex.getUrl().equals(url))
968        results.add(ex);
969    return results;
970  }
971
972  public static List<Extension> getExtensions(DomainResource resource, String url) {
973    List<Extension> results = new ArrayList<Extension>();
974    for (Extension ex : resource.getExtension())
975      if (ex.getUrl().equals(url))
976        results.add(ex);
977    return results;
978  }
979
980  //  public static void addDEReference(DataElement de, String value) {
981  //    for (Extension e : de.getExtension()) 
982  //      if (e.getUrl().equals(EXT_CIMI_REFERENCE)) {
983  //        e.setValue(new UriType(value));
984  //        return;
985  //      }
986  //    de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value)));
987  //  }
988
989  //  public static void setDeprecated(Element nc) {
990  //    for (Extension e : nc.getExtension()) 
991  //      if (e.getUrl().equals(EXT_DEPRECATED)) {
992  //        e.setValue(new BooleanType(true));
993  //        return;
994  //      }
995  //    nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true)));    
996  //  }
997
998  public static void setExtension(Element focus, String url, Coding c) {
999    for (Extension e : focus.getExtension()) 
1000      if (e.getUrl().equals(url)) {
1001        e.setValue(c);
1002        return;
1003      }
1004    focus.getExtension().add(new Extension().setUrl(url).setValue(c));    
1005  }
1006
1007  public static void removeExtension(DomainResource focus, String url) {
1008    Iterator<Extension> i = focus.getExtension().iterator();
1009    while (i.hasNext()) {
1010      Extension e = i.next(); // must be called before you can call i.remove()
1011      if (url.equals(e.getUrl())) {
1012        i.remove();
1013      }
1014    }
1015  }
1016
1017  public static void removeExtension(Element focus, String url) {
1018    Iterator<Extension> i = focus.getExtension().iterator();
1019    while (i.hasNext()) {
1020      Extension e = i.next(); // must be called before you can call i.remove()
1021      if (e.getUrl().equals(url)) {
1022        i.remove();
1023      }
1024    }
1025  }
1026
1027  public static int readIntegerExtension(DomainResource dr, String uri, int defaultValue) {
1028    Extension ex = ExtensionHelper.getExtension(dr, uri);
1029    if (ex == null)
1030      return defaultValue;
1031    if (ex.getValue() instanceof IntegerType)
1032      return ((IntegerType) ex.getValue()).getValue();
1033    throw new Error("Unable to read extension "+uri+" as an integer");
1034  }
1035
1036  public static int readIntegerExtension(Element e, String uri, int defaultValue) {
1037    Extension ex = ExtensionHelper.getExtension(e, uri);
1038    if (ex == null)
1039      return defaultValue;
1040    if (ex.getValue() instanceof IntegerType)
1041      return ((IntegerType) ex.getValue()).getValue();
1042    throw new Error("Unable to read extension "+uri+" as an integer");
1043  }
1044
1045  public static Map<String, String> getLanguageTranslations(Element e) {
1046    Map<String, String> res = new HashMap<String, String>();
1047    for (Extension ext : e.getExtension()) {
1048      if (ext.getUrl().equals(EXT_TRANSLATION)) {
1049        String lang = readStringExtension(ext, "lang");
1050        String value = readStringExtension(ext, "content");
1051        res.put(lang,  value);
1052      }
1053    }
1054    return res;
1055  }
1056
1057  public static StandardsStatus getStandardsStatus(DomainResource dr) throws FHIRException {
1058    return StandardsStatus.fromCode(ToolingExtensions.readStringExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS));
1059  }
1060
1061  public static StandardsStatus getStandardsStatus(Element e) throws FHIRException {
1062    return StandardsStatus.fromCode(ToolingExtensions.readStringExtension(e, ToolingExtensions.EXT_STANDARDS_STATUS));
1063  }
1064
1065  public static void setStandardsStatus(DomainResource dr, StandardsStatus status, String normativeVersion) {
1066    if (status == null)
1067      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS);
1068    else
1069      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS, status.toCode());
1070    if (normativeVersion == null)
1071      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION);
1072    else
1073      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION, normativeVersion);
1074  }
1075
1076  public static void setStandardsStatus(Element dr, StandardsStatus status, String normativeVersion) {
1077    if (status == null)
1078      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS);
1079    else
1080      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS, status.toCode());
1081    if (normativeVersion == null)
1082      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION);
1083    else
1084      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION, normativeVersion);
1085  }
1086
1087  public static ValidationMessage readValidationMessage(OperationOutcomeIssueComponent issue, Source source) {
1088    ValidationMessage vm = new ValidationMessage();
1089    vm.setSource(source);
1090    vm.setLevel(mapSeverity(issue.getSeverity()));
1091    vm.setType(mapType(issue.getCode()));
1092    if (issue.hasExtension(ToolingExtensions.EXT_ISSUE_LINE))
1093      vm.setLine(ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, 0));
1094    if (issue.hasExtension(ToolingExtensions.EXT_ISSUE_COL))
1095      vm.setCol(ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, 0));
1096    if (issue.hasExpression())
1097      vm.setLocation(issue.getExpression().get(0).asStringValue());
1098    vm.setMessage(issue.getDetails().getText());
1099    if (issue.hasExtension("http://hl7.org/fhir/StructureDefinition/rendering-xhtml"))
1100      vm.setHtml(ToolingExtensions.readStringExtension(issue, "http://hl7.org/fhir/StructureDefinition/rendering-xhtml"));
1101    return vm;
1102  }
1103
1104  private static IssueType mapType(org.hl7.fhir.r5.model.OperationOutcome.IssueType code) {
1105    if (code == null) {
1106      return null;
1107    }
1108    switch (code) {
1109    case BUSINESSRULE: return IssueType.BUSINESSRULE;
1110    case CODEINVALID: return IssueType.CODEINVALID;
1111    case CONFLICT: return IssueType.CONFLICT;
1112    case DELETED: return IssueType.DELETED;
1113    case DUPLICATE: return IssueType.DUPLICATE;
1114    case EXCEPTION: return IssueType.EXCEPTION;
1115    case EXPIRED: return IssueType.EXPIRED;
1116    case EXTENSION: return IssueType.EXTENSION;
1117    case FORBIDDEN: return IssueType.FORBIDDEN;
1118    case INCOMPLETE: return IssueType.INCOMPLETE;
1119    case INFORMATIONAL: return IssueType.INFORMATIONAL;
1120    case INVALID: return IssueType.INVALID;
1121    case INVARIANT: return IssueType.INVARIANT;
1122    case LOCKERROR: return IssueType.LOCKERROR;
1123    case LOGIN: return IssueType.LOGIN;
1124    case MULTIPLEMATCHES: return IssueType.MULTIPLEMATCHES;
1125    case NOSTORE: return IssueType.NOSTORE;
1126    case NOTFOUND: return IssueType.NOTFOUND;
1127    case NOTSUPPORTED: return IssueType.NOTSUPPORTED;
1128    case NULL: return IssueType.NULL;
1129    case PROCESSING: return IssueType.PROCESSING;
1130    case REQUIRED: return IssueType.REQUIRED;
1131    case SECURITY: return IssueType.SECURITY;
1132    case STRUCTURE: return IssueType.STRUCTURE;
1133    case SUPPRESSED: return IssueType.SUPPRESSED;
1134    case THROTTLED: return IssueType.THROTTLED;
1135    case TIMEOUT: return IssueType.TIMEOUT;
1136    case TOOCOSTLY: return IssueType.TOOCOSTLY;
1137    case TOOLONG: return IssueType.TOOLONG;
1138    case TRANSIENT: return IssueType.TRANSIENT;
1139    case UNKNOWN: return IssueType.UNKNOWN;
1140    case VALUE: return IssueType.VALUE;
1141    default: return null;
1142    }
1143  }
1144
1145  private static IssueSeverity mapSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity severity) {
1146    if (severity == null) {
1147      return null;
1148    }
1149    switch (severity) {
1150    case ERROR: return IssueSeverity.ERROR;
1151    case FATAL: return IssueSeverity.FATAL;
1152    case INFORMATION: return IssueSeverity.INFORMATION;
1153    case WARNING: return IssueSeverity.WARNING;
1154    default: return null;
1155    }
1156  }
1157
1158  public static String getPresentation(PrimitiveType<?> type) {
1159    if (type.hasExtension(EXT_RENDERED_VALUE))
1160      return readStringExtension(type, EXT_RENDERED_VALUE);
1161    return type.primitiveValue();
1162  }
1163
1164  public static String getPresentation(Element holder, PrimitiveType<?> type) {
1165    if (holder.hasExtension(EXT_RENDERED_VALUE))
1166      return readStringExtension(holder, EXT_RENDERED_VALUE);
1167    if (type.hasExtension(EXT_RENDERED_VALUE))
1168      return readStringExtension(type, EXT_RENDERED_VALUE);
1169    return type.primitiveValue();
1170  }
1171
1172  //  public static boolean hasOID(ValueSet vs) {
1173  //    return hasExtension(vs, EXT_OID);
1174  //  }
1175  //  
1176  //  public static boolean hasOID(CodeSystem cs) {
1177  //    return hasExtension(cs, EXT_OID);
1178  //  }
1179  //  
1180  public static void addUrlExtension(Element e, String url, String content) {
1181    if (!StringUtils.isBlank(content)) {
1182      Extension ex = getExtension(e, url);
1183      if (ex != null)
1184        ex.setValue(new UrlType(content));
1185      else
1186        e.getExtension().add(Factory.newExtension(url, new UrlType(content), true));   
1187    }
1188  }
1189
1190  public static void addUrlExtension(DomainResource dr, String url, String value) {
1191    Extension ex = getExtension(dr, url);
1192    if (ex != null)
1193      ex.setValue(new UrlType(value));
1194    else
1195      dr.getExtension().add(Factory.newExtension(url, new UrlType(value), true));   
1196  }
1197
1198  public static void addUriExtension(Element e, String url, String content) {
1199    if (!StringUtils.isBlank(content)) {
1200      Extension ex = getExtension(e, url);
1201      if (ex != null)
1202        ex.setValue(new UriType(content));
1203      else
1204        e.getExtension().add(Factory.newExtension(url, new UriType(content), true));   
1205    }
1206  }
1207
1208  public static void addUriExtension(DomainResource dr, String url, String value) {
1209    Extension ex = getExtension(dr, url);
1210    if (ex != null)
1211      ex.setValue(new UriType(value));
1212    else
1213      dr.getExtension().add(Factory.newExtension(url, new UriType(value), true));   
1214  }
1215
1216  public static boolean usesExtension(String url, Base base) {
1217    if ("Extension".equals(base.fhirType())) {
1218      Property p = base.getNamedProperty("url");
1219      for (Base b : p.getValues()) {
1220        if (url.equals(b.primitiveValue())) {
1221          return true;
1222        }
1223      }
1224    }
1225
1226    for (Property p : base.children() ) {
1227      for (Base v : p.getValues()) {
1228        if (usesExtension(url, v)) {
1229          return true;
1230        }
1231      }
1232    }
1233    return false;
1234  }
1235
1236  private static Set<String> cachedConsts;
1237  
1238  public static Set<String> allConsts() {
1239    if (cachedConsts == null) {
1240      Set<String> list = new HashSet<>();
1241      for (Field field : ToolingExtensions.class.getDeclaredFields()) {
1242        int modifiers = field.getModifiers();
1243        if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
1244          try {
1245            list.add(field.get(field.getType()).toString());
1246          } catch (Exception e) {
1247          }
1248        }
1249      }
1250      cachedConsts = list;
1251    }
1252    return cachedConsts;
1253  }
1254
1255  public static boolean hasAnyOfExtensions(Element d, String... urls) {
1256    for (String url : urls) {
1257      if (d.hasExtension(url)) {
1258        return true;
1259      }
1260    }
1261    return false;
1262  }
1263
1264  public static boolean hasAnyOfExtensions(DomainResource dr, String... urls) {
1265    for (String url : urls) {
1266      if (dr.hasExtension(url)) {
1267        return true;
1268      }
1269    }
1270    return false;
1271  }
1272
1273  public static int countExtensions(ElementDefinition d, String... urls) {
1274    int res = 0;
1275    for (String url : urls) {
1276      if (d.hasExtension(url)) {
1277        res++;
1278      }
1279    }
1280    return res;
1281  }
1282
1283  public static boolean hasExtensionValue(StructureDefinition src, String url, String value) {
1284    for (Extension ext : src.getExtension()) {
1285      if (url.equals(ext.getUrl()) && ext.hasValue() && value.equals(ext.getValue().primitiveValue())) {
1286        return true;
1287      }
1288    }
1289    return false;
1290  }
1291
1292}