package com.codeim.youliao.http;

import java.util.HashMap;
import java.util.Map;

public class HTMLEntity {
	public static String escape(String original) {
		StringBuffer buf = new StringBuffer(original);
		escape(buf);
		return buf.toString();
	}

	public static void escape(StringBuffer original) {
		int index = 0;
		String escaped;
		while (index < original.length()) {
			escaped = entityEscapeMap.get(original.substring(index, index + 1));
			if (null != escaped) {
				original.replace(index, index + 1, escaped);
				index += escaped.length();
			} else {
				index++;
			}
		}
	}

	public static String unescape(String original) {
		StringBuffer buf = new StringBuffer(original);
		unescape(buf);
		return buf.toString();
	}

	public static void unescape(StringBuffer original) {
		int index = 0;
		int semicolonIndex = 0;
		String escaped;
		String entity;
		while (index < original.length()) {
			index = original.indexOf("&", index);
			if (-1 == index) {
				break;
			}
			semicolonIndex = original.indexOf(";", index);
			if (-1 != semicolonIndex && 10 > (semicolonIndex - index)) {
				escaped = original.substring(index, semicolonIndex + 1);
				entity = escapeEntityMap.get(escaped);
				if (null != entity) {
					original.replace(index, semicolonIndex + 1, entity);
				}
				index++;
			} else {
				break;
			}
		}
	}

	private static Map<String, String> entityEscapeMap = new HashMap<String, String>();
	private static Map<String, String> escapeEntityMap = new HashMap<String, String>();

	static {
		String[][] entities = {
				{ "&nbsp;", "&#160;"/* no-break space = non-breaking space */,
						"\u00A0" },
				{ "&iexcl;", "&#161;"/* inverted exclamation mark */, "\u00A1" },
				{ "&cent;", "&#162;"/* cent sign */, "\u00A2" },
				{ "&pound;", "&#163;"/* pound sign */, "\u00A3" },
				{ "&curren;", "&#164;"/* currency sign */, "\u00A4" },
				{ "&yen;", "&#165;"/* yen sign = yuan sign */, "\u00A5" },
				{ "&brvbar;", "&#166;"/* broken bar = broken vertical bar */,
						"\u00A6" },
				{ "&sect;", "&#167;"/* section sign */, "\u00A7" },
				{ "&uml;", "&#168;"/* diaeresis = spacing diaeresis */,
						"\u00A8" },
				{ "&copy;", "&#169;"/* copyright sign */, "\u00A9" },
				{ "&ordf;", "&#170;"/* feminine ordinal indicator */, "\u00AA" },
				{ "&laquo;", "&#171;"/*
									 * left-pointing double angle quotation mark
									 * = left pointing guillemet
									 */, "\u00AB" },
				{ "&not;", "&#172;"/* not sign = discretionary hyphen */,
						"\u00AC" },
				{ "&shy;", "&#173;"/* soft hyphen = discretionary hyphen */,
						"\u00AD" },
				{ "&reg;", "&#174;"/*
									 * registered sign = registered trade mark
									 * sign
									 */, "\u00AE" },
				{ "&macr;", "&#175;"/*
									 * macron = spacing macron = overline = APL
									 * overbar
									 */, "\u00AF" },
				{ "&deg;", "&#176;"/* degree sign */, "\u00B0" },
				{ "&plusmn;", "&#177;"/* plus-minus sign = plus-or-minus sign */,
						"\u00B1" },
				{ "&sup2;", "&#178;"/*
									 * superscript two = superscript digit two =
									 * squared
									 */, "\u00B2" },
				{ "&sup3;", "&#179;"/*
									 * superscript three = superscript digit
									 * three = cubed
									 */, "\u00B3" },
				{ "&acute;", "&#180;"/* acute accent = spacing acute */,
						"\u00B4" },
				{ "&micro;", "&#181;"/* micro sign */, "\u00B5" },
				{ "&para;", "&#182;"/* pilcrow sign = paragraph sign */,
						"\u00B6" },
				{ "&middot;", "&#183;"/*
									 * middle dot = Georgian comma = Greek
									 * middle dot
									 */, "\u00B7" },
				{ "&cedil;", "&#184;"/* cedilla = spacing cedilla */, "\u00B8" },
				{ "&sup1;",
						"&#185;"/* superscript one = superscript digit one */,
						"\u00B9" },
				{ "&ordm;", "&#186;"/* masculine ordinal indicator */, "\u00BA" },
				{ "&raquo;", "&#187;"/*
									 * right-pointing double angle quotation
									 * mark = right pointing guillemet
									 */, "\u00BB" },
				{ "&frac14;", "&#188;"/*
									 * vulgar fraction one quarter = fraction
									 * one quarter
									 */, "\u00BC" },
				{ "&frac12;", "&#189;"/*
									 * vulgar fraction one half = fraction one
									 * half
									 */, "\u00BD" },
				{ "&frac34;", "&#190;"/*
									 * vulgar fraction three quarters = fraction
									 * three quarters
									 */, "\u00BE" },
				{ "&iquest;", "&#191;"/*
									 * inverted question mark = turned question
									 * mark
									 */, "\u00BF" },
				{ "&Agrave;", "&#192;"/*
									 * latin capital letter A with grave = latin
									 * capital letter A grave
									 */, "\u00C0" },
				{ "&Aacute;", "&#193;"/* latin capital letter A with acute */,
						"\u00C1" },
				{ "&Acirc;",
						"&#194;"/* latin capital letter A with circumflex */,
						"\u00C2" },
				{ "&Atilde;", "&#195;"/* latin capital letter A with tilde */,
						"\u00C3" },
				{ "&Auml;",
						"&#196;"/* latin capital letter A with diaeresis */,
						"\u00C4" },
				{ "&Aring;", "&#197;"/*
									 * latin capital letter A with ring above =
									 * latin capital letter A ring
									 */, "\u00C5" },
				{ "&AElig;", "&#198;"/*
									 * latin capital letter AE = latin capital
									 * ligature AE
									 */, "\u00C6" },
				{ "&Ccedil;", "&#199;"/* latin capital letter C with cedilla */,
						"\u00C7" },
				{ "&Egrave;", "&#200;"/* latin capital letter E with grave */,
						"\u00C8" },
				{ "&Eacute;", "&#201;"/* latin capital letter E with acute */,
						"\u00C9" },
				{ "&Ecirc;",
						"&#202;"/* latin capital letter E with circumflex */,
						"\u00CA" },
				{ "&Euml;",
						"&#203;"/* latin capital letter E with diaeresis */,
						"\u00CB" },
				{ "&Igrave;", "&#204;"/* latin capital letter I with grave */,
						"\u00CC" },
				{ "&Iacute;", "&#205;"/* latin capital letter I with acute */,
						"\u00CD" },
				{ "&Icirc;",
						"&#206;"/* latin capital letter I with circumflex */,
						"\u00CE" },
				{ "&Iuml;",
						"&#207;"/* latin capital letter I with diaeresis */,
						"\u00CF" },
				{ "&ETH;", "&#208;"/* latin capital letter ETH */, "\u00D0" },
				{ "&Ntilde;", "&#209;"/* latin capital letter N with tilde */,
						"\u00D1" },
				{ "&Ograve;", "&#210;"/* latin capital letter O with grave */,
						"\u00D2" },
				{ "&Oacute;", "&#211;"/* latin capital letter O with acute */,
						"\u00D3" },
				{ "&Ocirc;",
						"&#212;"/* latin capital letter O with circumflex */,
						"\u00D4" },
				{ "&Otilde;", "&#213;"/* latin capital letter O with tilde */,
						"\u00D5" },
				{ "&Ouml;",
						"&#214;"/* latin capital letter O with diaeresis */,
						"\u00D6" },
				{ "&times;", "&#215;"/* multiplication sign */, "\u00D7" },
				{ "&Oslash;", "&#216;"/*
									 * latin capital letter O with stroke =
									 * latin capital letter O slash
									 */, "\u00D8" },
				{ "&Ugrave;", "&#217;"/* latin capital letter U with grave */,
						"\u00D9" },
				{ "&Uacute;", "&#218;"/* latin capital letter U with acute */,
						"\u00DA" },
				{ "&Ucirc;",
						"&#219;"/* latin capital letter U with circumflex */,
						"\u00DB" },
				{ "&Uuml;",
						"&#220;"/* latin capital letter U with diaeresis */,
						"\u00DC" },
				{ "&Yacute;", "&#221;"/* latin capital letter Y with acute */,
						"\u00DD" },
				{ "&THORN;", "&#222;"/* latin capital letter THORN */, "\u00DE" },
				{ "&szlig;", "&#223;"/* latin small letter sharp s = ess-zed */,
						"\u00DF" },
				{ "&agrave;", "&#224;"/*
									 * latin small letter a with grave = latin
									 * small letter a grave
									 */, "\u00E0" },
				{ "&aacute;", "&#225;"/* latin small letter a with acute */,
						"\u00E1" },
				{ "&acirc;", "&#226;"/* latin small letter a with circumflex */,
						"\u00E2" },
				{ "&atilde;", "&#227;"/* latin small letter a with tilde */,
						"\u00E3" },
				{ "&auml;", "&#228;"/* latin small letter a with diaeresis */,
						"\u00E4" },
				{ "&aring;", "&#229;"/*
									 * latin small letter a with ring above =
									 * latin small letter a ring
									 */, "\u00E5" },
				{ "&aelig;", "&#230;"/*
									 * latin small letter ae = latin small
									 * ligature ae
									 */, "\u00E6" },
				{ "&ccedil;", "&#231;"/* latin small letter c with cedilla */,
						"\u00E7" },
				{ "&egrave;", "&#232;"/* latin small letter e with grave */,
						"\u00E8" },
				{ "&eacute;", "&#233;"/* latin small letter e with acute */,
						"\u00E9" },
				{ "&ecirc;", "&#234;"/* latin small letter e with circumflex */,
						"\u00EA" },
				{ "&euml;", "&#235;"/* latin small letter e with diaeresis */,
						"\u00EB" },
				{ "&igrave;", "&#236;"/* latin small letter i with grave */,
						"\u00EC" },
				{ "&iacute;", "&#237;"/* latin small letter i with acute */,
						"\u00ED" },
				{ "&icirc;", "&#238;"/* latin small letter i with circumflex */,
						"\u00EE" },
				{ "&iuml;", "&#239;"/* latin small letter i with diaeresis */,
						"\u00EF" },
				{ "&eth;", "&#240;"/* latin small letter eth */, "\u00F0" },
				{ "&ntilde;", "&#241;"/* latin small letter n with tilde */,
						"\u00F1" },
				{ "&ograve;", "&#242;"/* latin small letter o with grave */,
						"\u00F2" },
				{ "&oacute;", "&#243;"/* latin small letter o with acute */,
						"\u00F3" },
				{ "&ocirc;", "&#244;"/* latin small letter o with circumflex */,
						"\u00F4" },
				{ "&otilde;", "&#245;"/* latin small letter o with tilde */,
						"\u00F5" },
				{ "&ouml;", "&#246;"/* latin small letter o with diaeresis */,
						"\u00F6" },
				{ "&divide;", "&#247;"/* division sign */, "\u00F7" },
				{ "&oslash;", "&#248;"/*
									 * latin small letter o with stroke = latin
									 * small letter o slash
									 */, "\u00F8" },
				{ "&ugrave;", "&#249;"/* latin small letter u with grave */,
						"\u00F9" },
				{ "&uacute;", "&#250;"/* latin small letter u with acute */,
						"\u00FA" },
				{ "&ucirc;", "&#251;"/* latin small letter u with circumflex */,
						"\u00FB" },
				{ "&uuml;", "&#252;"/* latin small letter u with diaeresis */,
						"\u00FC" },
				{ "&yacute;", "&#253;"/* latin small letter y with acute */,
						"\u00FD" },
				{ "&thorn;", "&#254;"/* latin small letter thorn with */,
						"\u00FE" },
				{ "&yuml;", "&#255;"/* latin small letter y with diaeresis */,
						"\u00FF" },
				{ "&fnof;", "&#402;"/*
									 * latin small f with hook = function =
									 * florin
									 */, "\u0192" }
				/* Greek */
				,
				{ "&Alpha;", "&#913;"/* greek capital letter alpha */, "\u0391" },
				{ "&Beta;", "&#914;"/* greek capital letter beta */, "\u0392" },
				{ "&Gamma;", "&#915;"/* greek capital letter gamma */, "\u0393" },
				{ "&Delta;", "&#916;"/* greek capital letter delta */, "\u0394" },
				{ "&Epsilon;", "&#917;"/* greek capital letter epsilon */,
						"\u0395" },
				{ "&Zeta;", "&#918;"/* greek capital letter zeta */, "\u0396" },
				{ "&Eta;", "&#919;"/* greek capital letter eta */, "\u0397" },
				{ "&Theta;", "&#920;"/* greek capital letter theta */, "\u0398" },
				{ "&Iota;", "&#921;"/* greek capital letter iota */, "\u0399" },
				{ "&Kappa;", "&#922;"/* greek capital letter kappa */, "\u039A" },
				{ "&Lambda;", "&#923;"/* greek capital letter lambda */, "\u039B" },
				{ "&Mu;", "&#924;"/* greek capital letter mu */, "\u039C" },
				{ "&Nu;", "&#925;"/* greek capital letter nu */, "\u039D" },
				{ "&Xi;", "&#926;"/* greek capital letter xi */, "\u039E" },
				{ "&Omicron;", "&#927;"/* greek capital letter omicron */,
						"\u039F" },
				{ "&Pi;", "&#928;"/* greek capital letter pi */, "\u03A0" },
				{ "&Rho;", "&#929;"/* greek capital letter rho */, "\u03A1" }
				/* there is no Sigmaf and no \u03A2 */
				,
				{ "&Sigma;", "&#931;"/* greek capital letter sigma */, "\u03A3" },
				{ "&Tau;", "&#932;"/* greek capital letter tau */, "\u03A4" },
				{ "&Upsilon;", "&#933;"/* greek capital letter upsilon */,
						"\u03A5" },
				{ "&Phi;", "&#934;"/* greek capital letter phi */, "\u03A6" },
				{ "&Chi;", "&#935;"/* greek capital letter chi */, "\u03A7" },
				{ "&Psi;", "&#936;"/* greek capital letter psi */, "\u03A8" },
				{ "&Omega;", "&#937;"/* greek capital letter omega */, "\u03A9" },
				{ "&alpha;", "&#945;"/* greek small letter alpha */, "\u03B1" },
				{ "&beta;", "&#946;"/* greek small letter beta */, "\u03B2" },
				{ "&gamma;", "&#947;"/* greek small letter gamma */, "\u03B3" },
				{ "&delta;", "&#948;"/* greek small letter delta */, "\u03B4" },
				{ "&epsilon;", "&#949;"/* greek small letter epsilon */,
						"\u03B5" },
				{ "&zeta;", "&#950;"/* greek small letter zeta */, "\u03B6" },
				{ "&eta;", "&#951;"/* greek small letter eta */, "\u03B7" },
				{ "&theta;", "&#952;"/* greek small letter theta */, "\u03B8" },
				{ "&iota;", "&#953;"/* greek small letter iota */, "\u03B9" },
				{ "&kappa;", "&#954;"/* greek small letter kappa */, "\u03BA" },
				{ "&lambda;", "&#955;"/* greek small letter lambda */, "\u03BB" },
				{ "&mu;", "&#956;"/* greek small letter mu */, "\u03BC" },
				{ "&nu;", "&#957;"/* greek small letter nu */, "\u03BD" },
				{ "&xi;", "&#958;"/* greek small letter xi */, "\u03BE" },
				{ "&omicron;", "&#959;"/* greek small letter omicron */,
						"\u03BF" },
				{ "&pi;", "&#960;"/* greek small letter pi */, "\u03C0" },
				{ "&rho;", "&#961;"/* greek small letter rho */, "\u03C1" },
				{ "&sigmaf;", "&#962;"/* greek small letter final sigma */,
						"\u03C2" },
				{ "&sigma;", "&#963;"/* greek small letter sigma */, "\u03C3" },
				{ "&tau;", "&#964;"/* greek small letter tau */, "\u03C4" },
				{ "&upsilon;", "&#965;"/* greek small letter upsilon */,
						"\u03C5" },
				{ "&phi;", "&#966;"/* greek small letter phi */, "\u03C6" },
				{ "&chi;", "&#967;"/* greek small letter chi */, "\u03C7" },
				{ "&psi;", "&#968;"/* greek small letter psi */, "\u03C8" },
				{ "&omega;", "&#969;"/* greek small letter omega */, "\u03C9" },
				{ "&thetasym;", "&#977;"/* greek small letter theta symbol */,
						"\u03D1" },
				{ "&upsih;", "&#978;"/* greek upsilon with hook symbol */,
						"\u03D2" },
				{ "&piv;", "&#982;"/* greek pi symbol */, "\u03D6" }
				/* General Punctuation */
				,
				{ "&bull;", "&#8226;"/* bullet = black small circle */, "\u2022" }
				/* bullet is NOT the same as bullet operator ,"\u2219 */
				,
				{ "&hellip;", "&#8230;"/*
										 * horizontal ellipsis = three dot
										 * leader
										 */, "\u2026" },
				{ "&prime;", "&#8242;"/* prime = minutes = feet */, "\u2032" },
				{ "&Prime;", "&#8243;"/* double prime = seconds = inches */,
						"\u2033" },
				{ "&oline;", "&#8254;"/* overline = spacing overscore */,
						"\u203E" },
				{ "&frasl;", "&#8260;"/* fraction slash */, "\u2044" }
				/* Letterlike Symbols */
				,
				{ "&weierp;", "&#8472;"/*
										 * script capital P = power set =
										 * Weierstrass p
										 */, "\u2118" },
				{ "&image;",
						"&#8465;"/* blackletter capital I = imaginary part */,
						"\u2111" },
				{ "&real;",
						"&#8476;"/* blackletter capital R = real part symbol */,
						"\u211C" },
				{ "&trade;", "&#8482;"/* trade mark sign */, "\u2122" },
				{ "&alefsym;", "&#8501;"/*
										 * alef symbol = first transfinite
										 * cardinal
										 */, "\u2135" }
				/* alef symbol is NOT the same as hebrew letter alef ,"\u05D0"} */
				/* Arrows */
				,
				{ "&larr;", "&#8592;"/* leftwards arrow */, "\u2190" },
				{ "&uarr;", "&#8593;"/* upwards arrow */, "\u2191" },
				{ "&rarr;", "&#8594;"/* rightwards arrow */, "\u2192" },
				{ "&darr;", "&#8595;"/* downwards arrow */, "\u2193" },
				{ "&harr;", "&#8596;"/* left right arrow */, "\u2194" },
				{ "&crarr;", "&#8629;"/*
									 * downwards arrow with corner leftwards =
									 * carriage return
									 */, "\u21B5" },
				{ "&lArr;", "&#8656;"/* leftwards double arrow */, "\u21D0" }
				/*
				 * Unicode does not say that lArr is the same as the 'is implied
				 * by' arrow but also does not have any other character for that
				 * function. So ? lArr can be used for 'is implied by' as
				 * ISOtech suggests
				 */
				,
				{ "&uArr;", "&#8657;"/* upwards double arrow */, "\u21D1" },
				{ "&rArr;", "&#8658;"/* rightwards double arrow */, "\u21D2" }
				/*
				 * Unicode does not say this is the 'implies' character but does
				 * not have another character with this function so ? rArr can
				 * be used for 'implies' as ISOtech suggests
				 */
				,
				{ "&dArr;", "&#8659;"/* downwards double arrow */, "\u21D3" },
				{ "&hArr;", "&#8660;"/* left right double arrow */, "\u21D4" }
				/* Mathematical Operators */
				,
				{ "&forall;", "&#8704;"/* for all */, "\u2200" },
				{ "&part;", "&#8706;"/* partial differential */, "\u2202" },
				{ "&exist;", "&#8707;"/* there exists */, "\u2203" },
				{ "&empty;", "&#8709;"/* empty set = null set = diameter */,
						"\u2205" },
				{ "&nabla;", "&#8711;"/* nabla = backward difference */, "\u2207" },
				{ "&isin;", "&#8712;"/* element of */, "\u2208" },
				{ "&notin;", "&#8713;"/* not an element of */, "\u2209" },
				{ "&ni;", "&#8715;"/* contains as member */, "\u220B" }
				/* should there be a more memorable name than 'ni'? */
				,
				{ "&prod;", "&#8719;"/* n-ary product = product sign */,
						"\u220F" }
				/* prod is NOT the same character as ,"\u03A0"} */
				,
				{ "&sum;", "&#8721;"/* n-ary sumation */, "\u2211" }
				/* sum is NOT the same character as ,"\u03A3"} */
				,
				{ "&minus;", "&#8722;"/* minus sign */, "\u2212" },
				{ "&lowast;", "&#8727;"/* asterisk operator */, "\u2217" },
				{ "&radic;", "&#8730;"/* square root = radical sign */, "\u221A" },
				{ "&prop;", "&#8733;"/* proportional to */, "\u221D" },
				{ "&infin;", "&#8734;"/* infinity */, "\u221E" },
				{ "&ang;", "&#8736;"/* angle */, "\u2220" },
				{ "&and;", "&#8743;"/* logical and = wedge */, "\u2227" },
				{ "&or;", "&#8744;"/* logical or = vee */, "\u2228" },
				{ "&cap;", "&#8745;"/* intersection = cap */, "\u2229" },
				{ "&cup;", "&#8746;"/* union = cup */, "\u222A" },
				{ "&int;", "&#8747;"/* integral */, "\u222B" },
				{ "&there4;", "&#8756;"/* therefore */, "\u2234" },
				{
						"&sim;",
						"&#8764;"/* tilde operator = varies with = similar to */,
						"\u223C" }
				/*
				 * tilde operator is NOT the same character as the tilde
				 * ,"\u007E"}
				 */
				,
				{ "&cong;", "&#8773;"/* approximately equal to */, "\u2245" },
				{ "&asymp;", "&#8776;"/* almost equal to = asymptotic to */,
						"\u2248" },
				{ "&ne;", "&#8800;"/* not equal to */, "\u2260" },
				{ "&equiv;", "&#8801;"/* identical to */, "\u2261" },
				{ "&le;", "&#8804;"/* less-than or equal to */, "\u2264" },
				{ "&ge;", "&#8805;"/* greater-than or equal to */, "\u2265" },
				{ "&sub;", "&#8834;"/* subset of */, "\u2282" },
				{ "&sup;", "&#8835;"/* superset of */, "\u2283" }
				/* note that nsup 'not a superset of ,"\u2283"} */
				,
				{ "&sube;", "&#8838;"/* subset of or equal to */, "\u2286" },
				{ "&supe;", "&#8839;"/* superset of or equal to */, "\u2287" },
				{ "&oplus;", "&#8853;"/* circled plus = direct sum */, "\u2295" },
				{ "&otimes;", "&#8855;"/* circled times = vector product */,
						"\u2297" },
				{ "&perp;",
						"&#8869;"/* up tack = orthogonal to = perpendicular */,
						"\u22A5" },
				{ "&sdot;", "&#8901;"/* dot operator */, "\u22C5" }
				/*
				 * dot operator is NOT the same character as ,"\u00B7"} /*
				 * Miscellaneous Technical
				 */
				,
				{ "&lceil;", "&#8968;"/* left ceiling = apl upstile */, "\u2308" },
				{ "&rceil;", "&#8969;"/* right ceiling */, "\u2309" },
				{ "&lfloor;", "&#8970;"/* left floor = apl downstile */,
						"\u230A" },
				{ "&rfloor;", "&#8971;"/* right floor */, "\u230B" },
				{ "&lang;", "&#9001;"/* left-pointing angle bracket = bra */,
						"\u2329" }
				/* lang is NOT the same character as ,"\u003C"} */
				,
				{ "&rang;", "&#9002;"/* right-pointing angle bracket = ket */,
						"\u232A" }
				/* rang is NOT the same character as ,"\u003E"} */
				/* Geometric Shapes */
				,
				{ "&loz;", "&#9674;"/* lozenge */, "\u25CA" }
				/* Miscellaneous Symbols */
				,
				{ "&spades;", "&#9824;"/* black spade suit */, "\u2660" }
				/* black here seems to mean filled as opposed to hollow */
				,
				{ "&clubs;", "&#9827;"/* black club suit = shamrock */, "\u2663" },
				{ "&hearts;", "&#9829;"/* black heart suit = valentine */,
						"\u2665" },
				{ "&diams;", "&#9830;"/* black diamond suit */, "\u2666" },
				{ "&quot;", "&#34;" /* quotation mark = APL quote */, "\"" },
				{ "&amp;", "&#38;" /* ampersand */, "\u0026" },
				{ "&lt;", "&#60;" /* less-than sign */, "\u003C" },
				{ "&gt;", "&#62;" /* greater-than sign */, "\u003E" }
				/* Latin Extended-A */
				,
				{ "&OElig;", "&#338;" /* latin capital ligature OE */, "\u0152" },
				{ "&oelig;", "&#339;" /* latin small ligature oe */, "\u0153" }
				/*
				 * ligature is a misnomer this is a separate character in some
				 * languages
				 */
				,
				{ "&Scaron;",
						"&#352;" /* latin capital letter S with caron */,
						"\u0160" },
				{ "&scaron;", "&#353;" /* latin small letter s with caron */,
						"\u0161" },
				{ "&Yuml;",
						"&#376;" /* latin capital letter Y with diaeresis */,
						"\u0178" }
				/* Spacing Modifier Letters */
				,
				{ "&circ;", "&#710;" /* modifier letter circumflex accent */,
						"\u02C6" },
				{ "&tilde;", "&#732;" /* small tilde */, "\u02DC" }
				/* General Punctuation */
				,
				{ "&ensp;", "&#8194;"/* en space */, "\u2002" },
				{ "&emsp;", "&#8195;"/* em space */, "\u2003" },
				{ "&thinsp;", "&#8201;"/* thin space */, "\u2009" },
				{ "&zwnj;", "&#8204;"/* zero width non-joiner */, "\u200C" },
				{ "&zwj;", "&#8205;"/* zero width joiner */, "\u200D" },
				{ "&lrm;", "&#8206;"/* left-to-right mark */, "\u200E" },
				{ "&rlm;", "&#8207;"/* right-to-left mark */, "\u200F" },
				{ "&ndash;", "&#8211;"/* en dash */, "\u2013" },
				{ "&mdash;", "&#8212;"/* em dash */, "\u2014" },
				{ "&lsquo;", "&#8216;"/* left single quotation mark */, "\u2018" },
				{ "&rsquo;", "&#8217;"/* right single quotation mark */, "\u2019" },
				{ "&sbquo;", "&#8218;"/* single low-9 quotation mark */, "\u201A" },
				{ "&ldquo;", "&#8220;"/* left double quotation mark */, "\u201C" },
				{ "&rdquo;", "&#8221;"/* right double quotation mark */, "\u201D" },
				{ "&bdquo;", "&#8222;"/* double low-9 quotation mark */, "\u201E" },
				{ "&dagger;", "&#8224;"/* dagger */, "\u2020" },
				{ "&Dagger;", "&#8225;"/* double dagger */, "\u2021" },
				{ "&permil;", "&#8240;"/* per mille sign */, "\u2030" },
				{ "&lsaquo;", "&#8249;"/*
										 * single left-pointing angle quotation
										 * mark
										 */, "\u2039" }
				/* lsaquo is proposed but not yet ISO standardized */
				, { "&rsaquo;", "&#8250;"/*
										 * single right-pointing angle quotation
										 * mark
										 */, "\u203A" }
				/* rsaquo is proposed but not yet ISO standardized */
				, { "&euro;", "&#8364;" /* euro sign */, "\u20AC" } };
		for (String[] entity : entities) {
			entityEscapeMap.put(entity[2], entity[0]);
			escapeEntityMap.put(entity[0], entity[2]);
			escapeEntityMap.put(entity[1], entity[2]);
		}
	}

}
