/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.StringTokenizer;

/**
 *
 * Sanitizes the Query portion of a URL. Simple example:
 * <code>
 * UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
 * sanitizer.setAllowUnregisteredParamaters(true);
 * sanitizer.parseUrl("http://example.com/?name=Joe+User");
 * String name = sanitizer.getValue("name"));
 * // name now contains "Joe_User"
 * </code>
 *
 * Register ValueSanitizers to customize the way individual
 * parameters are sanitized:
 * <code>
 * UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
 * sanitizer.registerParamater("name", UrlQuerySanitizer.createSpaceLegal());
 * sanitizer.parseUrl("http://example.com/?name=Joe+User");
 * String name = sanitizer.getValue("name"));
 * // name now contains "Joe User". (The string is first decoded, which
 * // converts the '+' to a ' '. Then the string is sanitized, which
 * // converts the ' ' to an '_'. (The ' ' is converted because the default
 * unregistered parameter sanitizer does not allow any special characters,
 * and ' ' is a special character.)
 * </code>
 *
 * There are several ways to create ValueSanitizers. In order of increasing
 * sophistication:
 * <ol>
 * <li>Call one of the UrlQuerySanitizer.createXXX() methods.
 * <li>Construct your own instance of
 * UrlQuerySanitizer.IllegalCharacterValueSanitizer.
 * <li>Subclass UrlQuerySanitizer.ValueSanitizer to define your own value
 * sanitizer.
 * </ol>
 *
 */
public class UrlQuerySanitizer {

    /**
     * A simple tuple that holds parameter-value pairs.
     *
     */
    public class ParameterValuePair {
        /**
         * Construct a parameter-value tuple.
         * @param parameter an unencoded parameter
         * @param value an unencoded value
         */
        public ParameterValuePair(String parameter,
                String value) {
            mParameter = parameter;
            mValue = value;
        }
        /**
         * The unencoded parameter
         */
        public String mParameter;
        /**
         * The unencoded value
         */
        public String mValue;
    }

    final private HashMap<String, ValueSanitizer> mSanitizers =
        new HashMap<String, ValueSanitizer>();
    final private HashMap<String, String> mEntries =
        new HashMap<String, String>();
    final private ArrayList<ParameterValuePair> mEntriesList =
        new ArrayList<ParameterValuePair>();
    private boolean mAllowUnregisteredParamaters;
    private boolean mPreferFirstRepeatedParameter;
    private ValueSanitizer mUnregisteredParameterValueSanitizer =
        getAllIllegal();

    /**
     * A functor used to sanitize a single query value.
     *
     */
    public static interface ValueSanitizer {
        /**
         * Sanitize an unencoded value.
         * @param value
         * @return the sanitized unencoded value
         */
        public String sanitize(String value);
    }

    /**
     * Sanitize values based on which characters they contain. Illegal
     * characters are replaced with either space or '_', depending upon
     * whether space is a legal character or not.
     */
    public static class IllegalCharacterValueSanitizer implements
        ValueSanitizer {
        private int mFlags;

        /**
         * Allow space (' ') characters.
         */
        public final static int SPACE_OK =              1 << 0;
        /**
         * Allow whitespace characters other than space. The
         * other whitespace characters are
         * '\t' '\f' '\n' '\r' and '\0x000b' (vertical tab)
         */
        public final static int OTHER_WHITESPACE_OK =  1 << 1;
        /**
         * Allow characters with character codes 128 to 255.
         */
        public final static int NON_7_BIT_ASCII_OK =    1 << 2;
        /**
         * Allow double quote characters. ('"')
         */
        public final static int DQUOTE_OK =             1 << 3;
        /**
         * Allow single quote characters. ('\'')
         */
        public final static int SQUOTE_OK =             1 << 4;
        /**
         * Allow less-than characters. ('<')
         */
        public final static int LT_OK =                 1 << 5;
        /**
         * Allow greater-than characters. ('>')
         */
        public final static int GT_OK =                 1 << 6;
        /**
         * Allow ampersand characters ('&')
         */
        public final static int AMP_OK =                1 << 7;
        /**
         * Allow percent-sign characters ('%')
         */
        public final static int PCT_OK =                1 << 8;
        /**
         * Allow nul characters ('\0')
         */
        public final static int NUL_OK =                1 << 9;
        /**
         * Allow text to start with a script URL
         * such as "javascript:" or "vbscript:"
         */
        public final static int SCRIPT_URL_OK =         1 << 10;

        /**
         * Mask with all fields set to OK
         */
        public final static int ALL_OK =                0x7ff;

        /**
         * Mask with both regular space and other whitespace OK
         */
        public final static int ALL_WHITESPACE_OK =
            SPACE_OK | OTHER_WHITESPACE_OK;


        // Common flag combinations:

        /**
         * <ul>
         * <li>Deny all special characters.
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int ALL_ILLEGAL =
            0;
        /**
         * <ul>
         * <li>Allow all special characters except Nul. ('\0').
         * <li>Allow script URLs.
         * </ul>
         */
        public final static int ALL_BUT_NUL_LEGAL =
            ALL_OK & ~NUL_OK;
        /**
         * <ul>
         * <li>Allow all special characters except for:
         * <ul>
         *  <li>whitespace characters
         *  <li>Nul ('\0')
         * </ul>
         * <li>Allow script URLs.
         * </ul>
         */
        public final static int ALL_BUT_WHITESPACE_LEGAL =
            ALL_OK & ~(ALL_WHITESPACE_OK | NUL_OK);
        /**
         * <ul>
         * <li>Allow characters used by encoded URLs.
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int URL_LEGAL =
            NON_7_BIT_ASCII_OK | SQUOTE_OK | AMP_OK | PCT_OK;
        /**
         * <ul>
         * <li>Allow characters used by encoded URLs.
         * <li>Allow spaces.
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int URL_AND_SPACE_LEGAL =
            URL_LEGAL | SPACE_OK;
        /**
         * <ul>
         * <li>Allow ampersand.
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int AMP_LEGAL =
            AMP_OK;
        /**
         * <ul>
         * <li>Allow ampersand.
         * <li>Allow space.
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int AMP_AND_SPACE_LEGAL =
            AMP_OK | SPACE_OK;
        /**
         * <ul>
         * <li>Allow space.
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int SPACE_LEGAL =
            SPACE_OK;
        /**
         * <ul>
         * <li>Allow all but.
         * <ul>
         *  <li>Nul ('\0')
         *  <li>Angle brackets ('<', '>')
         * </ul>
         * <li>Deny script URLs.
         * </ul>
         */
        public final static int ALL_BUT_NUL_AND_ANGLE_BRACKETS_LEGAL =
            ALL_OK & ~(NUL_OK | LT_OK | GT_OK);

        /**
         *  Script URL definitions
         */

        private final static String JAVASCRIPT_PREFIX = "javascript:";

        private final static String VBSCRIPT_PREFIX = "vbscript:";

        private final static int MIN_SCRIPT_PREFIX_LENGTH = Math.min(
                JAVASCRIPT_PREFIX.length(), VBSCRIPT_PREFIX.length());

        /**
         * Construct a sanitizer. The parameters set the behavior of the
         * sanitizer.
         * @param flags some combination of the XXX_OK flags.
         */
        public IllegalCharacterValueSanitizer(
            int flags) {
            mFlags = flags;
        }
        /**
         * Sanitize a value.
         * <ol>
         * <li>If script URLs are not OK, they will be removed.
         * <li>If neither spaces nor other white space is OK, then
         * white space will be trimmed from the beginning and end of
         * the URL. (Just the actual white space characters are trimmed, not
         * other control codes.)
         * <li> Illegal characters will be replaced with
         * either ' ' or '_', depending on whether a space is itself a
         * legal character.
         * </ol>
         * @param value
         * @return the sanitized value
         */
        public String sanitize(String value) {
            if (value == null) {
                return null;
            }
            int length = value.length();
            if ((mFlags & SCRIPT_URL_OK) != 0) {
                if (length >= MIN_SCRIPT_PREFIX_LENGTH) {
                    String asLower = value.toLowerCase(Locale.ROOT);
                    if (asLower.startsWith(JAVASCRIPT_PREFIX)  ||
                        asLower.startsWith(VBSCRIPT_PREFIX)) {
                        return "";
                    }
                }
            }

            // If whitespace isn't OK, get rid of whitespace at beginning
            // and end of value.
            if ( (mFlags & ALL_WHITESPACE_OK) == 0) {
                value = trimWhitespace(value);
                // The length could have changed, so we need to correct
                // the length variable.
                length = value.length();
            }

            StringBuilder stringBuilder = new StringBuilder(length);
            for(int i = 0; i < length; i++) {
                char c = value.charAt(i);
                if (!characterIsLegal(c)) {
                    if ((mFlags & SPACE_OK) != 0) {
                        c = ' ';
                    }
                    else {
                        c = '_';
                    }
                }
                stringBuilder.append(c);
            }
            return stringBuilder.toString();
        }

        /**
         * Trim whitespace from the beginning and end of a string.
         * <p>
         * Note: can't use {@link String#trim} because {@link String#trim} has a
         * different definition of whitespace than we want.
         * @param value the string to trim
         * @return the trimmed string
         */
        private String trimWhitespace(String value) {
            int start = 0;
            int last = value.length() - 1;
            int end = last;
            while (start <= end && isWhitespace(value.charAt(start))) {
                start++;
            }
            while (end >= start && isWhitespace(value.charAt(end))) {
                end--;
            }
            if (start == 0 && end == last) {
                return value;
            }
            return value.substring(start, end + 1);
        }

        /**
         * Check if c is whitespace.
         * @param c character to test
         * @return true if c is a whitespace character
         */
        private boolean isWhitespace(char c) {
            switch(c) {
            case ' ':
            case '\t':
            case '\f':
            case '\n':
            case '\r':
            case 11: /* VT */
                return true;
            default:
                return false;
            }
        }

        /**
         * Check whether an individual character is legal. Uses the
         * flag bit-set passed into the constructor.
         * @param c
         * @return true if c is a legal character
         */
        private boolean characterIsLegal(char c) {
            switch(c) {
            case ' ' : return (mFlags & SPACE_OK) != 0;
            case '\t': case '\f': case '\n': case '\r': case 11: /* VT */
              return (mFlags & OTHER_WHITESPACE_OK) != 0;
            case '\"': return (mFlags & DQUOTE_OK) != 0;
            case '\'': return (mFlags & SQUOTE_OK) != 0;
            case '<' : return (mFlags & LT_OK) != 0;
            case '>' : return (mFlags & GT_OK) != 0;
            case '&' : return (mFlags & AMP_OK) != 0;
            case '%' : return (mFlags & PCT_OK) != 0;
            case '\0': return (mFlags & NUL_OK) != 0;
            default  : return (c >= 32 && c < 127) ||
                ((c >= 128) && ((mFlags & NON_7_BIT_ASCII_OK) != 0));
            }
        }
    }

    /**
     * Get the current value sanitizer used when processing
     * unregistered parameter values.
     * <p>
     * <b>Note:</b> The default unregistered parameter value sanitizer is
     * one that doesn't allow any special characters, similar to what
     * is returned by calling createAllIllegal.
     *
     * @return the current ValueSanitizer used to sanitize unregistered
     * parameter values.
     */
    public ValueSanitizer getUnregisteredParameterValueSanitizer() {
        return mUnregisteredParameterValueSanitizer;
    }

    /**
     * Set the value sanitizer used when processing unregistered
     * parameter values.
     * @param sanitizer set the ValueSanitizer used to sanitize unregistered
     * parameter values.
     */
    public void setUnregisteredParameterValueSanitizer(
            ValueSanitizer sanitizer) {
        mUnregisteredParameterValueSanitizer = sanitizer;
    }


    // Private fields for singleton sanitizers:

    private static final ValueSanitizer sAllIllegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.ALL_ILLEGAL);

    private static final ValueSanitizer sAllButNulLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.ALL_BUT_NUL_LEGAL);

    private static final ValueSanitizer sAllButWhitespaceLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.ALL_BUT_WHITESPACE_LEGAL);

    private static final ValueSanitizer sURLLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.URL_LEGAL);

    private static final ValueSanitizer sUrlAndSpaceLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.URL_AND_SPACE_LEGAL);

    private static final ValueSanitizer sAmpLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.AMP_LEGAL);

    private static final ValueSanitizer sAmpAndSpaceLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.AMP_AND_SPACE_LEGAL);

    private static final ValueSanitizer sSpaceLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.SPACE_LEGAL);

    private static final ValueSanitizer sAllButNulAndAngleBracketsLegal =
        new IllegalCharacterValueSanitizer(
                IllegalCharacterValueSanitizer.ALL_BUT_NUL_AND_ANGLE_BRACKETS_LEGAL);

    /**
     * Return a value sanitizer that does not allow any special characters,
     * and also does not allow script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getAllIllegal() {
        return sAllIllegal;
    }

    /**
     * Return a value sanitizer that allows everything except Nul ('\0')
     * characters. Script URLs are allowed.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getAllButNulLegal() {
        return sAllButNulLegal;
    }
    /**
     * Return a value sanitizer that allows everything except Nul ('\0')
     * characters, space (' '), and other whitespace characters.
     * Script URLs are allowed.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getAllButWhitespaceLegal() {
        return sAllButWhitespaceLegal;
    }
    /**
     * Return a value sanitizer that allows all the characters used by
     * encoded URLs. Does not allow script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getUrlLegal() {
        return sURLLegal;
    }
    /**
     * Return a value sanitizer that allows all the characters used by
     * encoded URLs and allows spaces, which are not technically legal
     * in encoded URLs, but commonly appear anyway.
     * Does not allow script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getUrlAndSpaceLegal() {
        return sUrlAndSpaceLegal;
    }
    /**
     * Return a value sanitizer that does not allow any special characters
     * except ampersand ('&'). Does not allow script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getAmpLegal() {
        return sAmpLegal;
    }
    /**
     * Return a value sanitizer that does not allow any special characters
     * except ampersand ('&') and space (' '). Does not allow script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getAmpAndSpaceLegal() {
        return sAmpAndSpaceLegal;
    }
    /**
     * Return a value sanitizer that does not allow any special characters
     * except space (' '). Does not allow script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getSpaceLegal() {
        return sSpaceLegal;
    }
    /**
     * Return a value sanitizer that allows any special characters
     * except angle brackets ('<' and '>') and Nul ('\0').
     * Allows script URLs.
     * @return a value sanitizer
     */
    public static final ValueSanitizer getAllButNulAndAngleBracketsLegal() {
        return sAllButNulAndAngleBracketsLegal;
    }

    /**
     * Constructs a UrlQuerySanitizer.
     * <p>
     * Defaults:
     * <ul>
     * <li>unregistered parameters are not allowed.
     * <li>the last instance of a repeated parameter is preferred.
     * <li>The default value sanitizer is an AllIllegal value sanitizer.
     * <ul>
     */
    public UrlQuerySanitizer() {
    }

    /**
     * Constructs a UrlQuerySanitizer and parses a URL.
     * This constructor is provided for convenience when the
     * default parsing behavior is acceptable.
     * <p>
     * Because the URL is parsed before the constructor returns, there isn't
     * a chance to configure the sanitizer to change the parsing behavior.
     * <p>
     * <code>
     * UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(myUrl);
     * String name = sanitizer.getValue("name");
     * </code>
     * <p>
     * Defaults:
     * <ul>
     * <li>unregistered parameters <em>are</em> allowed.
     * <li>the last instance of a repeated parameter is preferred.
     * <li>The default value sanitizer is an AllIllegal value sanitizer.
     * <ul>
     */
    public UrlQuerySanitizer(String url) {
        setAllowUnregisteredParamaters(true);
        parseUrl(url);
    }

    /**
     * Parse the query parameters out of an encoded URL.
     * Works by extracting the query portion from the URL and then
     * calling parseQuery(). If there is no query portion it is
     * treated as if the query portion is an empty string.
     * @param url the encoded URL to parse.
     */
    public void parseUrl(String url) {
        int queryIndex = url.indexOf('?');
        String query;
        if (queryIndex >= 0) {
            query = url.substring(queryIndex + 1);
        }
        else {
            query = "";
        }
        parseQuery(query);
    }

    /**
     * Parse a query. A query string is any number of parameter-value clauses
     * separated by any non-zero number of ampersands. A parameter-value clause
     * is a parameter followed by an equal sign, followed by a value. If the
     * equal sign is missing, the value is assumed to be the empty string.
     * @param query the query to parse.
     */
    public void parseQuery(String query) {
        clear();
        // Split by '&'
        StringTokenizer tokenizer = new StringTokenizer(query, "&");
        while(tokenizer.hasMoreElements()) {
            String attributeValuePair = tokenizer.nextToken();
            if (attributeValuePair.length() > 0) {
                int assignmentIndex = attributeValuePair.indexOf('=');
                if (assignmentIndex < 0) {
                    // No assignment found, treat as if empty value
                    parseEntry(attributeValuePair, "");
                }
                else {
                    parseEntry(attributeValuePair.substring(0, assignmentIndex),
                            attributeValuePair.substring(assignmentIndex + 1));
                }
            }
        }
    }

    /**
     * Get a set of all of the parameters found in the sanitized query.
     * <p>
     * Note: Do not modify this set. Treat it as a read-only set.
     * @return all the parameters found in the current query.
     */
    public Set<String> getParameterSet() {
        return mEntries.keySet();
    }

    /**
     * An array list of all of the parameter-value pairs in the sanitized
     * query, in the order they appeared in the query. May contain duplicate
     * parameters.
     * <p class="note"><b>Note:</b> Do not modify this list. Treat it as a read-only list.</p>
     */
    public List<ParameterValuePair> getParameterList() {
        return mEntriesList;
    }

    /**
     * Check if a parameter exists in the current sanitized query.
     * @param parameter the unencoded name of a parameter.
     * @return true if the parameter exists in the current sanitized queary.
     */
    public boolean hasParameter(String parameter) {
        return mEntries.containsKey(parameter);
    }

    /**
     * Get the value for a parameter in the current sanitized query.
     * Returns null if the parameter does not
     * exit.
     * @param parameter the unencoded name of a parameter.
     * @return the sanitized unencoded value of the parameter,
     * or null if the parameter does not exist.
     */
    public String getValue(String parameter) {
        return mEntries.get(parameter);
    }

    /**
     * Register a value sanitizer for a particular parameter. Can also be used
     * to replace or remove an already-set value sanitizer.
     * <p>
     * Registering a non-null value sanitizer for a particular parameter
     * makes that parameter a registered parameter.
     * @param parameter an unencoded parameter name
     * @param valueSanitizer the value sanitizer to use for a particular
     * parameter. May be null in order to unregister that parameter.
     * @see #getAllowUnregisteredParamaters()
     */
    public void registerParameter(String parameter,
            ValueSanitizer valueSanitizer) {
        if (valueSanitizer == null) {
            mSanitizers.remove(parameter);
        }
        mSanitizers.put(parameter, valueSanitizer);
    }

    /**
     * Register a value sanitizer for an array of parameters.
     * @param parameters An array of unencoded parameter names.
     * @param valueSanitizer
     * @see #registerParameter
     */
    public void registerParameters(String[] parameters,
            ValueSanitizer valueSanitizer) {
        int length = parameters.length;
        for(int i = 0; i < length; i++) {
            mSanitizers.put(parameters[i], valueSanitizer);
        }
    }

    /**
     * Set whether or not unregistered parameters are allowed. If they
     * are not allowed, then they will be dropped when a query is sanitized.
     * <p>
     * Defaults to false.
     * @param allowUnregisteredParamaters true to allow unregistered parameters.
     * @see #getAllowUnregisteredParamaters()
     */
    public void setAllowUnregisteredParamaters(
            boolean allowUnregisteredParamaters) {
        mAllowUnregisteredParamaters = allowUnregisteredParamaters;
    }

    /**
     * Get whether or not unregistered parameters are allowed. If not
     * allowed, they will be dropped when a query is parsed.
     * @return true if unregistered parameters are allowed.
     * @see #setAllowUnregisteredParamaters(boolean)
     */
    public boolean getAllowUnregisteredParamaters() {
        return mAllowUnregisteredParamaters;
    }

    /**
     * Set whether or not the first occurrence of a repeated parameter is
     * preferred. True means the first repeated parameter is preferred.
     * False means that the last repeated parameter is preferred.
     * <p>
     * The preferred parameter is the one that is returned when getParameter
     * is called.
     * <p>
     * defaults to false.
     * @param preferFirstRepeatedParameter True if the first repeated
     * parameter is preferred.
     * @see #getPreferFirstRepeatedParameter()
     */
    public void setPreferFirstRepeatedParameter(
            boolean preferFirstRepeatedParameter) {
        mPreferFirstRepeatedParameter = preferFirstRepeatedParameter;
    }

    /**
     * Get whether or not the first occurrence of a repeated parameter is
     * preferred.
     * @return true if the first occurrence of a repeated parameter is
     * preferred.
     * @see #setPreferFirstRepeatedParameter(boolean)
     */
    public boolean getPreferFirstRepeatedParameter() {
        return mPreferFirstRepeatedParameter;
    }

    /**
     * Parse an escaped parameter-value pair. The default implementation
     * unescapes both the parameter and the value, then looks up the
     * effective value sanitizer for the parameter and uses it to sanitize
     * the value. If all goes well then addSanitizedValue is called with
     * the unescaped parameter and the sanitized unescaped value.
     * @param parameter an escaped parameter
     * @param value an unsanitized escaped value
     */
    protected void parseEntry(String parameter, String value) {
        String unescapedParameter = unescape(parameter);
         ValueSanitizer valueSanitizer =
            getEffectiveValueSanitizer(unescapedParameter);

        if (valueSanitizer == null) {
            return;
        }
        String unescapedValue = unescape(value);
        String sanitizedValue = valueSanitizer.sanitize(unescapedValue);
        addSanitizedEntry(unescapedParameter, sanitizedValue);
    }

    /**
     * Record a sanitized parameter-value pair. Override if you want to
     * do additional filtering or validation.
     * @param parameter an unescaped parameter
     * @param value a sanitized unescaped value
     */
    protected void addSanitizedEntry(String parameter, String value) {
        mEntriesList.add(
                new ParameterValuePair(parameter, value));
        if (mPreferFirstRepeatedParameter) {
            if (mEntries.containsKey(parameter)) {
                return;
            }
        }
        mEntries.put(parameter, value);
    }

    /**
     * Get the value sanitizer for a parameter. Returns null if there
     * is no value sanitizer registered for the parameter.
     * @param parameter the unescaped parameter
     * @return the currently registered value sanitizer for this parameter.
     * @see #registerParameter(String, android.net.UrlQuerySanitizer.ValueSanitizer)
     */
    public ValueSanitizer getValueSanitizer(String parameter) {
        return mSanitizers.get(parameter);
    }

    /**
     * Get the effective value sanitizer for a parameter. Like getValueSanitizer,
     * except if there is no value sanitizer registered for a parameter, and
     * unregistered parameters are allowed, then the default value sanitizer is
     * returned.
     * @param parameter an unescaped parameter
     * @return the effective value sanitizer for a parameter.
     */
    public ValueSanitizer getEffectiveValueSanitizer(String parameter) {
        ValueSanitizer sanitizer = getValueSanitizer(parameter);
        if (sanitizer == null && mAllowUnregisteredParamaters) {
            sanitizer = getUnregisteredParameterValueSanitizer();
        }
        return sanitizer;
    }

    /**
     * Unescape an escaped string.
     * <ul>
     * <li>'+' characters are replaced by
     * ' ' characters.
     * <li>Valid "%xx" escape sequences are replaced by the
     * corresponding unescaped character.
     * <li>Invalid escape sequences such as %1z", are passed through unchanged.
     * <ol>
     * @param string the escaped string
     * @return the unescaped string.
     */
    public String unescape(String string) {
        // Early exit if no escaped characters.
        int firstEscape = string.indexOf('%');
        if ( firstEscape < 0) {
            firstEscape = string.indexOf('+');
            if (firstEscape < 0) {
                return string;
            }
        }

        int length = string.length();

        StringBuilder stringBuilder = new StringBuilder(length);
        stringBuilder.append(string.substring(0, firstEscape));
        for (int i = firstEscape; i < length; i++) {
            char c = string.charAt(i);
            if (c == '+') {
                c = ' ';
            }
            else if ( c == '%' && i + 2 < length) {
                char c1 = string.charAt(i + 1);
                char c2 = string.charAt(i + 2);
                if (isHexDigit(c1) && isHexDigit(c2)) {
                    c = (char) (decodeHexDigit(c1) * 16 + decodeHexDigit(c2));
                    i += 2;
                }
            }
            stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }

    /**
     * Test if a character is a hexidecimal digit. Both upper case and lower
     * case hex digits are allowed.
     * @param c the character to test
     * @return true if c is a hex digit.
     */
    protected boolean isHexDigit(char c) {
        return decodeHexDigit(c) >= 0;
    }

    /**
     * Convert a character that represents a hexidecimal digit into an integer.
     * If the character is not a hexidecimal digit, then -1 is returned.
     * Both upper case and lower case hex digits are allowed.
     * @param c the hexidecimal digit.
     * @return the integer value of the hexidecimal digit.
     */

    protected int decodeHexDigit(char c) {
        if (c >= '0' && c <= '9') {
            return c - '0';
        }
        else if (c >= 'A' && c <= 'F') {
            return c - 'A' + 10;
        }
        else if (c >= 'a' && c <= 'f') {
            return c - 'a' + 10;
        }
        else {
            return -1;
        }
    }

    /**
     * Clear the existing entries. Called to get ready to parse a new
     * query string.
     */
    protected void clear() {
        mEntries.clear();
        mEntriesList.clear();
    }
}

