class UriComponent {

    public static String decode(String str, int component) {
        if (str == null) {
            throw new IllegalArgumentException("Decoded string is null");
        }

        int length = str.length();

        if (length < 3 && str.indexOf('%') >= 0) {
            throw new IllegalArgumentException("Malformed string: " + str);
        }

        int p = str.lastIndexOf('%');
        if (p > 0 && p > (length - 3)) {
            throw new IllegalArgumentException("Malformed string '" + str + "' at index " + p);
        }

        p = 0; // reset pointer
        StringBuilder sb = new StringBuilder();
        NoSyncByteArrayOutputStream buff = null;
        while (p < length) {
            char c = str.charAt(p);
            switch (c) {
                case '%':
                    if (p + 2 > length) {
                        throw new IllegalArgumentException("Malformed string '" + str + "' at index " + p);
                    }
                    if (buff == null) {
                        buff = new NoSyncByteArrayOutputStream(4);
                    } else {
                        buff.reset();
                    }
                    p = percentDecode(str, p, buff);
                    byte[] bytes = buff.toByteArray();
                    if (bytes.length == 1 && (bytes[0] & 0xFF) < 128) {
                        sb.append((char)bytes[0]);
                    } else {
                        sb.append(UTF8.decode(ByteBuffer.wrap(bytes)));
                    }
                    break;
                case '+':
                    sb.append(' ');
                    p++;
                    break;
                default:
                    sb.append(c);
                    p++;
                    break;
            }
        }

        return sb.toString();
    }

    private  UriComponent();

}