001/*
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.util;
021
022import ca.uhn.fhir.context.ConfigurationException;
023import ca.uhn.fhir.i18n.Msg;
024import ca.uhn.fhir.model.primitive.XhtmlDt;
025import ca.uhn.fhir.parser.DataFormatException;
026import ca.uhn.fhir.util.jar.DependencyLogFactory;
027import ca.uhn.fhir.util.jar.IDependencyLog;
028import com.ctc.wstx.api.WstxInputProperties;
029import com.ctc.wstx.stax.WstxOutputFactory;
030import org.apache.commons.text.StringEscapeUtils;
031import org.codehaus.stax2.XMLOutputFactory2;
032import org.codehaus.stax2.io.EscapingWriterFactory;
033import org.w3c.dom.Document;
034import org.w3c.dom.Element;
035import org.w3c.dom.Node;
036import org.xml.sax.InputSource;
037import org.xml.sax.SAXException;
038
039import java.io.IOException;
040import java.io.OutputStream;
041import java.io.OutputStreamWriter;
042import java.io.Reader;
043import java.io.StringReader;
044import java.io.StringWriter;
045import java.io.UnsupportedEncodingException;
046import java.io.Writer;
047import java.util.ArrayList;
048import java.util.Collections;
049import java.util.HashMap;
050import java.util.List;
051import java.util.Map;
052import javax.xml.parsers.DocumentBuilder;
053import javax.xml.parsers.DocumentBuilderFactory;
054import javax.xml.parsers.ParserConfigurationException;
055import javax.xml.stream.FactoryConfigurationError;
056import javax.xml.stream.XMLEventReader;
057import javax.xml.stream.XMLEventWriter;
058import javax.xml.stream.XMLInputFactory;
059import javax.xml.stream.XMLOutputFactory;
060import javax.xml.stream.XMLResolver;
061import javax.xml.stream.XMLStreamException;
062import javax.xml.stream.XMLStreamWriter;
063import javax.xml.stream.events.XMLEvent;
064import javax.xml.transform.OutputKeys;
065import javax.xml.transform.Transformer;
066import javax.xml.transform.TransformerException;
067import javax.xml.transform.TransformerFactory;
068import javax.xml.transform.dom.DOMSource;
069import javax.xml.transform.stream.StreamResult;
070
071import static org.apache.commons.lang3.StringUtils.isBlank;
072
073/**
074 * Utility methods for working with the StAX API.
075 * <p>
076 * This class contains code adapted from the Apache Axiom project.
077 */
078public class XmlUtil {
079        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
080        private static final Map<String, Integer> VALID_ENTITY_NAMES;
081        private static final ExtendedEntityReplacingXmlResolver XML_RESOLVER = new ExtendedEntityReplacingXmlResolver();
082        private static XMLOutputFactory ourFragmentOutputFactory;
083        private static volatile boolean ourHaveLoggedStaxImplementation;
084        private static volatile XMLInputFactory ourInputFactory;
085        private static Throwable ourNextException;
086        private static volatile XMLOutputFactory ourOutputFactory;
087
088        static {
089                HashMap<String, Integer> validEntityNames = new HashMap<>(1448);
090                validEntityNames.put("AElig", 0x000C6);
091                validEntityNames.put("Aacute", 0x000C1);
092                validEntityNames.put("Abreve", 0x00102);
093                validEntityNames.put("Acirc", 0x000C2);
094                validEntityNames.put("Acy", 0x00410);
095                validEntityNames.put("Afr", 0x1D504);
096                validEntityNames.put("Agrave", 0x000C0);
097                validEntityNames.put("Alpha", 0x00391);
098                validEntityNames.put("Amacr", 0x00100);
099                validEntityNames.put("And", 0x02A53);
100                validEntityNames.put("Aogon", 0x00104);
101                validEntityNames.put("Aopf", 0x1D538);
102                validEntityNames.put("ApplyFunction", 0x02061);
103                validEntityNames.put("Aring", 0x000C5);
104                validEntityNames.put("Ascr", 0x1D49C);
105                validEntityNames.put("Atilde", 0x000C3);
106                validEntityNames.put("Auml", 0x000C4);
107                validEntityNames.put("Barv", 0x02AE7);
108                validEntityNames.put("Barwed", 0x02306);
109                validEntityNames.put("Bcy", 0x00411);
110                validEntityNames.put("Beta", 0x00392);
111                validEntityNames.put("Bfr", 0x1D505);
112                validEntityNames.put("Bopf", 0x1D539);
113                validEntityNames.put("CHcy", 0x00427);
114                validEntityNames.put("Cacute", 0x00106);
115                validEntityNames.put("Cap", 0x022D2);
116                validEntityNames.put("CapitalDifferentialD", 0x02145);
117                validEntityNames.put("Ccaron", 0x0010C);
118                validEntityNames.put("Ccedil", 0x000C7);
119                validEntityNames.put("Ccirc", 0x00108);
120                validEntityNames.put("Cconint", 0x02230);
121                validEntityNames.put("Cdot", 0x0010A);
122                validEntityNames.put("Cfr", 0x0212D);
123                validEntityNames.put("Chi", 0x003A7);
124                validEntityNames.put("Colon", 0x02237);
125                validEntityNames.put("Colone", 0x02A74);
126                validEntityNames.put("Conint", 0x0222F);
127                validEntityNames.put("Copf", 0x02102);
128                validEntityNames.put("Cross", 0x02A2F);
129                validEntityNames.put("Cscr", 0x1D49E);
130                validEntityNames.put("Cup", 0x022D3);
131                validEntityNames.put("DDotrahd", 0x02911);
132                validEntityNames.put("DJcy", 0x00402);
133                validEntityNames.put("DScy", 0x00405);
134                validEntityNames.put("DZcy", 0x0040F);
135                validEntityNames.put("Dagger", 0x02021);
136                validEntityNames.put("Darr", 0x021A1);
137                validEntityNames.put("Dashv", 0x02AE4);
138                validEntityNames.put("Dcaron", 0x0010E);
139                validEntityNames.put("Dcy", 0x00414);
140                validEntityNames.put("Delta", 0x00394);
141                validEntityNames.put("Dfr", 0x1D507);
142                validEntityNames.put("DifferentialD", 0x02146);
143                validEntityNames.put("Dopf", 0x1D53B);
144                validEntityNames.put("Dot", 0x000A8);
145                validEntityNames.put("DotDot", 0x020DC);
146                validEntityNames.put("DownArrowBar", 0x02913);
147                validEntityNames.put("DownBreve", 0x00311);
148                validEntityNames.put("DownLeftRightVector", 0x02950);
149                validEntityNames.put("DownLeftTeeVector", 0x0295E);
150                validEntityNames.put("DownLeftVectorBar", 0x02956);
151                validEntityNames.put("DownRightTeeVector", 0x0295F);
152                validEntityNames.put("DownRightVectorBar", 0x02957);
153                validEntityNames.put("DownTeeArrow", 0x021A7);
154                validEntityNames.put("Dscr", 0x1D49F);
155                validEntityNames.put("Dstrok", 0x00110);
156                validEntityNames.put("ENG", 0x0014A);
157                validEntityNames.put("ETH", 0x000D0);
158                validEntityNames.put("Eacute", 0x000C9);
159                validEntityNames.put("Ecaron", 0x0011A);
160                validEntityNames.put("Ecirc", 0x000CA);
161                validEntityNames.put("Ecy", 0x0042D);
162                validEntityNames.put("Edot", 0x00116);
163                validEntityNames.put("Efr", 0x1D508);
164                validEntityNames.put("Egrave", 0x000C8);
165                validEntityNames.put("Emacr", 0x00112);
166                validEntityNames.put("EmptySmallSquare", 0x025FB);
167                validEntityNames.put("EmptyVerySmallSquare", 0x025AB);
168                validEntityNames.put("Eogon", 0x00118);
169                validEntityNames.put("Eopf", 0x1D53C);
170                validEntityNames.put("Epsilon", 0x00395);
171                validEntityNames.put("Equal", 0x02A75);
172                validEntityNames.put("Escr", 0x02130);
173                validEntityNames.put("Esim", 0x02A73);
174                validEntityNames.put("Eta", 0x00397);
175                validEntityNames.put("Euml", 0x000CB);
176                validEntityNames.put("ExponentialE", 0x02147);
177                validEntityNames.put("Fcy", 0x00424);
178                validEntityNames.put("Ffr", 0x1D509);
179                validEntityNames.put("FilledSmallSquare", 0x025FC);
180                validEntityNames.put("Fopf", 0x1D53D);
181                validEntityNames.put("Fscr", 0x02131);
182                validEntityNames.put("GJcy", 0x00403);
183                validEntityNames.put("Gamma", 0x00393);
184                validEntityNames.put("Gammad", 0x003DC);
185                validEntityNames.put("Gbreve", 0x0011E);
186                validEntityNames.put("Gcedil", 0x00122);
187                validEntityNames.put("Gcirc", 0x0011C);
188                validEntityNames.put("Gcy", 0x00413);
189                validEntityNames.put("Gdot", 0x00120);
190                validEntityNames.put("Gfr", 0x1D50A);
191                validEntityNames.put("Gg", 0x022D9);
192                validEntityNames.put("Gopf", 0x1D53E);
193                validEntityNames.put("GreaterGreater", 0x02AA2);
194                validEntityNames.put("Gscr", 0x1D4A2);
195                validEntityNames.put("Gt", 0x0226B);
196                validEntityNames.put("HARDcy", 0x0042A);
197                validEntityNames.put("Hat", 0x0005E);
198                validEntityNames.put("Hcirc", 0x00124);
199                validEntityNames.put("Hfr", 0x0210C);
200                validEntityNames.put("Hstrok", 0x00126);
201                validEntityNames.put("IEcy", 0x00415);
202                validEntityNames.put("IJlig", 0x00132);
203                validEntityNames.put("IOcy", 0x00401);
204                validEntityNames.put("Iacute", 0x000CD);
205                validEntityNames.put("Icirc", 0x000CE);
206                validEntityNames.put("Icy", 0x00418);
207                validEntityNames.put("Idot", 0x00130);
208                validEntityNames.put("Igrave", 0x000CC);
209                validEntityNames.put("Imacr", 0x0012A);
210                validEntityNames.put("ImaginaryI", 0x02148);
211                validEntityNames.put("Int", 0x0222C);
212                validEntityNames.put("InvisibleComma", 0x02063);
213                validEntityNames.put("InvisibleTimes", 0x02062);
214                validEntityNames.put("Iogon", 0x0012E);
215                validEntityNames.put("Iopf", 0x1D540);
216                validEntityNames.put("Iota", 0x00399);
217                validEntityNames.put("Iscr", 0x02110);
218                validEntityNames.put("Itilde", 0x00128);
219                validEntityNames.put("Iukcy", 0x00406);
220                validEntityNames.put("Iuml", 0x000CF);
221                validEntityNames.put("Jcirc", 0x00134);
222                validEntityNames.put("Jcy", 0x00419);
223                validEntityNames.put("Jfr", 0x1D50D);
224                validEntityNames.put("Jopf", 0x1D541);
225                validEntityNames.put("Jscr", 0x1D4A5);
226                validEntityNames.put("Jsercy", 0x00408);
227                validEntityNames.put("Jukcy", 0x00404);
228                validEntityNames.put("KHcy", 0x00425);
229                validEntityNames.put("KJcy", 0x0040C);
230                validEntityNames.put("Kappa", 0x0039A);
231                validEntityNames.put("Kcedil", 0x00136);
232                validEntityNames.put("Kcy", 0x0041A);
233                validEntityNames.put("Kfr", 0x1D50E);
234                validEntityNames.put("Kopf", 0x1D542);
235                validEntityNames.put("Kscr", 0x1D4A6);
236                validEntityNames.put("LJcy", 0x00409);
237                validEntityNames.put("Lacute", 0x00139);
238                validEntityNames.put("Lambda", 0x0039B);
239                validEntityNames.put("Lang", 0x027EA);
240                validEntityNames.put("Larr", 0x0219E);
241                validEntityNames.put("Lcaron", 0x0013D);
242                validEntityNames.put("Lcedil", 0x0013B);
243                validEntityNames.put("Lcy", 0x0041B);
244                validEntityNames.put("LeftDownTeeVector", 0x02961);
245                validEntityNames.put("LeftDownVectorBar", 0x02959);
246                validEntityNames.put("LeftRightVector", 0x0294E);
247                validEntityNames.put("LeftTeeArrow", 0x021A4);
248                validEntityNames.put("LeftTeeVector", 0x0295A);
249                validEntityNames.put("LeftTriangleBar", 0x029CF);
250                validEntityNames.put("LeftUpDownVector", 0x02951);
251                validEntityNames.put("LeftUpTeeVector", 0x02960);
252                validEntityNames.put("LeftUpVectorBar", 0x02958);
253                validEntityNames.put("LeftVectorBar", 0x02952);
254                validEntityNames.put("LessLess", 0x02AA1);
255                validEntityNames.put("Lfr", 0x1D50F);
256                validEntityNames.put("Ll", 0x022D8);
257                validEntityNames.put("Lmidot", 0x0013F);
258                validEntityNames.put("Lopf", 0x1D543);
259                validEntityNames.put("Lscr", 0x02112);
260                validEntityNames.put("Lstrok", 0x00141);
261                validEntityNames.put("Lt", 0x0226A);
262                validEntityNames.put("Map", 0x02905);
263                validEntityNames.put("Mcy", 0x0041C);
264                validEntityNames.put("MediumSpace", 0x0205F);
265                validEntityNames.put("Mfr", 0x1D510);
266                validEntityNames.put("Mopf", 0x1D544);
267                validEntityNames.put("Mu", 0x0039C);
268                validEntityNames.put("NJcy", 0x0040A);
269                validEntityNames.put("Nacute", 0x00143);
270                validEntityNames.put("Ncaron", 0x00147);
271                validEntityNames.put("Ncedil", 0x00145);
272                validEntityNames.put("Ncy", 0x0041D);
273                validEntityNames.put("NewLine", 0x0000A);
274                validEntityNames.put("Nfr", 0x1D511);
275                validEntityNames.put("NoBreak", 0x02060);
276                validEntityNames.put("Nopf", 0x02115);
277                validEntityNames.put("Not", 0x02AEC);
278                validEntityNames.put("NotCupCap", 0x0226D);
279                validEntityNames.put("Nscr", 0x1D4A9);
280                validEntityNames.put("Ntilde", 0x000D1);
281                validEntityNames.put("Nu", 0x0039D);
282                validEntityNames.put("OElig", 0x00152);
283                validEntityNames.put("Oacute", 0x000D3);
284                validEntityNames.put("Ocirc", 0x000D4);
285                validEntityNames.put("Ocy", 0x0041E);
286                validEntityNames.put("Odblac", 0x00150);
287                validEntityNames.put("Ofr", 0x1D512);
288                validEntityNames.put("Ograve", 0x000D2);
289                validEntityNames.put("Omacr", 0x0014C);
290                validEntityNames.put("Omega", 0x003A9);
291                validEntityNames.put("Omicron", 0x0039F);
292                validEntityNames.put("Oopf", 0x1D546);
293                validEntityNames.put("Or", 0x02A54);
294                validEntityNames.put("Oscr", 0x1D4AA);
295                validEntityNames.put("Oslash", 0x000D8);
296                validEntityNames.put("Otilde", 0x000D5);
297                validEntityNames.put("Otimes", 0x02A37);
298                validEntityNames.put("Ouml", 0x000D6);
299                validEntityNames.put("OverBrace", 0x023DE);
300                validEntityNames.put("OverParenthesis", 0x023DC);
301                validEntityNames.put("Pcy", 0x0041F);
302                validEntityNames.put("Pfr", 0x1D513);
303                validEntityNames.put("Phi", 0x003A6);
304                validEntityNames.put("Pi", 0x003A0);
305                validEntityNames.put("Popf", 0x02119);
306                validEntityNames.put("Pr", 0x02ABB);
307                validEntityNames.put("Prime", 0x02033);
308                validEntityNames.put("Pscr", 0x1D4AB);
309                validEntityNames.put("Psi", 0x003A8);
310                validEntityNames.put("Qfr", 0x1D514);
311                validEntityNames.put("Qscr", 0x1D4AC);
312                validEntityNames.put("RBarr", 0x02910);
313                validEntityNames.put("Racute", 0x00154);
314                validEntityNames.put("Rang", 0x027EB);
315                validEntityNames.put("Rarr", 0x021A0);
316                validEntityNames.put("Rarrtl", 0x02916);
317                validEntityNames.put("Rcaron", 0x00158);
318                validEntityNames.put("Rcedil", 0x00156);
319                validEntityNames.put("Rcy", 0x00420);
320                validEntityNames.put("Rho", 0x003A1);
321                validEntityNames.put("RightDownTeeVector", 0x0295D);
322                validEntityNames.put("RightDownVectorBar", 0x02955);
323                validEntityNames.put("RightTeeVector", 0x0295B);
324                validEntityNames.put("RightTriangleBar", 0x029D0);
325                validEntityNames.put("RightUpDownVector", 0x0294F);
326                validEntityNames.put("RightUpTeeVector", 0x0295C);
327                validEntityNames.put("RightUpVectorBar", 0x02954);
328                validEntityNames.put("RightVectorBar", 0x02953);
329                validEntityNames.put("RoundImplies", 0x02970);
330                validEntityNames.put("Rscr", 0x0211B);
331                validEntityNames.put("RuleDelayed", 0x029F4);
332                validEntityNames.put("SHCHcy", 0x00429);
333                validEntityNames.put("SHcy", 0x00428);
334                validEntityNames.put("SOFTcy", 0x0042C);
335                validEntityNames.put("Sacute", 0x0015A);
336                validEntityNames.put("Sc", 0x02ABC);
337                validEntityNames.put("Scaron", 0x00160);
338                validEntityNames.put("Scedil", 0x0015E);
339                validEntityNames.put("Scirc", 0x0015C);
340                validEntityNames.put("Scy", 0x00421);
341                validEntityNames.put("Sfr", 0x1D516);
342                validEntityNames.put("Sigma", 0x003A3);
343                validEntityNames.put("Sopf", 0x1D54A);
344                validEntityNames.put("Sscr", 0x1D4AE);
345                validEntityNames.put("Sub", 0x022D0);
346                validEntityNames.put("Sup", 0x022D1);
347                validEntityNames.put("THORN", 0x000DE);
348                validEntityNames.put("TSHcy", 0x0040B);
349                validEntityNames.put("TScy", 0x00426);
350                validEntityNames.put("Tab", 0x00009);
351                validEntityNames.put("Tau", 0x003A4);
352                validEntityNames.put("Tcaron", 0x00164);
353                validEntityNames.put("Tcedil", 0x00162);
354                validEntityNames.put("Tcy", 0x00422);
355                validEntityNames.put("Tfr", 0x1D517);
356                validEntityNames.put("Theta", 0x00398);
357                validEntityNames.put("Topf", 0x1D54B);
358                validEntityNames.put("Tscr", 0x1D4AF);
359                validEntityNames.put("Tstrok", 0x00166);
360                validEntityNames.put("Uacute", 0x000DA);
361                validEntityNames.put("Uarr", 0x0219F);
362                validEntityNames.put("Uarrocir", 0x02949);
363                validEntityNames.put("Ubrcy", 0x0040E);
364                validEntityNames.put("Ubreve", 0x0016C);
365                validEntityNames.put("Ucirc", 0x000DB);
366                validEntityNames.put("Ucy", 0x00423);
367                validEntityNames.put("Udblac", 0x00170);
368                validEntityNames.put("Ufr", 0x1D518);
369                validEntityNames.put("Ugrave", 0x000D9);
370                validEntityNames.put("Umacr", 0x0016A);
371                validEntityNames.put("UnderBar", 0x00332);
372                validEntityNames.put("UnderBrace", 0x023DF);
373                validEntityNames.put("UnderParenthesis", 0x023DD);
374                validEntityNames.put("Uogon", 0x00172);
375                validEntityNames.put("Uopf", 0x1D54C);
376                validEntityNames.put("UpArrowBar", 0x02912);
377                validEntityNames.put("UpTeeArrow", 0x021A5);
378                validEntityNames.put("Upsi", 0x003D2);
379                validEntityNames.put("Upsilon", 0x003A5);
380                validEntityNames.put("Uring", 0x0016E);
381                validEntityNames.put("Uscr", 0x1D4B0);
382                validEntityNames.put("Utilde", 0x00168);
383                validEntityNames.put("Uuml", 0x000DC);
384                validEntityNames.put("VDash", 0x022AB);
385                validEntityNames.put("Vbar", 0x02AEB);
386                validEntityNames.put("Vcy", 0x00412);
387                validEntityNames.put("Vdash", 0x022A9);
388                validEntityNames.put("Vdashl", 0x02AE6);
389                validEntityNames.put("Verbar", 0x02016);
390                validEntityNames.put("VerticalSeparator", 0x02758);
391                validEntityNames.put("Vfr", 0x1D519);
392                validEntityNames.put("Vopf", 0x1D54D);
393                validEntityNames.put("Vscr", 0x1D4B1);
394                validEntityNames.put("Vvdash", 0x022AA);
395                validEntityNames.put("Wcirc", 0x00174);
396                validEntityNames.put("Wfr", 0x1D51A);
397                validEntityNames.put("Wopf", 0x1D54E);
398                validEntityNames.put("Wscr", 0x1D4B2);
399                validEntityNames.put("Xfr", 0x1D51B);
400                validEntityNames.put("Xi", 0x0039E);
401                validEntityNames.put("Xopf", 0x1D54F);
402                validEntityNames.put("Xscr", 0x1D4B3);
403                validEntityNames.put("YAcy", 0x0042F);
404                validEntityNames.put("YIcy", 0x00407);
405                validEntityNames.put("YUcy", 0x0042E);
406                validEntityNames.put("Yacute", 0x000DD);
407                validEntityNames.put("Ycirc", 0x00176);
408                validEntityNames.put("Ycy", 0x0042B);
409                validEntityNames.put("Yfr", 0x1D51C);
410                validEntityNames.put("Yopf", 0x1D550);
411                validEntityNames.put("Yscr", 0x1D4B4);
412                validEntityNames.put("Yuml", 0x00178);
413                validEntityNames.put("ZHcy", 0x00416);
414                validEntityNames.put("Zacute", 0x00179);
415                validEntityNames.put("Zcaron", 0x0017D);
416                validEntityNames.put("Zcy", 0x00417);
417                validEntityNames.put("Zdot", 0x0017B);
418                validEntityNames.put("ZeroWidthSpace", 0x0200B);
419                validEntityNames.put("Zeta", 0x00396);
420                validEntityNames.put("Zfr", 0x02128);
421                validEntityNames.put("Zscr", 0x1D4B5);
422                validEntityNames.put("aacute", 0x000E1);
423                validEntityNames.put("abreve", 0x00103);
424                validEntityNames.put("ac", 0x0223E);
425                validEntityNames.put("acd", 0x0223F);
426                validEntityNames.put("acirc", 0x000E2);
427                validEntityNames.put("acute", 0x000B4);
428                validEntityNames.put("acy", 0x00430);
429                validEntityNames.put("aelig", 0x000E6);
430                validEntityNames.put("afr", 0x1D51E);
431                validEntityNames.put("agrave", 0x000E0);
432                validEntityNames.put("alefsym", 0x02135);
433                validEntityNames.put("alpha", 0x003B1);
434                validEntityNames.put("amacr", 0x00101);
435                validEntityNames.put("amalg", 0x02A3F);
436                validEntityNames.put("amp", 0x00026);
437                validEntityNames.put("and", 0x02227);
438                validEntityNames.put("andand", 0x02A55);
439                validEntityNames.put("andd", 0x02A5C);
440                validEntityNames.put("andslope", 0x02A58);
441                validEntityNames.put("andv", 0x02A5A);
442                validEntityNames.put("ang", 0x02220);
443                validEntityNames.put("ange", 0x029A4);
444                validEntityNames.put("angmsd", 0x02221);
445                validEntityNames.put("angmsdaa", 0x029A8);
446                validEntityNames.put("angmsdab", 0x029A9);
447                validEntityNames.put("angmsdac", 0x029AA);
448                validEntityNames.put("angmsdad", 0x029AB);
449                validEntityNames.put("angmsdae", 0x029AC);
450                validEntityNames.put("angmsdaf", 0x029AD);
451                validEntityNames.put("angmsdag", 0x029AE);
452                validEntityNames.put("angmsdah", 0x029AF);
453                validEntityNames.put("angrt", 0x0221F);
454                validEntityNames.put("angrtvb", 0x022BE);
455                validEntityNames.put("angrtvbd", 0x0299D);
456                validEntityNames.put("angsph", 0x02222);
457                validEntityNames.put("angst", 0x0212B);
458                validEntityNames.put("angzarr", 0x0237C);
459                validEntityNames.put("aogon", 0x00105);
460                validEntityNames.put("aopf", 0x1D552);
461                validEntityNames.put("apE", 0x02A70);
462                validEntityNames.put("apacir", 0x02A6F);
463                validEntityNames.put("ape", 0x0224A);
464                validEntityNames.put("apid", 0x0224B);
465                validEntityNames.put("apos", 0x00027);
466                validEntityNames.put("aring", 0x000E5);
467                validEntityNames.put("ascr", 0x1D4B6);
468                validEntityNames.put("ast", 0x0002A);
469                validEntityNames.put("asymp", 0x02248);
470                validEntityNames.put("asympeq", 0x0224D);
471                validEntityNames.put("atilde", 0x000E3);
472                validEntityNames.put("auml", 0x000E4);
473                validEntityNames.put("awconint", 0x02233);
474                validEntityNames.put("awint", 0x02A11);
475                validEntityNames.put("bNot", 0x02AED);
476                validEntityNames.put("barvee", 0x022BD);
477                validEntityNames.put("barwed", 0x02305);
478                validEntityNames.put("bbrk", 0x023B5);
479                validEntityNames.put("bbrktbrk", 0x023B6);
480                validEntityNames.put("bcong", 0x0224C);
481                validEntityNames.put("bcy", 0x00431);
482                validEntityNames.put("becaus", 0x02235);
483                validEntityNames.put("bemptyv", 0x029B0);
484                validEntityNames.put("bepsi", 0x003F6);
485                validEntityNames.put("bernou", 0x0212C);
486                validEntityNames.put("beta", 0x003B2);
487                validEntityNames.put("beth", 0x02136);
488                validEntityNames.put("bfr", 0x1D51F);
489                validEntityNames.put("blank", 0x02423);
490                validEntityNames.put("blk12", 0x02592);
491                validEntityNames.put("blk14", 0x02591);
492                validEntityNames.put("blk34", 0x02593);
493                validEntityNames.put("block", 0x02588);
494                validEntityNames.put("bnot", 0x02310);
495                validEntityNames.put("bopf", 0x1D553);
496                validEntityNames.put("bottom", 0x022A5);
497                validEntityNames.put("bowtie", 0x022C8);
498                validEntityNames.put("boxDL", 0x02557);
499                validEntityNames.put("boxDR", 0x02554);
500                validEntityNames.put("boxDl", 0x02556);
501                validEntityNames.put("boxDr", 0x02553);
502                validEntityNames.put("boxH", 0x02550);
503                validEntityNames.put("boxHD", 0x02566);
504                validEntityNames.put("boxHU", 0x02569);
505                validEntityNames.put("boxHd", 0x02564);
506                validEntityNames.put("boxHu", 0x02567);
507                validEntityNames.put("boxUL", 0x0255D);
508                validEntityNames.put("boxUR", 0x0255A);
509                validEntityNames.put("boxUl", 0x0255C);
510                validEntityNames.put("boxUr", 0x02559);
511                validEntityNames.put("boxV", 0x02551);
512                validEntityNames.put("boxVH", 0x0256C);
513                validEntityNames.put("boxVL", 0x02563);
514                validEntityNames.put("boxVR", 0x02560);
515                validEntityNames.put("boxVh", 0x0256B);
516                validEntityNames.put("boxVl", 0x02562);
517                validEntityNames.put("boxVr", 0x0255F);
518                validEntityNames.put("boxbox", 0x029C9);
519                validEntityNames.put("boxdL", 0x02555);
520                validEntityNames.put("boxdR", 0x02552);
521                validEntityNames.put("boxdl", 0x02510);
522                validEntityNames.put("boxdr", 0x0250C);
523                validEntityNames.put("boxh", 0x02500);
524                validEntityNames.put("boxhD", 0x02565);
525                validEntityNames.put("boxhU", 0x02568);
526                validEntityNames.put("boxhd", 0x0252C);
527                validEntityNames.put("boxhu", 0x02534);
528                validEntityNames.put("boxuL", 0x0255B);
529                validEntityNames.put("boxuR", 0x02558);
530                validEntityNames.put("boxul", 0x02518);
531                validEntityNames.put("boxur", 0x02514);
532                validEntityNames.put("boxv", 0x02502);
533                validEntityNames.put("boxvH", 0x0256A);
534                validEntityNames.put("boxvL", 0x02561);
535                validEntityNames.put("boxvR", 0x0255E);
536                validEntityNames.put("boxvh", 0x0253C);
537                validEntityNames.put("boxvl", 0x02524);
538                validEntityNames.put("boxvr", 0x0251C);
539                validEntityNames.put("bprime", 0x02035);
540                validEntityNames.put("breve", 0x002D8);
541                validEntityNames.put("brvbar", 0x000A6);
542                validEntityNames.put("bscr", 0x1D4B7);
543                validEntityNames.put("bsemi", 0x0204F);
544                validEntityNames.put("bsim", 0x0223D);
545                validEntityNames.put("bsime", 0x022CD);
546                validEntityNames.put("bsol", 0x0005C);
547                validEntityNames.put("bsolb", 0x029C5);
548                validEntityNames.put("bull", 0x02022);
549                validEntityNames.put("bump", 0x0224E);
550                validEntityNames.put("bumpE", 0x02AAE);
551                validEntityNames.put("bumpe", 0x0224F);
552                validEntityNames.put("cacute", 0x00107);
553                validEntityNames.put("cap", 0x02229);
554                validEntityNames.put("capand", 0x02A44);
555                validEntityNames.put("capbrcup", 0x02A49);
556                validEntityNames.put("capcap", 0x02A4B);
557                validEntityNames.put("capcup", 0x02A47);
558                validEntityNames.put("capdot", 0x02A40);
559                validEntityNames.put("caret", 0x02041);
560                validEntityNames.put("caron", 0x002C7);
561                validEntityNames.put("ccaps", 0x02A4D);
562                validEntityNames.put("ccaron", 0x0010D);
563                validEntityNames.put("ccedil", 0x000E7);
564                validEntityNames.put("ccirc", 0x00109);
565                validEntityNames.put("ccups", 0x02A4C);
566                validEntityNames.put("ccupssm", 0x02A50);
567                validEntityNames.put("cdot", 0x0010B);
568                validEntityNames.put("cedil", 0x000B8);
569                validEntityNames.put("cemptyv", 0x029B2);
570                validEntityNames.put("cent", 0x000A2);
571                validEntityNames.put("cfr", 0x1D520);
572                validEntityNames.put("chcy", 0x00447);
573                validEntityNames.put("check", 0x02713);
574                validEntityNames.put("chi", 0x003C7);
575                validEntityNames.put("cir", 0x025CB);
576                validEntityNames.put("cirE", 0x029C3);
577                validEntityNames.put("circ", 0x002C6);
578                validEntityNames.put("cire", 0x02257);
579                validEntityNames.put("cirfnint", 0x02A10);
580                validEntityNames.put("cirmid", 0x02AEF);
581                validEntityNames.put("cirscir", 0x029C2);
582                validEntityNames.put("clubs", 0x02663);
583                validEntityNames.put("colon", 0x0003A);
584                validEntityNames.put("colone", 0x02254);
585                validEntityNames.put("comma", 0x0002C);
586                validEntityNames.put("commat", 0x00040);
587                validEntityNames.put("comp", 0x02201);
588                validEntityNames.put("compfn", 0x02218);
589                validEntityNames.put("cong", 0x02245);
590                validEntityNames.put("congdot", 0x02A6D);
591                validEntityNames.put("conint", 0x0222E);
592                validEntityNames.put("copf", 0x1D554);
593                validEntityNames.put("coprod", 0x02210);
594                validEntityNames.put("copy", 0x000A9);
595                validEntityNames.put("copysr", 0x02117);
596                validEntityNames.put("crarr", 0x021B5);
597                validEntityNames.put("cross", 0x02717);
598                validEntityNames.put("cscr", 0x1D4B8);
599                validEntityNames.put("csub", 0x02ACF);
600                validEntityNames.put("csube", 0x02AD1);
601                validEntityNames.put("csup", 0x02AD0);
602                validEntityNames.put("csupe", 0x02AD2);
603                validEntityNames.put("ctdot", 0x022EF);
604                validEntityNames.put("cudarrl", 0x02938);
605                validEntityNames.put("cudarrr", 0x02935);
606                validEntityNames.put("cuepr", 0x022DE);
607                validEntityNames.put("cuesc", 0x022DF);
608                validEntityNames.put("cularr", 0x021B6);
609                validEntityNames.put("cularrp", 0x0293D);
610                validEntityNames.put("cup", 0x0222A);
611                validEntityNames.put("cupbrcap", 0x02A48);
612                validEntityNames.put("cupcap", 0x02A46);
613                validEntityNames.put("cupcup", 0x02A4A);
614                validEntityNames.put("cupdot", 0x0228D);
615                validEntityNames.put("cupor", 0x02A45);
616                validEntityNames.put("curarr", 0x021B7);
617                validEntityNames.put("curarrm", 0x0293C);
618                validEntityNames.put("curren", 0x000A4);
619                validEntityNames.put("cuvee", 0x022CE);
620                validEntityNames.put("cuwed", 0x022CF);
621                validEntityNames.put("cwconint", 0x02232);
622                validEntityNames.put("cwint", 0x02231);
623                validEntityNames.put("cylcty", 0x0232D);
624                validEntityNames.put("dArr", 0x021D3);
625                validEntityNames.put("dHar", 0x02965);
626                validEntityNames.put("dagger", 0x02020);
627                validEntityNames.put("daleth", 0x02138);
628                validEntityNames.put("darr", 0x02193);
629                validEntityNames.put("dashv", 0x022A3);
630                validEntityNames.put("dblac", 0x002DD);
631                validEntityNames.put("dcaron", 0x0010F);
632                validEntityNames.put("dcy", 0x00434);
633                validEntityNames.put("ddarr", 0x021CA);
634                validEntityNames.put("deg", 0x000B0);
635                validEntityNames.put("delta", 0x003B4);
636                validEntityNames.put("demptyv", 0x029B1);
637                validEntityNames.put("dfisht", 0x0297F);
638                validEntityNames.put("dfr", 0x1D521);
639                validEntityNames.put("dharl", 0x021C3);
640                validEntityNames.put("dharr", 0x021C2);
641                validEntityNames.put("diam", 0x022C4);
642                validEntityNames.put("diams", 0x02666);
643                validEntityNames.put("disin", 0x022F2);
644                validEntityNames.put("divide", 0x000F7);
645                validEntityNames.put("divonx", 0x022C7);
646                validEntityNames.put("djcy", 0x00452);
647                validEntityNames.put("dlcorn", 0x0231E);
648                validEntityNames.put("dlcrop", 0x0230D);
649                validEntityNames.put("dollar", 0x00024);
650                validEntityNames.put("dopf", 0x1D555);
651                validEntityNames.put("dot", 0x002D9);
652                validEntityNames.put("drcorn", 0x0231F);
653                validEntityNames.put("drcrop", 0x0230C);
654                validEntityNames.put("dscr", 0x1D4B9);
655                validEntityNames.put("dscy", 0x00455);
656                validEntityNames.put("dsol", 0x029F6);
657                validEntityNames.put("dstrok", 0x00111);
658                validEntityNames.put("dtdot", 0x022F1);
659                validEntityNames.put("dtri", 0x025BF);
660                validEntityNames.put("dtrif", 0x025BE);
661                validEntityNames.put("duarr", 0x021F5);
662                validEntityNames.put("duhar", 0x0296F);
663                validEntityNames.put("dwangle", 0x029A6);
664                validEntityNames.put("dzcy", 0x0045F);
665                validEntityNames.put("dzigrarr", 0x027FF);
666                validEntityNames.put("eDDot", 0x02A77);
667                validEntityNames.put("eDot", 0x02251);
668                validEntityNames.put("eacute", 0x000E9);
669                validEntityNames.put("easter", 0x02A6E);
670                validEntityNames.put("ecaron", 0x0011B);
671                validEntityNames.put("ecir", 0x02256);
672                validEntityNames.put("ecirc", 0x000EA);
673                validEntityNames.put("ecolon", 0x02255);
674                validEntityNames.put("ecy", 0x0044D);
675                validEntityNames.put("edot", 0x00117);
676                validEntityNames.put("efDot", 0x02252);
677                validEntityNames.put("efr", 0x1D522);
678                validEntityNames.put("eg", 0x02A9A);
679                validEntityNames.put("egrave", 0x000E8);
680                validEntityNames.put("egs", 0x02A96);
681                validEntityNames.put("egsdot", 0x02A98);
682                validEntityNames.put("el", 0x02A99);
683                validEntityNames.put("elinters", 0x023E7);
684                validEntityNames.put("ell", 0x02113);
685                validEntityNames.put("els", 0x02A95);
686                validEntityNames.put("elsdot", 0x02A97);
687                validEntityNames.put("emacr", 0x00113);
688                validEntityNames.put("empty", 0x02205);
689                validEntityNames.put("emsp", 0x02003);
690                validEntityNames.put("emsp13", 0x02004);
691                validEntityNames.put("emsp14", 0x02005);
692                validEntityNames.put("eng", 0x0014B);
693                validEntityNames.put("ensp", 0x02002);
694                validEntityNames.put("eogon", 0x00119);
695                validEntityNames.put("eopf", 0x1D556);
696                validEntityNames.put("epar", 0x022D5);
697                validEntityNames.put("eparsl", 0x029E3);
698                validEntityNames.put("eplus", 0x02A71);
699                validEntityNames.put("epsi", 0x003F5);
700                validEntityNames.put("epsiv", 0x003B5);
701                validEntityNames.put("equals", 0x0003D);
702                validEntityNames.put("equest", 0x0225F);
703                validEntityNames.put("equiv", 0x02261);
704                validEntityNames.put("equivDD", 0x02A78);
705                validEntityNames.put("eqvparsl", 0x029E5);
706                validEntityNames.put("erDot", 0x02253);
707                validEntityNames.put("erarr", 0x02971);
708                validEntityNames.put("escr", 0x0212F);
709                validEntityNames.put("esdot", 0x02250);
710                validEntityNames.put("esim", 0x02242);
711                validEntityNames.put("eta", 0x003B7);
712                validEntityNames.put("eth", 0x000F0);
713                validEntityNames.put("euml", 0x000EB);
714                validEntityNames.put("euro", 0x020AC);
715                validEntityNames.put("excl", 0x00021);
716                validEntityNames.put("exist", 0x02203);
717                validEntityNames.put("fcy", 0x00444);
718                validEntityNames.put("female", 0x02640);
719                validEntityNames.put("ffilig", 0x0FB03);
720                validEntityNames.put("fflig", 0x0FB00);
721                validEntityNames.put("ffllig", 0x0FB04);
722                validEntityNames.put("ffr", 0x1D523);
723                validEntityNames.put("filig", 0x0FB01);
724                validEntityNames.put("flat", 0x0266D);
725                validEntityNames.put("fllig", 0x0FB02);
726                validEntityNames.put("fltns", 0x025B1);
727                validEntityNames.put("fnof", 0x00192);
728                validEntityNames.put("fopf", 0x1D557);
729                validEntityNames.put("forall", 0x02200);
730                validEntityNames.put("fork", 0x022D4);
731                validEntityNames.put("forkv", 0x02AD9);
732                validEntityNames.put("fpartint", 0x02A0D);
733                validEntityNames.put("frac12", 0x000BD);
734                validEntityNames.put("frac13", 0x02153);
735                validEntityNames.put("frac14", 0x000BC);
736                validEntityNames.put("frac15", 0x02155);
737                validEntityNames.put("frac16", 0x02159);
738                validEntityNames.put("frac18", 0x0215B);
739                validEntityNames.put("frac23", 0x02154);
740                validEntityNames.put("frac25", 0x02156);
741                validEntityNames.put("frac34", 0x000BE);
742                validEntityNames.put("frac35", 0x02157);
743                validEntityNames.put("frac38", 0x0215C);
744                validEntityNames.put("frac45", 0x02158);
745                validEntityNames.put("frac56", 0x0215A);
746                validEntityNames.put("frac58", 0x0215D);
747                validEntityNames.put("frac78", 0x0215E);
748                validEntityNames.put("frasl", 0x02044);
749                validEntityNames.put("frown", 0x02322);
750                validEntityNames.put("fscr", 0x1D4BB);
751                validEntityNames.put("gE", 0x02267);
752                validEntityNames.put("gEl", 0x02A8C);
753                validEntityNames.put("gacute", 0x001F5);
754                validEntityNames.put("gamma", 0x003B3);
755                validEntityNames.put("gammad", 0x003DD);
756                validEntityNames.put("gap", 0x02A86);
757                validEntityNames.put("gbreve", 0x0011F);
758                validEntityNames.put("gcirc", 0x0011D);
759                validEntityNames.put("gcy", 0x00433);
760                validEntityNames.put("gdot", 0x00121);
761                validEntityNames.put("ge", 0x02265);
762                validEntityNames.put("gel", 0x022DB);
763                validEntityNames.put("ges", 0x02A7E);
764                validEntityNames.put("gescc", 0x02AA9);
765                validEntityNames.put("gesdot", 0x02A80);
766                validEntityNames.put("gesdoto", 0x02A82);
767                validEntityNames.put("gesdotol", 0x02A84);
768                validEntityNames.put("gesles", 0x02A94);
769                validEntityNames.put("gfr", 0x1D524);
770                validEntityNames.put("gimel", 0x02137);
771                validEntityNames.put("gjcy", 0x00453);
772                validEntityNames.put("gl", 0x02277);
773                validEntityNames.put("glE", 0x02A92);
774                validEntityNames.put("gla", 0x02AA5);
775                validEntityNames.put("glj", 0x02AA4);
776                validEntityNames.put("gnE", 0x02269);
777                validEntityNames.put("gnap", 0x02A8A);
778                validEntityNames.put("gne", 0x02A88);
779                validEntityNames.put("gnsim", 0x022E7);
780                validEntityNames.put("gopf", 0x1D558);
781                validEntityNames.put("grave", 0x00060);
782                validEntityNames.put("gscr", 0x0210A);
783                validEntityNames.put("gsim", 0x02273);
784                validEntityNames.put("gsime", 0x02A8E);
785                validEntityNames.put("gsiml", 0x02A90);
786                validEntityNames.put("gt", 0x0003E);
787                validEntityNames.put("gtcc", 0x02AA7);
788                validEntityNames.put("gtcir", 0x02A7A);
789                validEntityNames.put("gtdot", 0x022D7);
790                validEntityNames.put("gtlPar", 0x02995);
791                validEntityNames.put("gtquest", 0x02A7C);
792                validEntityNames.put("gtrarr", 0x02978);
793                validEntityNames.put("hArr", 0x021D4);
794                validEntityNames.put("hairsp", 0x0200A);
795                validEntityNames.put("hamilt", 0x0210B);
796                validEntityNames.put("hardcy", 0x0044A);
797                validEntityNames.put("harr", 0x02194);
798                validEntityNames.put("harrcir", 0x02948);
799                validEntityNames.put("harrw", 0x021AD);
800                validEntityNames.put("hcirc", 0x00125);
801                validEntityNames.put("hearts", 0x02665);
802                validEntityNames.put("hellip", 0x02026);
803                validEntityNames.put("hercon", 0x022B9);
804                validEntityNames.put("hfr", 0x1D525);
805                validEntityNames.put("hoarr", 0x021FF);
806                validEntityNames.put("homtht", 0x0223B);
807                validEntityNames.put("hopf", 0x1D559);
808                validEntityNames.put("horbar", 0x02015);
809                validEntityNames.put("hscr", 0x1D4BD);
810                validEntityNames.put("hstrok", 0x00127);
811                validEntityNames.put("hybull", 0x02043);
812                validEntityNames.put("hyphen", 0x02010);
813                validEntityNames.put("iacute", 0x000ED);
814                validEntityNames.put("icirc", 0x000EE);
815                validEntityNames.put("icy", 0x00438);
816                validEntityNames.put("iecy", 0x00435);
817                validEntityNames.put("iexcl", 0x000A1);
818                validEntityNames.put("ifr", 0x1D526);
819                validEntityNames.put("igrave", 0x000EC);
820                validEntityNames.put("iinfin", 0x029DC);
821                validEntityNames.put("iiota", 0x02129);
822                validEntityNames.put("ijlig", 0x00133);
823                validEntityNames.put("imacr", 0x0012B);
824                validEntityNames.put("image", 0x02111);
825                validEntityNames.put("imath", 0x00131);
826                validEntityNames.put("imof", 0x022B7);
827                validEntityNames.put("imped", 0x001B5);
828                validEntityNames.put("incare", 0x02105);
829                validEntityNames.put("infin", 0x0221E);
830                validEntityNames.put("infintie", 0x029DD);
831                validEntityNames.put("int", 0x0222B);
832                validEntityNames.put("intcal", 0x022BA);
833                validEntityNames.put("integers", 0x02124);
834                validEntityNames.put("intlarhk", 0x02A17);
835                validEntityNames.put("iocy", 0x00451);
836                validEntityNames.put("iogon", 0x0012F);
837                validEntityNames.put("iopf", 0x1D55A);
838                validEntityNames.put("iota", 0x003B9);
839                validEntityNames.put("iprod", 0x02A3C);
840                validEntityNames.put("iquest", 0x000BF);
841                validEntityNames.put("iscr", 0x1D4BE);
842                validEntityNames.put("isin", 0x02208);
843                validEntityNames.put("isinE", 0x022F9);
844                validEntityNames.put("isindot", 0x022F5);
845                validEntityNames.put("isins", 0x022F4);
846                validEntityNames.put("isinsv", 0x022F3);
847                validEntityNames.put("itilde", 0x00129);
848                validEntityNames.put("iukcy", 0x00456);
849                validEntityNames.put("iuml", 0x000EF);
850                validEntityNames.put("jcirc", 0x00135);
851                validEntityNames.put("jcy", 0x00439);
852                validEntityNames.put("jfr", 0x1D527);
853                validEntityNames.put("jmath", 0x00237);
854                validEntityNames.put("jopf", 0x1D55B);
855                validEntityNames.put("jscr", 0x1D4BF);
856                validEntityNames.put("jsercy", 0x00458);
857                validEntityNames.put("jukcy", 0x00454);
858                validEntityNames.put("kappa", 0x003BA);
859                validEntityNames.put("kappav", 0x003F0);
860                validEntityNames.put("kcedil", 0x00137);
861                validEntityNames.put("kcy", 0x0043A);
862                validEntityNames.put("kfr", 0x1D528);
863                validEntityNames.put("kgreen", 0x00138);
864                validEntityNames.put("khcy", 0x00445);
865                validEntityNames.put("kjcy", 0x0045C);
866                validEntityNames.put("kopf", 0x1D55C);
867                validEntityNames.put("kscr", 0x1D4C0);
868                validEntityNames.put("lAarr", 0x021DA);
869                validEntityNames.put("lArr", 0x021D0);
870                validEntityNames.put("lAtail", 0x0291B);
871                validEntityNames.put("lBarr", 0x0290E);
872                validEntityNames.put("lE", 0x02266);
873                validEntityNames.put("lEg", 0x02A8B);
874                validEntityNames.put("lHar", 0x02962);
875                validEntityNames.put("lacute", 0x0013A);
876                validEntityNames.put("laemptyv", 0x029B4);
877                validEntityNames.put("lambda", 0x003BB);
878                validEntityNames.put("lang", 0x027E8);
879                validEntityNames.put("langd", 0x02991);
880                validEntityNames.put("lap", 0x02A85);
881                validEntityNames.put("laquo", 0x000AB);
882                validEntityNames.put("larr", 0x02190);
883                validEntityNames.put("larrb", 0x021E4);
884                validEntityNames.put("larrbfs", 0x0291F);
885                validEntityNames.put("larrfs", 0x0291D);
886                validEntityNames.put("larrhk", 0x021A9);
887                validEntityNames.put("larrlp", 0x021AB);
888                validEntityNames.put("larrpl", 0x02939);
889                validEntityNames.put("larrsim", 0x02973);
890                validEntityNames.put("larrtl", 0x021A2);
891                validEntityNames.put("lat", 0x02AAB);
892                validEntityNames.put("latail", 0x02919);
893                validEntityNames.put("late", 0x02AAD);
894                validEntityNames.put("lbarr", 0x0290C);
895                validEntityNames.put("lbbrk", 0x02772);
896                validEntityNames.put("lbrke", 0x0298B);
897                validEntityNames.put("lbrksld", 0x0298F);
898                validEntityNames.put("lbrkslu", 0x0298D);
899                validEntityNames.put("lcaron", 0x0013E);
900                validEntityNames.put("lcedil", 0x0013C);
901                validEntityNames.put("lceil", 0x02308);
902                validEntityNames.put("lcub", 0x0007B);
903                validEntityNames.put("lcy", 0x0043B);
904                validEntityNames.put("ldca", 0x02936);
905                validEntityNames.put("ldquo", 0x0201C);
906                validEntityNames.put("ldquor", 0x0201E);
907                validEntityNames.put("ldrdhar", 0x02967);
908                validEntityNames.put("ldrushar", 0x0294B);
909                validEntityNames.put("ldsh", 0x021B2);
910                validEntityNames.put("le", 0x02264);
911                validEntityNames.put("leg", 0x022DA);
912                validEntityNames.put("les", 0x02A7D);
913                validEntityNames.put("lescc", 0x02AA8);
914                validEntityNames.put("lesdot", 0x02A7F);
915                validEntityNames.put("lesdoto", 0x02A81);
916                validEntityNames.put("lesdotor", 0x02A83);
917                validEntityNames.put("lesges", 0x02A93);
918                validEntityNames.put("lfisht", 0x0297C);
919                validEntityNames.put("lfloor", 0x0230A);
920                validEntityNames.put("lfr", 0x1D529);
921                validEntityNames.put("lg", 0x02276);
922                validEntityNames.put("lgE", 0x02A91);
923                validEntityNames.put("lhard", 0x021BD);
924                validEntityNames.put("lharu", 0x021BC);
925                validEntityNames.put("lharul", 0x0296A);
926                validEntityNames.put("lhblk", 0x02584);
927                validEntityNames.put("ljcy", 0x00459);
928                validEntityNames.put("llarr", 0x021C7);
929                validEntityNames.put("llhard", 0x0296B);
930                validEntityNames.put("lltri", 0x025FA);
931                validEntityNames.put("lmidot", 0x00140);
932                validEntityNames.put("lmoust", 0x023B0);
933                validEntityNames.put("lnE", 0x02268);
934                validEntityNames.put("lnap", 0x02A89);
935                validEntityNames.put("lne", 0x02A87);
936                validEntityNames.put("lnsim", 0x022E6);
937                validEntityNames.put("loang", 0x027EC);
938                validEntityNames.put("loarr", 0x021FD);
939                validEntityNames.put("lobrk", 0x027E6);
940                validEntityNames.put("lopar", 0x02985);
941                validEntityNames.put("lopf", 0x1D55D);
942                validEntityNames.put("loplus", 0x02A2D);
943                validEntityNames.put("lotimes", 0x02A34);
944                validEntityNames.put("lowast", 0x02217);
945                validEntityNames.put("lowbar", 0x0005F);
946                validEntityNames.put("loz", 0x025CA);
947                validEntityNames.put("lozf", 0x029EB);
948                validEntityNames.put("lpar", 0x00028);
949                validEntityNames.put("lparlt", 0x02993);
950                validEntityNames.put("lrarr", 0x021C6);
951                validEntityNames.put("lrhar", 0x021CB);
952                validEntityNames.put("lrhard", 0x0296D);
953                validEntityNames.put("lrm", 0x0200E);
954                validEntityNames.put("lrtri", 0x022BF);
955                validEntityNames.put("lsaquo", 0x02039);
956                validEntityNames.put("lscr", 0x1D4C1);
957                validEntityNames.put("lsh", 0x021B0);
958                validEntityNames.put("lsim", 0x02272);
959                validEntityNames.put("lsime", 0x02A8D);
960                validEntityNames.put("lsimg", 0x02A8F);
961                validEntityNames.put("lsqb", 0x0005B);
962                validEntityNames.put("lsquo", 0x02018);
963                validEntityNames.put("lsquor", 0x0201A);
964                validEntityNames.put("lstrok", 0x00142);
965                validEntityNames.put("lt", 0x0003C);
966                validEntityNames.put("ltcc", 0x02AA6);
967                validEntityNames.put("ltcir", 0x02A79);
968                validEntityNames.put("ltdot", 0x022D6);
969                validEntityNames.put("lthree", 0x022CB);
970                validEntityNames.put("ltimes", 0x022C9);
971                validEntityNames.put("ltlarr", 0x02976);
972                validEntityNames.put("ltquest", 0x02A7B);
973                validEntityNames.put("ltrPar", 0x02996);
974                validEntityNames.put("ltri", 0x025C3);
975                validEntityNames.put("ltrie", 0x022B4);
976                validEntityNames.put("ltrif", 0x025C2);
977                validEntityNames.put("lurdshar", 0x0294A);
978                validEntityNames.put("luruhar", 0x02966);
979                validEntityNames.put("mDDot", 0x0223A);
980                validEntityNames.put("macr", 0x000AF);
981                validEntityNames.put("male", 0x02642);
982                validEntityNames.put("malt", 0x02720);
983                validEntityNames.put("map", 0x021A6);
984                validEntityNames.put("marker", 0x025AE);
985                validEntityNames.put("mcomma", 0x02A29);
986                validEntityNames.put("mcy", 0x0043C);
987                validEntityNames.put("mdash", 0x02014);
988                validEntityNames.put("mfr", 0x1D52A);
989                validEntityNames.put("mho", 0x02127);
990                validEntityNames.put("micro", 0x000B5);
991                validEntityNames.put("mid", 0x02223);
992                validEntityNames.put("midcir", 0x02AF0);
993                validEntityNames.put("middot", 0x000B7);
994                validEntityNames.put("minus", 0x02212);
995                validEntityNames.put("minusb", 0x0229F);
996                validEntityNames.put("minusd", 0x02238);
997                validEntityNames.put("minusdu", 0x02A2A);
998                validEntityNames.put("mlcp", 0x02ADB);
999                validEntityNames.put("mnplus", 0x02213);
1000                validEntityNames.put("models", 0x022A7);
1001                validEntityNames.put("mopf", 0x1D55E);
1002                validEntityNames.put("mscr", 0x1D4C2);
1003                validEntityNames.put("mu", 0x003BC);
1004                validEntityNames.put("mumap", 0x022B8);
1005                validEntityNames.put("nVDash", 0x022AF);
1006                validEntityNames.put("nVdash", 0x022AE);
1007                validEntityNames.put("nabla", 0x02207);
1008                validEntityNames.put("nacute", 0x00144);
1009                validEntityNames.put("nap", 0x02249);
1010                validEntityNames.put("napos", 0x00149);
1011                validEntityNames.put("natur", 0x0266E);
1012                validEntityNames.put("nbsp", 0x000A0);
1013                validEntityNames.put("ncap", 0x02A43);
1014                validEntityNames.put("ncaron", 0x00148);
1015                validEntityNames.put("ncedil", 0x00146);
1016                validEntityNames.put("ncong", 0x02247);
1017                validEntityNames.put("ncup", 0x02A42);
1018                validEntityNames.put("ncy", 0x0043D);
1019                validEntityNames.put("ndash", 0x02013);
1020                validEntityNames.put("ne", 0x02260);
1021                validEntityNames.put("neArr", 0x021D7);
1022                validEntityNames.put("nearhk", 0x02924);
1023                validEntityNames.put("nearr", 0x02197);
1024                validEntityNames.put("nequiv", 0x02262);
1025                validEntityNames.put("nesear", 0x02928);
1026                validEntityNames.put("nexist", 0x02204);
1027                validEntityNames.put("nfr", 0x1D52B);
1028                validEntityNames.put("nge", 0x02271);
1029                validEntityNames.put("ngsim", 0x02275);
1030                validEntityNames.put("ngt", 0x0226F);
1031                validEntityNames.put("nhArr", 0x021CE);
1032                validEntityNames.put("nharr", 0x021AE);
1033                validEntityNames.put("nhpar", 0x02AF2);
1034                validEntityNames.put("nis", 0x022FC);
1035                validEntityNames.put("nisd", 0x022FA);
1036                validEntityNames.put("niv", 0x0220B);
1037                validEntityNames.put("njcy", 0x0045A);
1038                validEntityNames.put("nlArr", 0x021CD);
1039                validEntityNames.put("nlarr", 0x0219A);
1040                validEntityNames.put("nldr", 0x02025);
1041                validEntityNames.put("nle", 0x02270);
1042                validEntityNames.put("nlsim", 0x02274);
1043                validEntityNames.put("nlt", 0x0226E);
1044                validEntityNames.put("nltri", 0x022EA);
1045                validEntityNames.put("nltrie", 0x022EC);
1046                validEntityNames.put("nmid", 0x02224);
1047                validEntityNames.put("nopf", 0x1D55F);
1048                validEntityNames.put("not", 0x000AC);
1049                validEntityNames.put("notin", 0x02209);
1050                validEntityNames.put("notinvb", 0x022F7);
1051                validEntityNames.put("notinvc", 0x022F6);
1052                validEntityNames.put("notni", 0x0220C);
1053                validEntityNames.put("notnivb", 0x022FE);
1054                validEntityNames.put("notnivc", 0x022FD);
1055                validEntityNames.put("npar", 0x02226);
1056                validEntityNames.put("npolint", 0x02A14);
1057                validEntityNames.put("npr", 0x02280);
1058                validEntityNames.put("nprcue", 0x022E0);
1059                validEntityNames.put("nrArr", 0x021CF);
1060                validEntityNames.put("nrarr", 0x0219B);
1061                validEntityNames.put("nrtri", 0x022EB);
1062                validEntityNames.put("nrtrie", 0x022ED);
1063                validEntityNames.put("nsc", 0x02281);
1064                validEntityNames.put("nsccue", 0x022E1);
1065                validEntityNames.put("nscr", 0x1D4C3);
1066                validEntityNames.put("nsim", 0x02241);
1067                validEntityNames.put("nsime", 0x02244);
1068                validEntityNames.put("nsqsube", 0x022E2);
1069                validEntityNames.put("nsqsupe", 0x022E3);
1070                validEntityNames.put("nsub", 0x02284);
1071                validEntityNames.put("nsube", 0x02288);
1072                validEntityNames.put("nsup", 0x02285);
1073                validEntityNames.put("nsupe", 0x02289);
1074                validEntityNames.put("ntgl", 0x02279);
1075                validEntityNames.put("ntilde", 0x000F1);
1076                validEntityNames.put("ntlg", 0x02278);
1077                validEntityNames.put("nu", 0x003BD);
1078                validEntityNames.put("num", 0x00023);
1079                validEntityNames.put("numero", 0x02116);
1080                validEntityNames.put("numsp", 0x02007);
1081                validEntityNames.put("nvDash", 0x022AD);
1082                validEntityNames.put("nvHarr", 0x02904);
1083                validEntityNames.put("nvdash", 0x022AC);
1084                validEntityNames.put("nvinfin", 0x029DE);
1085                validEntityNames.put("nvlArr", 0x02902);
1086                validEntityNames.put("nvrArr", 0x02903);
1087                validEntityNames.put("nwArr", 0x021D6);
1088                validEntityNames.put("nwarhk", 0x02923);
1089                validEntityNames.put("nwarr", 0x02196);
1090                validEntityNames.put("nwnear", 0x02927);
1091                validEntityNames.put("oS", 0x024C8);
1092                validEntityNames.put("oacute", 0x000F3);
1093                validEntityNames.put("oast", 0x0229B);
1094                validEntityNames.put("ocir", 0x0229A);
1095                validEntityNames.put("ocirc", 0x000F4);
1096                validEntityNames.put("ocy", 0x0043E);
1097                validEntityNames.put("odash", 0x0229D);
1098                validEntityNames.put("odblac", 0x00151);
1099                validEntityNames.put("odiv", 0x02A38);
1100                validEntityNames.put("odot", 0x02299);
1101                validEntityNames.put("odsold", 0x029BC);
1102                validEntityNames.put("oelig", 0x00153);
1103                validEntityNames.put("ofcir", 0x029BF);
1104                validEntityNames.put("ofr", 0x1D52C);
1105                validEntityNames.put("ogon", 0x002DB);
1106                validEntityNames.put("ograve", 0x000F2);
1107                validEntityNames.put("ogt", 0x029C1);
1108                validEntityNames.put("ohbar", 0x029B5);
1109                validEntityNames.put("ohm", 0x02126);
1110                validEntityNames.put("olarr", 0x021BA);
1111                validEntityNames.put("olcir", 0x029BE);
1112                validEntityNames.put("olcross", 0x029BB);
1113                validEntityNames.put("oline", 0x0203E);
1114                validEntityNames.put("olt", 0x029C0);
1115                validEntityNames.put("omacr", 0x0014D);
1116                validEntityNames.put("omega", 0x003C9);
1117                validEntityNames.put("omicron", 0x003BF);
1118                validEntityNames.put("omid", 0x029B6);
1119                validEntityNames.put("ominus", 0x02296);
1120                validEntityNames.put("oopf", 0x1D560);
1121                validEntityNames.put("opar", 0x029B7);
1122                validEntityNames.put("operp", 0x029B9);
1123                validEntityNames.put("oplus", 0x02295);
1124                validEntityNames.put("or", 0x02228);
1125                validEntityNames.put("orarr", 0x021BB);
1126                validEntityNames.put("ord", 0x02A5D);
1127                validEntityNames.put("order", 0x02134);
1128                validEntityNames.put("ordf", 0x000AA);
1129                validEntityNames.put("ordm", 0x000BA);
1130                validEntityNames.put("origof", 0x022B6);
1131                validEntityNames.put("oror", 0x02A56);
1132                validEntityNames.put("orslope", 0x02A57);
1133                validEntityNames.put("orv", 0x02A5B);
1134                validEntityNames.put("oslash", 0x000F8);
1135                validEntityNames.put("osol", 0x02298);
1136                validEntityNames.put("otilde", 0x000F5);
1137                validEntityNames.put("otimes", 0x02297);
1138                validEntityNames.put("otimesas", 0x02A36);
1139                validEntityNames.put("ouml", 0x000F6);
1140                validEntityNames.put("ovbar", 0x0233D);
1141                validEntityNames.put("par", 0x02225);
1142                validEntityNames.put("para", 0x000B6);
1143                validEntityNames.put("parsim", 0x02AF3);
1144                validEntityNames.put("parsl", 0x02AFD);
1145                validEntityNames.put("part", 0x02202);
1146                validEntityNames.put("pcy", 0x0043F);
1147                validEntityNames.put("percnt", 0x00025);
1148                validEntityNames.put("period", 0x0002E);
1149                validEntityNames.put("permil", 0x02030);
1150                validEntityNames.put("pertenk", 0x02031);
1151                validEntityNames.put("pfr", 0x1D52D);
1152                validEntityNames.put("phi", 0x003C6);
1153                validEntityNames.put("phmmat", 0x02133);
1154                validEntityNames.put("phone", 0x0260E);
1155                validEntityNames.put("pi", 0x003C0);
1156                validEntityNames.put("piv", 0x003D6);
1157                validEntityNames.put("planck", 0x0210F);
1158                validEntityNames.put("planckh", 0x0210E);
1159                validEntityNames.put("plus", 0x0002B);
1160                validEntityNames.put("plusacir", 0x02A23);
1161                validEntityNames.put("plusb", 0x0229E);
1162                validEntityNames.put("pluscir", 0x02A22);
1163                validEntityNames.put("plusdo", 0x02214);
1164                validEntityNames.put("plusdu", 0x02A25);
1165                validEntityNames.put("pluse", 0x02A72);
1166                validEntityNames.put("plusmn", 0x000B1);
1167                validEntityNames.put("plussim", 0x02A26);
1168                validEntityNames.put("plustwo", 0x02A27);
1169                validEntityNames.put("pointint", 0x02A15);
1170                validEntityNames.put("popf", 0x1D561);
1171                validEntityNames.put("pound", 0x000A3);
1172                validEntityNames.put("pr", 0x0227A);
1173                validEntityNames.put("prE", 0x02AB3);
1174                validEntityNames.put("prap", 0x02AB7);
1175                validEntityNames.put("prcue", 0x0227C);
1176                validEntityNames.put("pre", 0x02AAF);
1177                validEntityNames.put("prime", 0x02032);
1178                validEntityNames.put("prnE", 0x02AB5);
1179                validEntityNames.put("prnap", 0x02AB9);
1180                validEntityNames.put("prnsim", 0x022E8);
1181                validEntityNames.put("prod", 0x0220F);
1182                validEntityNames.put("profalar", 0x0232E);
1183                validEntityNames.put("profline", 0x02312);
1184                validEntityNames.put("profsurf", 0x02313);
1185                validEntityNames.put("prop", 0x0221D);
1186                validEntityNames.put("prsim", 0x0227E);
1187                validEntityNames.put("prurel", 0x022B0);
1188                validEntityNames.put("pscr", 0x1D4C5);
1189                validEntityNames.put("psi", 0x003C8);
1190                validEntityNames.put("puncsp", 0x02008);
1191                validEntityNames.put("qfr", 0x1D52E);
1192                validEntityNames.put("qint", 0x02A0C);
1193                validEntityNames.put("qopf", 0x1D562);
1194                validEntityNames.put("qprime", 0x02057);
1195                validEntityNames.put("qscr", 0x1D4C6);
1196                validEntityNames.put("quaternions", 0x0210D);
1197                validEntityNames.put("quatint", 0x02A16);
1198                validEntityNames.put("quest", 0x0003F);
1199                validEntityNames.put("quot", 0x00022);
1200                validEntityNames.put("rAarr", 0x021DB);
1201                validEntityNames.put("rArr", 0x021D2);
1202                validEntityNames.put("rAtail", 0x0291C);
1203                validEntityNames.put("rBarr", 0x0290F);
1204                validEntityNames.put("rHar", 0x02964);
1205                validEntityNames.put("race", 0x029DA);
1206                validEntityNames.put("racute", 0x00155);
1207                validEntityNames.put("radic", 0x0221A);
1208                validEntityNames.put("raemptyv", 0x029B3);
1209                validEntityNames.put("rang", 0x027E9);
1210                validEntityNames.put("rangd", 0x02992);
1211                validEntityNames.put("range", 0x029A5);
1212                validEntityNames.put("raquo", 0x000BB);
1213                validEntityNames.put("rarr", 0x02192);
1214                validEntityNames.put("rarrap", 0x02975);
1215                validEntityNames.put("rarrb", 0x021E5);
1216                validEntityNames.put("rarrbfs", 0x02920);
1217                validEntityNames.put("rarrc", 0x02933);
1218                validEntityNames.put("rarrfs", 0x0291E);
1219                validEntityNames.put("rarrhk", 0x021AA);
1220                validEntityNames.put("rarrlp", 0x021AC);
1221                validEntityNames.put("rarrpl", 0x02945);
1222                validEntityNames.put("rarrsim", 0x02974);
1223                validEntityNames.put("rarrtl", 0x021A3);
1224                validEntityNames.put("rarrw", 0x0219D);
1225                validEntityNames.put("ratail", 0x0291A);
1226                validEntityNames.put("ratio", 0x02236);
1227                validEntityNames.put("rationals", 0x0211A);
1228                validEntityNames.put("rbarr", 0x0290D);
1229                validEntityNames.put("rbbrk", 0x02773);
1230                validEntityNames.put("rbrke", 0x0298C);
1231                validEntityNames.put("rbrksld", 0x0298E);
1232                validEntityNames.put("rbrkslu", 0x02990);
1233                validEntityNames.put("rcaron", 0x00159);
1234                validEntityNames.put("rcedil", 0x00157);
1235                validEntityNames.put("rceil", 0x02309);
1236                validEntityNames.put("rcub", 0x0007D);
1237                validEntityNames.put("rcy", 0x00440);
1238                validEntityNames.put("rdca", 0x02937);
1239                validEntityNames.put("rdldhar", 0x02969);
1240                validEntityNames.put("rdquo", 0x0201D);
1241                validEntityNames.put("rdsh", 0x021B3);
1242                validEntityNames.put("real", 0x0211C);
1243                validEntityNames.put("reals", 0x0211D);
1244                validEntityNames.put("rect", 0x025AD);
1245                validEntityNames.put("reg", 0x000AE);
1246                validEntityNames.put("rfisht", 0x0297D);
1247                validEntityNames.put("rfloor", 0x0230B);
1248                validEntityNames.put("rfr", 0x1D52F);
1249                validEntityNames.put("rhard", 0x021C1);
1250                validEntityNames.put("rharu", 0x021C0);
1251                validEntityNames.put("rharul", 0x0296C);
1252                validEntityNames.put("rho", 0x003C1);
1253                validEntityNames.put("rhov", 0x003F1);
1254                validEntityNames.put("ring", 0x002DA);
1255                validEntityNames.put("rlarr", 0x021C4);
1256                validEntityNames.put("rlhar", 0x021CC);
1257                validEntityNames.put("rlm", 0x0200F);
1258                validEntityNames.put("rmoust", 0x023B1);
1259                validEntityNames.put("rnmid", 0x02AEE);
1260                validEntityNames.put("roang", 0x027ED);
1261                validEntityNames.put("roarr", 0x021FE);
1262                validEntityNames.put("robrk", 0x027E7);
1263                validEntityNames.put("ropar", 0x02986);
1264                validEntityNames.put("ropf", 0x1D563);
1265                validEntityNames.put("roplus", 0x02A2E);
1266                validEntityNames.put("rotimes", 0x02A35);
1267                validEntityNames.put("rpar", 0x00029);
1268                validEntityNames.put("rpargt", 0x02994);
1269                validEntityNames.put("rppolint", 0x02A12);
1270                validEntityNames.put("rrarr", 0x021C9);
1271                validEntityNames.put("rsaquo", 0x0203A);
1272                validEntityNames.put("rscr", 0x1D4C7);
1273                validEntityNames.put("rsh", 0x021B1);
1274                validEntityNames.put("rsqb", 0x0005D);
1275                validEntityNames.put("rsquo", 0x02019);
1276                validEntityNames.put("rthree", 0x022CC);
1277                validEntityNames.put("rtimes", 0x022CA);
1278                validEntityNames.put("rtri", 0x025B9);
1279                validEntityNames.put("rtrie", 0x022B5);
1280                validEntityNames.put("rtrif", 0x025B8);
1281                validEntityNames.put("rtriltri", 0x029CE);
1282                validEntityNames.put("ruluhar", 0x02968);
1283                validEntityNames.put("rx", 0x0211E);
1284                validEntityNames.put("sacute", 0x0015B);
1285                validEntityNames.put("sc", 0x0227B);
1286                validEntityNames.put("scE", 0x02AB4);
1287                validEntityNames.put("scap", 0x02AB8);
1288                validEntityNames.put("scaron", 0x00161);
1289                validEntityNames.put("sccue", 0x0227D);
1290                validEntityNames.put("sce", 0x02AB0);
1291                validEntityNames.put("scedil", 0x0015F);
1292                validEntityNames.put("scirc", 0x0015D);
1293                validEntityNames.put("scnE", 0x02AB6);
1294                validEntityNames.put("scnap", 0x02ABA);
1295                validEntityNames.put("scnsim", 0x022E9);
1296                validEntityNames.put("scpolint", 0x02A13);
1297                validEntityNames.put("scsim", 0x0227F);
1298                validEntityNames.put("scy", 0x00441);
1299                validEntityNames.put("sdot", 0x022C5);
1300                validEntityNames.put("sdotb", 0x022A1);
1301                validEntityNames.put("sdote", 0x02A66);
1302                validEntityNames.put("seArr", 0x021D8);
1303                validEntityNames.put("searhk", 0x02925);
1304                validEntityNames.put("searr", 0x02198);
1305                validEntityNames.put("sect", 0x000A7);
1306                validEntityNames.put("semi", 0x0003B);
1307                validEntityNames.put("seswar", 0x02929);
1308                validEntityNames.put("setmn", 0x02216);
1309                validEntityNames.put("sext", 0x02736);
1310                validEntityNames.put("sfr", 0x1D530);
1311                validEntityNames.put("sharp", 0x0266F);
1312                validEntityNames.put("shchcy", 0x00449);
1313                validEntityNames.put("shcy", 0x00448);
1314                validEntityNames.put("shy", 0x000AD);
1315                validEntityNames.put("sigma", 0x003C3);
1316                validEntityNames.put("sigmav", 0x003C2);
1317                validEntityNames.put("sim", 0x0223C);
1318                validEntityNames.put("simdot", 0x02A6A);
1319                validEntityNames.put("sime", 0x02243);
1320                validEntityNames.put("simg", 0x02A9E);
1321                validEntityNames.put("simgE", 0x02AA0);
1322                validEntityNames.put("siml", 0x02A9D);
1323                validEntityNames.put("simlE", 0x02A9F);
1324                validEntityNames.put("simne", 0x02246);
1325                validEntityNames.put("simplus", 0x02A24);
1326                validEntityNames.put("simrarr", 0x02972);
1327                validEntityNames.put("smashp", 0x02A33);
1328                validEntityNames.put("smeparsl", 0x029E4);
1329                validEntityNames.put("smile", 0x02323);
1330                validEntityNames.put("smt", 0x02AAA);
1331                validEntityNames.put("smte", 0x02AAC);
1332                validEntityNames.put("softcy", 0x0044C);
1333                validEntityNames.put("sol", 0x0002F);
1334                validEntityNames.put("solb", 0x029C4);
1335                validEntityNames.put("solbar", 0x0233F);
1336                validEntityNames.put("sopf", 0x1D564);
1337                validEntityNames.put("spades", 0x02660);
1338                validEntityNames.put("sqcap", 0x02293);
1339                validEntityNames.put("sqcup", 0x02294);
1340                validEntityNames.put("sqsub", 0x0228F);
1341                validEntityNames.put("sqsube", 0x02291);
1342                validEntityNames.put("sqsup", 0x02290);
1343                validEntityNames.put("sqsupe", 0x02292);
1344                validEntityNames.put("squ", 0x025A1);
1345                validEntityNames.put("squf", 0x025AA);
1346                validEntityNames.put("sscr", 0x1D4C8);
1347                validEntityNames.put("sstarf", 0x022C6);
1348                validEntityNames.put("star", 0x02606);
1349                validEntityNames.put("starf", 0x02605);
1350                validEntityNames.put("straightphi", 0x003D5);
1351                validEntityNames.put("sub", 0x02282);
1352                validEntityNames.put("subE", 0x02AC5);
1353                validEntityNames.put("subdot", 0x02ABD);
1354                validEntityNames.put("sube", 0x02286);
1355                validEntityNames.put("subedot", 0x02AC3);
1356                validEntityNames.put("submult", 0x02AC1);
1357                validEntityNames.put("subnE", 0x02ACB);
1358                validEntityNames.put("subne", 0x0228A);
1359                validEntityNames.put("subplus", 0x02ABF);
1360                validEntityNames.put("subrarr", 0x02979);
1361                validEntityNames.put("subsim", 0x02AC7);
1362                validEntityNames.put("subsub", 0x02AD5);
1363                validEntityNames.put("subsup", 0x02AD3);
1364                validEntityNames.put("sum", 0x02211);
1365                validEntityNames.put("sung", 0x0266A);
1366                validEntityNames.put("sup", 0x02283);
1367                validEntityNames.put("sup1", 0x000B9);
1368                validEntityNames.put("sup2", 0x000B2);
1369                validEntityNames.put("sup3", 0x000B3);
1370                validEntityNames.put("supE", 0x02AC6);
1371                validEntityNames.put("supdot", 0x02ABE);
1372                validEntityNames.put("supdsub", 0x02AD8);
1373                validEntityNames.put("supe", 0x02287);
1374                validEntityNames.put("supedot", 0x02AC4);
1375                validEntityNames.put("suphsub", 0x02AD7);
1376                validEntityNames.put("suplarr", 0x0297B);
1377                validEntityNames.put("supmult", 0x02AC2);
1378                validEntityNames.put("supnE", 0x02ACC);
1379                validEntityNames.put("supne", 0x0228B);
1380                validEntityNames.put("supplus", 0x02AC0);
1381                validEntityNames.put("supsim", 0x02AC8);
1382                validEntityNames.put("supsub", 0x02AD4);
1383                validEntityNames.put("supsup", 0x02AD6);
1384                validEntityNames.put("swArr", 0x021D9);
1385                validEntityNames.put("swarhk", 0x02926);
1386                validEntityNames.put("swarr", 0x02199);
1387                validEntityNames.put("swnwar", 0x0292A);
1388                validEntityNames.put("szlig", 0x000DF);
1389                validEntityNames.put("target", 0x02316);
1390                validEntityNames.put("tau", 0x003C4);
1391                validEntityNames.put("tbrk", 0x023B4);
1392                validEntityNames.put("tcaron", 0x00165);
1393                validEntityNames.put("tcedil", 0x00163);
1394                validEntityNames.put("tcy", 0x00442);
1395                validEntityNames.put("tdot", 0x020DB);
1396                validEntityNames.put("telrec", 0x02315);
1397                validEntityNames.put("tfr", 0x1D531);
1398                validEntityNames.put("there4", 0x02234);
1399                validEntityNames.put("theta", 0x003B8);
1400                validEntityNames.put("thetav", 0x003D1);
1401                validEntityNames.put("thinsp", 0x02009);
1402                validEntityNames.put("thorn", 0x000FE);
1403                validEntityNames.put("tilde", 0x002DC);
1404                validEntityNames.put("times", 0x000D7);
1405                validEntityNames.put("timesb", 0x022A0);
1406                validEntityNames.put("timesbar", 0x02A31);
1407                validEntityNames.put("timesd", 0x02A30);
1408                validEntityNames.put("tint", 0x0222D);
1409                validEntityNames.put("top", 0x022A4);
1410                validEntityNames.put("topbot", 0x02336);
1411                validEntityNames.put("topcir", 0x02AF1);
1412                validEntityNames.put("topf", 0x1D565);
1413                validEntityNames.put("topfork", 0x02ADA);
1414                validEntityNames.put("tprime", 0x02034);
1415                validEntityNames.put("trade", 0x02122);
1416                validEntityNames.put("tridot", 0x025EC);
1417                validEntityNames.put("trie", 0x0225C);
1418                validEntityNames.put("triminus", 0x02A3A);
1419                validEntityNames.put("triplus", 0x02A39);
1420                validEntityNames.put("trisb", 0x029CD);
1421                validEntityNames.put("tritime", 0x02A3B);
1422                validEntityNames.put("trpezium", 0x023E2);
1423                validEntityNames.put("tscr", 0x1D4C9);
1424                validEntityNames.put("tscy", 0x00446);
1425                validEntityNames.put("tshcy", 0x0045B);
1426                validEntityNames.put("tstrok", 0x00167);
1427                validEntityNames.put("twixt", 0x0226C);
1428                validEntityNames.put("uArr", 0x021D1);
1429                validEntityNames.put("uHar", 0x02963);
1430                validEntityNames.put("uacute", 0x000FA);
1431                validEntityNames.put("uarr", 0x02191);
1432                validEntityNames.put("ubrcy", 0x0045E);
1433                validEntityNames.put("ubreve", 0x0016D);
1434                validEntityNames.put("ucirc", 0x000FB);
1435                validEntityNames.put("ucy", 0x00443);
1436                validEntityNames.put("udarr", 0x021C5);
1437                validEntityNames.put("udblac", 0x00171);
1438                validEntityNames.put("udhar", 0x0296E);
1439                validEntityNames.put("ufisht", 0x0297E);
1440                validEntityNames.put("ufr", 0x1D532);
1441                validEntityNames.put("ugrave", 0x000F9);
1442                validEntityNames.put("uharl", 0x021BF);
1443                validEntityNames.put("uharr", 0x021BE);
1444                validEntityNames.put("uhblk", 0x02580);
1445                validEntityNames.put("ulcorn", 0x0231C);
1446                validEntityNames.put("ulcrop", 0x0230F);
1447                validEntityNames.put("ultri", 0x025F8);
1448                validEntityNames.put("umacr", 0x0016B);
1449                validEntityNames.put("uogon", 0x00173);
1450                validEntityNames.put("uopf", 0x1D566);
1451                validEntityNames.put("uplus", 0x0228E);
1452                validEntityNames.put("upsi", 0x003C5);
1453                validEntityNames.put("urcorn", 0x0231D);
1454                validEntityNames.put("urcrop", 0x0230E);
1455                validEntityNames.put("uring", 0x0016F);
1456                validEntityNames.put("urtri", 0x025F9);
1457                validEntityNames.put("uscr", 0x1D4CA);
1458                validEntityNames.put("utdot", 0x022F0);
1459                validEntityNames.put("utilde", 0x00169);
1460                validEntityNames.put("utri", 0x025B5);
1461                validEntityNames.put("utrif", 0x025B4);
1462                validEntityNames.put("uuarr", 0x021C8);
1463                validEntityNames.put("uuml", 0x000FC);
1464                validEntityNames.put("uwangle", 0x029A7);
1465                validEntityNames.put("vArr", 0x021D5);
1466                validEntityNames.put("vBar", 0x02AE8);
1467                validEntityNames.put("vBarv", 0x02AE9);
1468                validEntityNames.put("vDash", 0x022A8);
1469                validEntityNames.put("vangrt", 0x0299C);
1470                validEntityNames.put("varr", 0x02195);
1471                validEntityNames.put("vcy", 0x00432);
1472                validEntityNames.put("vdash", 0x022A2);
1473                validEntityNames.put("veebar", 0x022BB);
1474                validEntityNames.put("veeeq", 0x0225A);
1475                validEntityNames.put("vellip", 0x022EE);
1476                validEntityNames.put("verbar", 0x0007C);
1477                validEntityNames.put("vfr", 0x1D533);
1478                validEntityNames.put("vltri", 0x022B2);
1479                validEntityNames.put("vopf", 0x1D567);
1480                validEntityNames.put("vrtri", 0x022B3);
1481                validEntityNames.put("vscr", 0x1D4CB);
1482                validEntityNames.put("vzigzag", 0x0299A);
1483                validEntityNames.put("wcirc", 0x00175);
1484                validEntityNames.put("wedbar", 0x02A5F);
1485                validEntityNames.put("wedgeq", 0x02259);
1486                validEntityNames.put("weierp", 0x02118);
1487                validEntityNames.put("wfr", 0x1D534);
1488                validEntityNames.put("wopf", 0x1D568);
1489                validEntityNames.put("wreath", 0x02240);
1490                validEntityNames.put("wscr", 0x1D4CC);
1491                validEntityNames.put("xcap", 0x022C2);
1492                validEntityNames.put("xcirc", 0x025EF);
1493                validEntityNames.put("xcup", 0x022C3);
1494                validEntityNames.put("xdtri", 0x025BD);
1495                validEntityNames.put("xfr", 0x1D535);
1496                validEntityNames.put("xhArr", 0x027FA);
1497                validEntityNames.put("xharr", 0x027F7);
1498                validEntityNames.put("xi", 0x003BE);
1499                validEntityNames.put("xlArr", 0x027F8);
1500                validEntityNames.put("xlarr", 0x027F5);
1501                validEntityNames.put("xmap", 0x027FC);
1502                validEntityNames.put("xnis", 0x022FB);
1503                validEntityNames.put("xodot", 0x02A00);
1504                validEntityNames.put("xopf", 0x1D569);
1505                validEntityNames.put("xoplus", 0x02A01);
1506                validEntityNames.put("xotime", 0x02A02);
1507                validEntityNames.put("xrArr", 0x027F9);
1508                validEntityNames.put("xrarr", 0x027F6);
1509                validEntityNames.put("xscr", 0x1D4CD);
1510                validEntityNames.put("xsqcup", 0x02A06);
1511                validEntityNames.put("xuplus", 0x02A04);
1512                validEntityNames.put("xutri", 0x025B3);
1513                validEntityNames.put("xvee", 0x022C1);
1514                validEntityNames.put("xwedge", 0x022C0);
1515                validEntityNames.put("yacute", 0x000FD);
1516                validEntityNames.put("yacy", 0x0044F);
1517                validEntityNames.put("ycirc", 0x00177);
1518                validEntityNames.put("ycy", 0x0044B);
1519                validEntityNames.put("yen", 0x000A5);
1520                validEntityNames.put("yfr", 0x1D536);
1521                validEntityNames.put("yicy", 0x00457);
1522                validEntityNames.put("yopf", 0x1D56A);
1523                validEntityNames.put("yscr", 0x1D4CE);
1524                validEntityNames.put("yucy", 0x0044E);
1525                validEntityNames.put("yuml", 0x000FF);
1526                validEntityNames.put("zacute", 0x0017A);
1527                validEntityNames.put("zcaron", 0x0017E);
1528                validEntityNames.put("zcy", 0x00437);
1529                validEntityNames.put("zdot", 0x0017C);
1530                validEntityNames.put("zeta", 0x003B6);
1531                validEntityNames.put("zfr", 0x1D537);
1532                validEntityNames.put("zhcy", 0x00436);
1533                validEntityNames.put("zigrarr", 0x021DD);
1534                validEntityNames.put("zopf", 0x1D56B);
1535                validEntityNames.put("zscr", 0x1D4CF);
1536                validEntityNames.put("zwj", 0x0200D);
1537                validEntityNames.put("zwnj", 0x0200C);
1538
1539                VALID_ENTITY_NAMES = Collections.unmodifiableMap(validEntityNames);
1540        }
1541
1542        /**
1543         * Non-instantiable
1544         */
1545        private XmlUtil() {}
1546
1547        private static final class ExtendedEntityReplacingXmlResolver implements XMLResolver {
1548                @Override
1549                public Object resolveEntity(String thePublicID, String theSystemID, String theBaseURI, String theNamespace) {
1550                        if (thePublicID == null && theSystemID == null) {
1551                                if (theNamespace != null && VALID_ENTITY_NAMES.containsKey(theNamespace)) {
1552                                        return new String(Character.toChars(VALID_ENTITY_NAMES.get(theNamespace)));
1553                                }
1554                        }
1555
1556                        return null;
1557                }
1558        }
1559
1560        public static class MyEscaper implements EscapingWriterFactory {
1561
1562                @Override
1563                public Writer createEscapingWriterFor(OutputStream theOut, String theEnc) throws UnsupportedEncodingException {
1564                        return createEscapingWriterFor(new OutputStreamWriter(theOut, theEnc), theEnc);
1565                }
1566
1567                @Override
1568                public Writer createEscapingWriterFor(final Writer theW, String theEnc) {
1569                        return new Writer() {
1570
1571                                @Override
1572                                public void close() throws IOException {
1573                                        theW.close();
1574                                }
1575
1576                                @Override
1577                                public void flush() throws IOException {
1578                                        theW.flush();
1579                                }
1580
1581                                @Override
1582                                public void write(char[] theCbuf, int theOff, int theLen) throws IOException {
1583                                        boolean hasEscapable = false;
1584                                        for (int i = 0; i < theLen && !hasEscapable; i++) {
1585                                                char nextChar = theCbuf[i + theOff];
1586                                                switch (nextChar) {
1587                                                        case '<':
1588                                                        case '>':
1589                                                        case '"':
1590                                                        case '&':
1591                                                                hasEscapable = true;
1592                                                                break;
1593                                                        default:
1594                                                                break;
1595                                                }
1596                                        }
1597
1598                                        if (!hasEscapable) {
1599                                                theW.write(theCbuf, theOff, theLen);
1600                                                return;
1601                                        }
1602
1603                                        String escaped = StringEscapeUtils.escapeXml10(new String(theCbuf, theOff, theLen));
1604                                        theW.write(escaped.toCharArray());
1605                                }
1606                        };
1607                }
1608        }
1609
1610        private static XMLOutputFactory createOutputFactory() throws FactoryConfigurationError {
1611                try {
1612                        // Detect if we're running with the Android lib, and force repackaged Woodstox to be used
1613                        Class.forName("ca.uhn.fhir.repackage.javax.xml.stream.XMLOutputFactory");
1614                        System.setProperty(
1615                                        javax.xml.stream.XMLOutputFactory.class.getName(),
1616                                        com.ctc.wstx.stax.WstxOutputFactory.class.getName());
1617                } catch (ClassNotFoundException e) {
1618                        // ok
1619                }
1620
1621                XMLOutputFactory outputFactory = newOutputFactory();
1622
1623                if (!ourHaveLoggedStaxImplementation) {
1624                        logStaxImplementation(outputFactory.getClass());
1625                }
1626
1627                /*
1628                 * Note that these properties are Woodstox specific and they cause a crash in environments where SJSXP is
1629                 * being used (e.g. glassfish) so we don't set them there.
1630                 */
1631                try {
1632                        Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
1633                        if (outputFactory instanceof WstxOutputFactory) {
1634                                //                              ((WstxOutputFactory)outputFactory).getConfig().setAttrValueEscaperFactory(new MyEscaper());
1635                                outputFactory.setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, new MyEscaper());
1636                        }
1637                } catch (ClassNotFoundException e) {
1638                        ourLog.debug("WstxOutputFactory (Woodstox) not found on classpath");
1639                }
1640                return outputFactory;
1641        }
1642
1643        private static XMLEventWriter createXmlFragmentWriter(Writer theWriter)
1644                        throws FactoryConfigurationError, XMLStreamException {
1645                XMLOutputFactory outputFactory = getOrCreateFragmentOutputFactory();
1646                return outputFactory.createXMLEventWriter(theWriter);
1647        }
1648
1649        public static XMLEventReader createXmlReader(Reader reader) throws FactoryConfigurationError, XMLStreamException {
1650                throwUnitTestExceptionIfConfiguredToDoSo();
1651
1652                XMLInputFactory inputFactory = getOrCreateInputFactory();
1653
1654                // Now.. create the reader and return it
1655                return inputFactory.createXMLEventReader(reader);
1656        }
1657
1658        public static XMLStreamWriter createXmlStreamWriter(Writer theWriter)
1659                        throws FactoryConfigurationError, XMLStreamException {
1660                throwUnitTestExceptionIfConfiguredToDoSo();
1661
1662                XMLOutputFactory outputFactory = getOrCreateOutputFactory();
1663                return outputFactory.createXMLStreamWriter(theWriter);
1664        }
1665
1666        public static XMLEventWriter createXmlWriter(Writer theWriter)
1667                        throws FactoryConfigurationError, XMLStreamException {
1668                XMLOutputFactory outputFactory = getOrCreateOutputFactory();
1669                return outputFactory.createXMLEventWriter(theWriter);
1670        }
1671
1672        /**
1673         * Encode a set of StAX events into a String
1674         */
1675        public static String encode(List<XMLEvent> theEvents) {
1676                try {
1677                        StringWriter w = new StringWriter();
1678                        XMLEventWriter ew = XmlUtil.createXmlFragmentWriter(w);
1679
1680                        for (XMLEvent next : theEvents) {
1681                                if (next.isCharacters()) {
1682                                        ew.add(next);
1683                                } else {
1684                                        ew.add(next);
1685                                }
1686                        }
1687                        ew.close();
1688                        return w.toString();
1689                } catch (XMLStreamException e) {
1690                        throw new DataFormatException(Msg.code(1751) + "Problem with the contained XML events", e);
1691                } catch (FactoryConfigurationError e) {
1692                        throw new ConfigurationException(Msg.code(1752) + e);
1693                }
1694        }
1695
1696        private static XMLOutputFactory getOrCreateFragmentOutputFactory() throws FactoryConfigurationError {
1697                XMLOutputFactory retVal = ourFragmentOutputFactory;
1698                if (retVal == null) {
1699                        retVal = createOutputFactory();
1700                        retVal.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
1701                        ourFragmentOutputFactory = retVal;
1702                        return retVal;
1703                }
1704                return retVal;
1705        }
1706
1707        private static XMLInputFactory getOrCreateInputFactory() throws FactoryConfigurationError {
1708                if (ourInputFactory == null) {
1709
1710                        try {
1711                                // Detect if we're running with the Android lib, and force repackaged Woodstox to be used
1712                                Class.forName("ca.uhn.fhir.repackage.javax.xml.stream.XMLInputFactory");
1713                                System.setProperty(
1714                                                javax.xml.stream.XMLInputFactory.class.getName(),
1715                                                com.ctc.wstx.stax.WstxInputFactory.class.getName());
1716                        } catch (ClassNotFoundException e) {
1717                                // ok
1718                        }
1719
1720                        XMLInputFactory inputFactory = newInputFactory();
1721
1722                        if (!ourHaveLoggedStaxImplementation) {
1723                                logStaxImplementation(inputFactory.getClass());
1724                        }
1725
1726                        /*
1727                         * These two properties disable external entity processing, which can
1728                         * be a security vulnerability.
1729                         *
1730                         * See https://github.com/hapifhir/hapi-fhir/issues/339
1731                         * https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing
1732                         */
1733                        inputFactory.setProperty(
1734                                        XMLInputFactory.SUPPORT_DTD, false); // This disables DTDs entirely for that factory
1735                        inputFactory.setProperty(
1736                                        "javax.xml.stream.isSupportingExternalEntities", false); // disable external entities
1737
1738                        /*
1739                         * In the following few lines, you can uncomment the first and comment the second to disable automatic
1740                         * parsing of extended entities, e.g. &sect;
1741                         *
1742                         * Note that these properties are Woodstox specific and they cause a crash in environments where SJSXP is
1743                         * being used (e.g. glassfish) so we don't set them there.
1744                         */
1745                        try {
1746                                Class.forName("com.ctc.wstx.stax.WstxInputFactory");
1747                                boolean isWoodstox = inputFactory instanceof com.ctc.wstx.stax.WstxInputFactory;
1748                                if (!isWoodstox) {
1749                                        // Check if implementation is woodstox by property since instanceof check does not work if running
1750                                        // in JBoss
1751                                        try {
1752                                                isWoodstox = inputFactory.getProperty("org.codehaus.stax2.implVersion") != null;
1753                                        } catch (Exception e) {
1754                                                // ignore
1755                                        }
1756                                }
1757                                if (isWoodstox) {
1758                                        // inputFactory.setProperty(WstxInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
1759                                        inputFactory.setProperty(WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER, XML_RESOLVER);
1760                                        try {
1761                                                inputFactory.setProperty(WstxInputProperties.P_MAX_ATTRIBUTE_SIZE, "100000000");
1762                                        } catch (IllegalArgumentException e) {
1763                                                // ignore
1764                                        }
1765                                }
1766                        } catch (ClassNotFoundException e) {
1767                                ourLog.debug("WstxOutputFactory (Woodstox) not found on classpath");
1768                        }
1769                        ourInputFactory = inputFactory;
1770                }
1771                return ourInputFactory;
1772        }
1773
1774        private static XMLOutputFactory getOrCreateOutputFactory() throws FactoryConfigurationError {
1775                if (ourOutputFactory == null) {
1776                        ourOutputFactory = createOutputFactory();
1777                }
1778                return ourOutputFactory;
1779        }
1780
1781        private static void logStaxImplementation(Class<?> theClass) {
1782                IDependencyLog logger = DependencyLogFactory.createJarLogger();
1783                if (logger != null) {
1784                        logger.logStaxImplementation(theClass);
1785                }
1786                ourHaveLoggedStaxImplementation = true;
1787        }
1788
1789        static XMLInputFactory newInputFactory() throws FactoryConfigurationError {
1790                XMLInputFactory inputFactory;
1791                try {
1792                        inputFactory = XMLInputFactory.newInstance();
1793                        if (inputFactory.isPropertySupported(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES)) {
1794                                inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
1795                        }
1796                        throwUnitTestExceptionIfConfiguredToDoSo();
1797                } catch (Throwable e) {
1798                        throw new ConfigurationException(
1799                                        Msg.code(1753) + "Unable to initialize StAX - XML processing is disabled", e);
1800                }
1801                return inputFactory;
1802        }
1803
1804        static XMLOutputFactory newOutputFactory() throws FactoryConfigurationError {
1805                XMLOutputFactory outputFactory;
1806                try {
1807                        outputFactory = XMLOutputFactory.newInstance();
1808                        throwUnitTestExceptionIfConfiguredToDoSo();
1809                } catch (Throwable e) {
1810                        throw new ConfigurationException(
1811                                        Msg.code(1754) + "Unable to initialize StAX - XML processing is disabled", e);
1812                }
1813                return outputFactory;
1814        }
1815
1816        /**
1817         * Parses an XML string into a set of StAX events
1818         */
1819        public static List<XMLEvent> parse(String theValue) {
1820                if (isBlank(theValue)) {
1821                        return Collections.emptyList();
1822                }
1823
1824                String val = theValue.trim();
1825                if (!val.startsWith("<")) {
1826                        val = XhtmlDt.DIV_OPEN_FIRST + val + "</div>";
1827                }
1828                boolean hasProcessingInstruction = val.startsWith("<?");
1829                if (hasProcessingInstruction && val.endsWith("?>")) {
1830                        return null;
1831                }
1832
1833                try {
1834                        ArrayList<XMLEvent> value = new ArrayList<>();
1835                        StringReader reader = new StringReader(val);
1836                        XMLEventReader er = XmlUtil.createXmlReader(reader);
1837                        boolean first = true;
1838                        while (er.hasNext()) {
1839                                XMLEvent next = er.nextEvent();
1840                                if (first) {
1841                                        first = false;
1842                                        continue;
1843                                }
1844                                if (er.hasNext()) {
1845                                        // don't add the last event
1846                                        value.add(next);
1847                                }
1848                        }
1849                        return value;
1850
1851                } catch (XMLStreamException e) {
1852                        throw new DataFormatException(
1853                                        Msg.code(1755) + "String does not appear to be valid XML/XHTML (error is \"" + e.getMessage()
1854                                                        + "\"): " + theValue,
1855                                        e);
1856                } catch (FactoryConfigurationError e) {
1857                        throw new ConfigurationException(Msg.code(1756) + e);
1858                }
1859        }
1860
1861        /**
1862         * FOR UNIT TESTS ONLY - Throw this exception for the next operation
1863         */
1864        static void setThrowExceptionForUnitTest(Throwable theException) {
1865                ourNextException = theException;
1866        }
1867
1868        private static void throwUnitTestExceptionIfConfiguredToDoSo()
1869                        throws FactoryConfigurationError, XMLStreamException {
1870                if (ourNextException != null) {
1871                        if (ourNextException instanceof javax.xml.stream.FactoryConfigurationError) {
1872                                throw ((javax.xml.stream.FactoryConfigurationError) ourNextException);
1873                        }
1874                        throw (XMLStreamException) ourNextException;
1875                }
1876        }
1877
1878        public static Document parseDocument(String theInput) throws IOException, SAXException {
1879                StringReader reader = new StringReader(theInput);
1880                return parseDocument(reader);
1881        }
1882
1883        public static Document parseDocument(Reader reader) throws SAXException, IOException {
1884                return parseDocument(reader, true, false);
1885        }
1886
1887        public static Document parseDocument(Reader theReader, boolean theNamespaceAware, boolean allowDoctypeDeclaration)
1888                        throws SAXException, IOException {
1889                DocumentBuilder builder;
1890                try {
1891                        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
1892                        docBuilderFactory.setNamespaceAware(theNamespaceAware);
1893                        docBuilderFactory.setXIncludeAware(false);
1894                        docBuilderFactory.setExpandEntityReferences(false);
1895                        try {
1896                                docBuilderFactory.setFeature(
1897                                                "http://apache.org/xml/features/disallow-doctype-decl", !allowDoctypeDeclaration);
1898                                docBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
1899                                docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
1900                                docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
1901                                docBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
1902                                throwUnitTestExceptionIfConfiguredToDoSo();
1903                        } catch (Exception e) {
1904                                ourLog.warn("Failed to set feature on XML parser: " + e.toString());
1905                        }
1906
1907                        builder = docBuilderFactory.newDocumentBuilder();
1908                } catch (ParserConfigurationException e) {
1909                        throw new ConfigurationException(Msg.code(1757) + e);
1910                }
1911
1912                InputSource src = new InputSource(theReader);
1913                return builder.parse(src);
1914        }
1915
1916        public static List<Element> getChildrenByTagName(Element theParent, String theName) {
1917                List<Element> nodeList = new ArrayList<Element>();
1918                for (Node child = theParent.getFirstChild(); child != null; child = child.getNextSibling()) {
1919                        if (child.getNodeType() == Node.ELEMENT_NODE && theName.equals(child.getNodeName())) {
1920                                nodeList.add((Element) child);
1921                        }
1922                }
1923
1924                return nodeList;
1925        }
1926
1927        public static String encodeDocument(Node theElement) throws TransformerException {
1928                return encodeDocument(theElement, false);
1929        }
1930
1931        public static String encodeDocument(Node theElement, boolean theIndent) throws TransformerException {
1932                TransformerFactory transFactory = TransformerFactory.newInstance();
1933                Transformer transformer = transFactory.newTransformer();
1934                StringWriter buffer = new StringWriter();
1935                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
1936                if (theIndent) {
1937                        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
1938                }
1939                transformer.transform(new DOMSource(theElement), new StreamResult(buffer));
1940                return buffer.toString();
1941        }
1942
1943        /**
1944         * FOR UNIT TESTS ONLY - Used to reset OutputFactory for test cases that customize OutputFactory
1945         */
1946        public static void resetOutputFactoryForTest() {
1947                ourOutputFactory = null;
1948        }
1949}