package org.commonmark.internal.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Html5Entities {

    private static final Map<String, String> NAMED_CHARACTER_REFERENCES = readEntities();
    private static final Pattern NUMERIC_PATTERN = Pattern.compile("^&#[Xx]?");
    private static final String ENTITY_PATH = "/org/commonmark/internal/util/entities.properties";

    public static String entityToString(String input) {
        Matcher matcher = NUMERIC_PATTERN.matcher(input);

        if (matcher.find()) {
            int base = matcher.end() == 2 ? 10 : 16;
            try {
                int codePoint = Integer.parseInt(input.substring(matcher.end(), input.length() - 1), base);
                if (codePoint == 0) {
                    return "\uFFFD";
                }
                return new String(Character.toChars(codePoint));
            } catch (IllegalArgumentException e) {
                return "\uFFFD";
            }
        } else {
            String name = input.substring(1, input.length() - 1);
            String s = NAMED_CHARACTER_REFERENCES.get(name);
            if (s != null) {
                return s;
            } else {
                return input;
            }
        }
    }

    private static Map<String, String> readEntities() {
        Map<String, String> entities = new HashMap<>();
        InputStream stream = Html5Entities.class.getResourceAsStream(ENTITY_PATH);
        Charset charset = Charset.forName("UTF-8");
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, charset))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                if (line.length() == 0) {
                    continue;
                }
                int equal = line.indexOf("=");
                String key = line.substring(0, equal);
                String value = line.substring(equal + 1);
                entities.put(key, value);
            }
        } catch (IOException e) {
            throw new IllegalStateException("Failed reading data for HTML named character references", e);
        }
        entities.put("NewLine", "\n");
        return entities;
    }
}

@@ -202,42 +202,36 @@
 ava.
-util.HashMap;%0Aimport java.util.Map
+nio.charset.StandardCharsets
 ;%0Aim
@@ -249,21 +249,15 @@
 til.
-regex.Matcher
+HashMap
 ;%0Aim
@@ -275,21 +275,11 @@
 til.
-regex.Pattern
+Map
 ;%0A%0Ap
@@ -401,88 +401,8 @@
 ();%0A
-    private static final Pattern NUMERIC_PATTERN = Pattern.compile(%22%5E&#%5BXx%5D?%22);%0A
     
@@ -565,59 +565,162 @@
     
-Matcher matcher = NUMERIC_PATTERN.matcher(input
+if (!input.startsWith(%22&%22) %7C%7C !input.endsWith(%22;%22)) %7B%0A            return input;%0A        %7D%0A%0A        String value = input.substring(1, input.length() - 1
 );%0A
-%0A
     
@@ -731,79 +731,252 @@
 if (
-matcher.find()) %7B%0A            int base = matcher.end() == 2 ? 10 :
+value.startsWith(%22#%22)) %7B%0A            value = value.substring(1);%0A            int base = 10;%0A            if (value.startsWith(%22x%22) %7C%7C value.startsWith(%22X%22)) %7B%0A                value = value.substring(1);%0A                base =
  16;%0A
+            %7D%0A%0A
     
@@ -1042,58 +1042,13 @@
 Int(
-input.substring(matcher.end(), input.length() - 1)
+value
 , ba
@@ -1329,74 +1329,8 @@
 e %7B%0A
-            String name = input.substring(1, input.length() - 1);%0A
     
@@ -1379,19 +1379,20 @@
 CES.get(
-nam
+valu
 e);%0A    
@@ -1749,32 +1749,30 @@
 t = 
-Charset.forName(%22UTF-8%22)
+StandardCharsets.UTF_8
 ;%0A  

Remove unnecessary usage of regex for entities