public static String escapeHtml(String input) {
        // Avoid building a new string in the majority of cases (nothing to escape)
        StringBuilder sb = null;

        loop:
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            String replacement;
            switch (c) {
                case '&':
                    replacement = "&amp;";
                    break;
                case '<':
                    replacement = "&lt;";
                    break;
                case '>':
                    replacement = "&gt;";
                    break;
                case '\"':
                    replacement = "&quot;";
                    break;
                default:
                    if (sb != null) {
                        sb.append(c);
                    }
                    continue loop;
            }
            if (sb == null) {
                sb = new StringBuilder();
                sb.append(input, 0, i);
            }
            sb.append(replacement);
        }

        return sb != null ? sb.toString() : input;
    }
@Test
    public void testEscapeHtml() {
        assertEquals("nothing to escape", Escaping.escapeHtml("nothing to escape"));
        assertEquals("&amp;", Escaping.escapeHtml("&"));
        assertEquals("&lt;", Escaping.escapeHtml("<"));
        assertEquals("&gt;", Escaping.escapeHtml(">"));
        assertEquals("&quot;", Escaping.escapeHtml("\""));
        assertEquals("&lt; start", Escaping.escapeHtml("< start"));
        assertEquals("end &gt;", Escaping.escapeHtml("end >"));
        assertEquals("&lt; both &gt;", Escaping.escapeHtml("< both >"));
        assertEquals("&lt; middle &amp; too &gt;", Escaping.escapeHtml("< middle & too >"));
    }