public static String unhtmlentities(String str) {

        //initialize html translation maps table the first time is called
        if (htmlentities_map.isEmpty()) {
            initializeEntitiesTables();
        }

        StringBuilder buf = new StringBuilder();

        for (int i = 0; i < str.length(); ++i) {
            char ch = str.charAt(i);
            if (ch == '&') {
                int semi = str.indexOf(';', i + 1);
                if ((semi == -1) || ((semi - i) > 7)) {
                    buf.append(ch);
                    continue;
                }
                String entity = str.substring(i, semi + 1);
                Integer iso;
                if (entity.charAt(1) == ' ') {
                    buf.append(ch);
                    continue;
                }
                if (entity.charAt(1) == '#') {
                    if (entity.charAt(2) == 'x') {
                        iso = Integer.valueOf(Integer.parseInt(entity.substring(3, entity.length() - 1), 16));
                    } else {
                        iso = Integer.valueOf(entity.substring(2, entity.length() - 1));
                    }
                } else {
                    iso = (Integer) unhtmlentities_map.get(entity);
                }
                if (iso == null) {
                    buf.append(entity);
                } else {
                    buf.append((char) (iso.intValue()));
                }
                i = semi;
            } else {
                buf.append(ch);
            }
        }
        return buf.toString();
    }