/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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 java.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;

import org.apache.harmony.luni.internal.nls.Messages;

/**
 * This class represents an instance of a URI as defined by RFC 2396.
 */
public final class URI implements Comparable<URI>, Serializable {

    private static final long serialVersionUID = -6052424284110960213l;

    static final String unreserved = "_-!.~\'()*"; //$NON-NLS-1$

    static final String punct = ",;:$&+="; //$NON-NLS-1$

    static final String reserved = punct + "?/[]@"; //$NON-NLS-1$

    static final String someLegal = unreserved + punct;

    static final String allLegal = unreserved + reserved;

    private String string;

    private transient String scheme;

    private transient String schemespecificpart;

    private transient String authority;

    private transient String userinfo;

    private transient String host;

    private transient int port = -1;

    private transient String path;

    private transient String query;

    private transient String fragment;

    private transient boolean opaque;

    private transient boolean absolute;

    private transient boolean serverAuthority = false;

    private transient int hash = -1;

    private URI() {
    }

    /**
     * Creates a new URI instance according to the given string {@code uri}.
     *
     * @param uri
     *            the textual URI representation to be parsed into a URI object.
     * @throws URISyntaxException
     *             if the given string {@code uri} doesn't fit to the
     *             specification RFC2396 or could not be parsed correctly.
     */
    public URI(String uri) throws URISyntaxException {
        new Helper().parseURI(uri, false);
    }

    /**
     * Creates a new URI instance using the given arguments. This constructor
     * first creates a temporary URI string from the given components. This
     * string will be parsed later on to create the URI instance.
     * <p>
     * {@code [scheme:]scheme-specific-part[#fragment]}
     *
     * @param scheme
     *            the scheme part of the URI.
     * @param ssp
     *            the scheme-specific-part of the URI.
     * @param frag
     *            the fragment part of the URI.
     * @throws URISyntaxException
     *             if the temporary created string doesn't fit to the
     *             specification RFC2396 or could not be parsed correctly.
     */
    public URI(String scheme, String ssp, String frag)
            throws URISyntaxException {
        StringBuilder uri = new StringBuilder();
        if (scheme != null) {
            uri.append(scheme);
            uri.append(':');
        }
        if (ssp != null) {
            // QUOTE ILLEGAL CHARACTERS
            uri.append(quoteComponent(ssp, allLegal));
        }
        if (frag != null) {
            uri.append('#');
            // QUOTE ILLEGAL CHARACTERS
            uri.append(quoteComponent(frag, allLegal));
        }

        new Helper().parseURI(uri.toString(), false);
    }

    /**
     * Creates a new URI instance using the given arguments. This constructor
     * first creates a temporary URI string from the given components. This
     * string will be parsed later on to create the URI instance.
     * <p>
     * {@code [scheme:][user-info@]host[:port][path][?query][#fragment]}
     *
     * @param scheme
     *            the scheme part of the URI.
     * @param userinfo
     *            the user information of the URI for authentication and
     *            authorization.
     * @param host
     *            the host name of the URI.
     * @param port
     *            the port number of the URI.
     * @param path
     *            the path to the resource on the host.
     * @param query
     *            the query part of the URI to specify parameters for the
     *            resource.
     * @param fragment
     *            the fragment part of the URI.
     * @throws URISyntaxException
     *             if the temporary created string doesn't fit to the
     *             specification RFC2396 or could not be parsed correctly.
     */
    public URI(String scheme, String userinfo, String host, int port,
            String path, String query, String fragment)
            throws URISyntaxException {

        if (scheme == null && userinfo == null && host == null && path == null
                && query == null && fragment == null) {
            this.path = ""; //$NON-NLS-1$
            return;
        }

        if (scheme != null && path != null && path.length() > 0
                && path.charAt(0) != '/') {
            throw new URISyntaxException(path, Messages.getString("luni.82")); //$NON-NLS-1$
        }

        StringBuilder uri = new StringBuilder();
        if (scheme != null) {
            uri.append(scheme);
            uri.append(':');
        }

        if (userinfo != null || host != null || port != -1) {
            uri.append("//"); //$NON-NLS-1$
        }

        if (userinfo != null) {
            // QUOTE ILLEGAL CHARACTERS in userinfo
            uri.append(quoteComponent(userinfo, someLegal));
            uri.append('@');
        }

        if (host != null) {
            // check for ipv6 addresses that hasn't been enclosed
            // in square brackets
            if (host.indexOf(':') != -1 && host.indexOf(']') == -1
                    && host.indexOf('[') == -1) {
                host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
            }
            uri.append(host);
        }

        if (port != -1) {
            uri.append(':');
            uri.append(port);
        }

        if (path != null) {
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(path, "/@" + someLegal)); //$NON-NLS-1$
        }

        if (query != null) {
            uri.append('?');
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(query, allLegal));
        }

        if (fragment != null) {
            // QUOTE ILLEGAL CHARS
            uri.append('#');
            uri.append(quoteComponent(fragment, allLegal));
        }

        new Helper().parseURI(uri.toString(), true);
    }

    /**
     * Creates a new URI instance using the given arguments. This constructor
     * first creates a temporary URI string from the given components. This
     * string will be parsed later on to create the URI instance.
     * <p>
     * {@code [scheme:]host[path][#fragment]}
     *
     * @param scheme
     *            the scheme part of the URI.
     * @param host
     *            the host name of the URI.
     * @param path
     *            the path to the resource on the host.
     * @param fragment
     *            the fragment part of the URI.
     * @throws URISyntaxException
     *             if the temporary created string doesn't fit to the
     *             specification RFC2396 or could not be parsed correctly.
     */
    public URI(String scheme, String host, String path, String fragment)
            throws URISyntaxException {
        this(scheme, null, host, -1, path, null, fragment);
    }

    /**
     * Creates a new URI instance using the given arguments. This constructor
     * first creates a temporary URI string from the given components. This
     * string will be parsed later on to create the URI instance.
     * <p>
     * {@code [scheme:][//authority][path][?query][#fragment]}
     *
     * @param scheme
     *            the scheme part of the URI.
     * @param authority
     *            the authority part of the URI.
     * @param path
     *            the path to the resource on the host.
     * @param query
     *            the query part of the URI to specify parameters for the
     *            resource.
     * @param fragment
     *            the fragment part of the URI.
     * @throws URISyntaxException
     *             if the temporary created string doesn't fit to the
     *             specification RFC2396 or could not be parsed correctly.
     */
    public URI(String scheme, String authority, String path, String query,
            String fragment) throws URISyntaxException {
        if (scheme != null && path != null && path.length() > 0
                && path.charAt(0) != '/') {
            throw new URISyntaxException(path, Messages.getString("luni.82")); //$NON-NLS-1$
        }

        StringBuilder uri = new StringBuilder();
        if (scheme != null) {
            uri.append(scheme);
            uri.append(':');
        }
        if (authority != null) {
            uri.append("//"); //$NON-NLS-1$
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(authority, "@[]" + someLegal)); //$NON-NLS-1$
        }

        if (path != null) {
            // QUOTE ILLEGAL CHARS
            uri.append(quoteComponent(path, "/@" + someLegal)); //$NON-NLS-1$
        }
        if (query != null) {
            // QUOTE ILLEGAL CHARS
            uri.append('?');
            uri.append(quoteComponent(query, allLegal));
        }
        if (fragment != null) {
            // QUOTE ILLEGAL CHARS
            uri.append('#');
            uri.append(quoteComponent(fragment, allLegal));
        }

        new Helper().parseURI(uri.toString(), false);
    }

    private class Helper {

        private void parseURI(String uri, boolean forceServer)
                throws URISyntaxException {
            String temp = uri;
            // assign uri string to the input value per spec
            string = uri;
            int index, index1, index2, index3;
            // parse into Fragment, Scheme, and SchemeSpecificPart
            // then parse SchemeSpecificPart if necessary

            // Fragment
            index = temp.indexOf('#');
            if (index != -1) {
                // remove the fragment from the end
                fragment = temp.substring(index + 1);
                validateFragment(uri, fragment, index + 1);
                temp = temp.substring(0, index);
            }

            // Scheme and SchemeSpecificPart
            index = index1 = temp.indexOf(':');
            index2 = temp.indexOf('/');
            index3 = temp.indexOf('?');

            // if a '/' or '?' occurs before the first ':' the uri has no
            // specified scheme, and is therefore not absolute
            if (index != -1 && (index2 >= index || index2 == -1)
                    && (index3 >= index || index3 == -1)) {
                // the characters up to the first ':' comprise the scheme
                absolute = true;
                scheme = temp.substring(0, index);
                if (scheme.length() == 0) {
                    throw new URISyntaxException(uri, Messages.getString("luni.83"), //$NON-NLS-1$
                            index);
                }
                validateScheme(uri, scheme, 0);
                schemespecificpart = temp.substring(index + 1);
                if (schemespecificpart.length() == 0) {
                    throw new URISyntaxException(uri, Messages.getString("luni.84"), //$NON-NLS-1$
                            index + 1);
                }
            } else {
                absolute = false;
                schemespecificpart = temp;
            }

            if (scheme == null || schemespecificpart.length() > 0
                    && schemespecificpart.charAt(0) == '/') {
                opaque = false;
                // the URI is hierarchical

                // Query
                temp = schemespecificpart;
                index = temp.indexOf('?');
                if (index != -1) {
                    query = temp.substring(index + 1);
                    temp = temp.substring(0, index);
                    validateQuery(uri, query, index2 + 1 + index);
                }

                // Authority and Path
                if (temp.startsWith("//")) { //$NON-NLS-1$
                    index = temp.indexOf('/', 2);
                    if (index != -1) {
                        authority = temp.substring(2, index);
                        path = temp.substring(index);
                    } else {
                        authority = temp.substring(2);
                        if (authority.length() == 0 && query == null
                                && fragment == null) {
                            throw new URISyntaxException(uri, Messages
                                    .getString("luni.9F"), uri.length()); //$NON-NLS-1$
                        }

                        path = ""; //$NON-NLS-1$
                        // nothing left, so path is empty (not null, path should
                        // never be null)
                    }

                    if (authority.length() == 0) {
                        authority = null;
                    } else {
                        validateAuthority(uri, authority, index1 + 3);
                    }
                } else { // no authority specified
                    path = temp;
                }

                int pathIndex = 0;
                if (index2 > -1) {
                    pathIndex += index2;
                }
                if (index > -1) {
                    pathIndex += index;
                }
                validatePath(uri, path, pathIndex);
            } else { // if not hierarchical, URI is opaque
                opaque = true;
                validateSsp(uri, schemespecificpart, index2 + 2 + index);
            }

            parseAuthority(forceServer);
        }

        private void validateScheme(String uri, String scheme, int index)
                throws URISyntaxException {
            // first char needs to be an alpha char
            char ch = scheme.charAt(0);
            if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
                throw new URISyntaxException(uri, Messages.getString("luni.85"), 0); //$NON-NLS-1$
            }

            try {
                URIEncoderDecoder.validateSimple(scheme, "+-."); //$NON-NLS-1$
            } catch (URISyntaxException e) {
                throw new URISyntaxException(uri, Messages.getString("luni.85"), index //$NON-NLS-1$
                        + e.getIndex());
            }
        }

        private void validateSsp(String uri, String ssp, int index)
                throws URISyntaxException {
            try {
                URIEncoderDecoder.validate(ssp, allLegal);
            } catch (URISyntaxException e) {
                throw new URISyntaxException(uri, Messages.getString("luni.86", e //$NON-NLS-1$
                        .getReason()), index + e.getIndex());
            }
        }

        private void validateAuthority(String uri, String authority, int index)
                throws URISyntaxException {
            try {
                URIEncoderDecoder.validate(authority, "@[]" + someLegal); //$NON-NLS-1$
            } catch (URISyntaxException e) {
                throw new URISyntaxException(uri, Messages.getString("luni.87", e //$NON-NLS-1$
                        .getReason()), index + e.getIndex());
            }
        }

        private void validatePath(String uri, String path, int index)
                throws URISyntaxException {
            try {
                URIEncoderDecoder.validate(path, "/@" + someLegal); //$NON-NLS-1$
            } catch (URISyntaxException e) {
                throw new URISyntaxException(uri, Messages.getString("luni.88", e //$NON-NLS-1$
                        .getReason()), index + e.getIndex());
            }
        }

        private void validateQuery(String uri, String query, int index)
                throws URISyntaxException {
            try {
                URIEncoderDecoder.validate(query, allLegal);
            } catch (URISyntaxException e) {
                throw new URISyntaxException(uri, Messages.getString("luni.89", e //$NON-NLS-1$
                        .getReason()), index + e.getIndex());

            }
        }

        private void validateFragment(String uri, String fragment, int index)
                throws URISyntaxException {
            try {
                URIEncoderDecoder.validate(fragment, allLegal);
            } catch (URISyntaxException e) {
                throw new URISyntaxException(uri, Messages.getString("luni.8A", e //$NON-NLS-1$
                        .getReason()), index + e.getIndex());
            }
        }

        /**
         * determine the host, port and userinfo if the authority parses
         * successfully to a server based authority
         * 
         * behavour in error cases: if forceServer is true, throw
         * URISyntaxException with the proper diagnostic messages. if
         * forceServer is false assume this is a registry based uri, and just
         * return leaving the host, port and userinfo fields undefined.
         * 
         * and there are some error cases where URISyntaxException is thrown
         * regardless of the forceServer parameter e.g. malformed ipv6 address
         */
        private void parseAuthority(boolean forceServer)
                throws URISyntaxException {
            if (authority == null) {
                return;
            }

            String temp, tempUserinfo = null, tempHost = null;
            int index, hostindex = 0;
            int tempPort = -1;

            temp = authority;
            index = temp.indexOf('@');
            if (index != -1) {
                // remove user info
                tempUserinfo = temp.substring(0, index);
                validateUserinfo(authority, tempUserinfo, 0);
                temp = temp.substring(index + 1); // host[:port] is left
                hostindex = index + 1;
            }

            index = temp.lastIndexOf(':');
            int endindex = temp.indexOf(']');

            if (index != -1 && endindex < index) {
                // determine port and host
                tempHost = temp.substring(0, index);

                if (index < (temp.length() - 1)) { // port part is not empty
                    try {
                        tempPort = Integer.parseInt(temp.substring(index + 1));
                        if (tempPort < 0) {
                            if (forceServer) {
                                throw new URISyntaxException(
                                        authority,
                                        Messages.getString("luni.8B"), hostindex + index + 1); //$NON-NLS-1$
                            }
                            return;
                        }
                    } catch (NumberFormatException e) {
                        if (forceServer) {
                            throw new URISyntaxException(authority, Messages
                                    .getString("luni.8B"), hostindex + index + 1); //$NON-NLS-1$
                        }
                        return;
                    }
                }
            } else {
                tempHost = temp;
            }

            if (tempHost.equals("")) { //$NON-NLS-1$
                if (forceServer) {
                    throw new URISyntaxException(authority, Messages
                            .getString("luni.A0"), hostindex); //$NON-NLS-1$
                }
                return;
            }

            if (!isValidHost(forceServer, tempHost)) {
                return;
            }

            // this is a server based uri,
            // fill in the userinfo, host and port fields
            userinfo = tempUserinfo;
            host = tempHost;
            port = tempPort;
            serverAuthority = true;
        }

        private void validateUserinfo(String uri, String userinfo, int index)
                throws URISyntaxException {
            for (int i = 0; i < userinfo.length(); i++) {
                char ch = userinfo.charAt(i);
                if (ch == ']' || ch == '[') {
                    throw new URISyntaxException(uri, Messages.getString("luni.8C"), //$NON-NLS-1$
                            index + i);
                }
            }
        }

        /**
         * distinguish between IPv4, IPv6, domain name and validate it based on
         * its type
         */
        private boolean isValidHost(boolean forceServer, String host)
                throws URISyntaxException {
            if (host.charAt(0) == '[') {
                // ipv6 address
                if (host.charAt(host.length() - 1) != ']') {
                    throw new URISyntaxException(host,
                            Messages.getString("luni.8D"), 0); //$NON-NLS-1$
                }
                if (!isValidIP6Address(host)) {
                    throw new URISyntaxException(host, Messages.getString("luni.8E")); //$NON-NLS-1$
                }
                return true;
            }

            // '[' and ']' can only be the first char and last char
            // of the host name
            if (host.indexOf('[') != -1 || host.indexOf(']') != -1) {
                throw new URISyntaxException(host, Messages.getString("luni.8F"), 0); //$NON-NLS-1$
            }

            int index = host.lastIndexOf('.');
            if (index < 0 || index == host.length() - 1
                    || !Character.isDigit(host.charAt(index + 1))) {
                // domain name
                if (isValidDomainName(host)) {
                    return true;
                }
                if (forceServer) {
                    throw new URISyntaxException(host,
                            Messages.getString("luni.8F"), 0); //$NON-NLS-1$
                }
                return false;
            }

            // IPv4 address
            if (isValidIPv4Address(host)) {
                return true;
            }
            if (forceServer) {
                throw new URISyntaxException(host, Messages.getString("luni.90"), 0); //$NON-NLS-1$
            }
            return false;
        }

        private boolean isValidDomainName(String host) {
            try {
                URIEncoderDecoder.validateSimple(host, "-."); //$NON-NLS-1$
            } catch (URISyntaxException e) {
                return false;
            }

            String label = null;
            StringTokenizer st = new StringTokenizer(host, "."); //$NON-NLS-1$
            while (st.hasMoreTokens()) {
                label = st.nextToken();
                if (label.startsWith("-") || label.endsWith("-")) { //$NON-NLS-1$ //$NON-NLS-2$
                    return false;
                }
            }

            if (!label.equals(host)) {
                char ch = label.charAt(0);
                if (ch >= '0' && ch <= '9') {
                    return false;
                }
            }
            return true;
        }

        private boolean isValidIPv4Address(String host) {
            int index;
            int index2;
            try {
                int num;
                index = host.indexOf('.');
                num = Integer.parseInt(host.substring(0, index));
                if (num < 0 || num > 255) {
                    return false;
                }
                index2 = host.indexOf('.', index + 1);
                num = Integer.parseInt(host.substring(index + 1, index2));
                if (num < 0 || num > 255) {
                    return false;
                }
                index = host.indexOf('.', index2 + 1);
                num = Integer.parseInt(host.substring(index2 + 1, index));
                if (num < 0 || num > 255) {
                    return false;
                }
                num = Integer.parseInt(host.substring(index + 1));
                if (num < 0 || num > 255) {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        private boolean isValidIP6Address(String ipAddress) {
            int length = ipAddress.length();
            boolean doubleColon = false;
            int numberOfColons = 0;
            int numberOfPeriods = 0;
            String word = ""; //$NON-NLS-1$
            char c = 0;
            char prevChar = 0;
            int offset = 0; // offset for [] ip addresses

            if (length < 2) {
                return false;
            }

            for (int i = 0; i < length; i++) {
                prevChar = c;
                c = ipAddress.charAt(i);
                switch (c) {

                    // case for an open bracket [x:x:x:...x]
                    case '[':
                        if (i != 0) {
                            return false; // must be first character
                        }
                        if (ipAddress.charAt(length - 1) != ']') {
                            return false; // must have a close ]
                        }
                        if ((ipAddress.charAt(1) == ':')
                                && (ipAddress.charAt(2) != ':')) {
                            return false;
                        }
                        offset = 1;
                        if (length < 4) {
                            return false;
                        }
                        break;

                    // case for a closed bracket at end of IP [x:x:x:...x]
                    case ']':
                        if (i != length - 1) {
                            return false; // must be last character
                        }
                        if (ipAddress.charAt(0) != '[') {
                            return false; // must have a open [
                        }
                        break;

                    // case for the last 32-bits represented as IPv4
                    // x:x:x:x:x:x:d.d.d.d
                    case '.':
                        numberOfPeriods++;
                        if (numberOfPeriods > 3) {
                            return false;
                        }
                        if (!isValidIP4Word(word)) {
                            return false;
                        }
                        if (numberOfColons != 6 && !doubleColon) {
                            return false;
                        }
                        // a special case ::1:2:3:4:5:d.d.d.d allows 7 colons
                        // with
                        // an IPv4 ending, otherwise 7 :'s is bad
                        if (numberOfColons == 7
                                && ipAddress.charAt(0 + offset) != ':'
                                && ipAddress.charAt(1 + offset) != ':') {
                            return false;
                        }
                        word = ""; //$NON-NLS-1$
                        break;

                    case ':':
                        numberOfColons++;
                        if (numberOfColons > 7) {
                            return false;
                        }
                        if (numberOfPeriods > 0) {
                            return false;
                        }
                        if (prevChar == ':') {
                            if (doubleColon) {
                                return false;
                            }
                            doubleColon = true;
                        }
                        word = ""; //$NON-NLS-1$
                        break;

                    default:
                        if (word.length() > 3) {
                            return false;
                        }
                        if (!isValidHexChar(c)) {
                            return false;
                        }
                        word += c;
                }
            }

            // Check if we have an IPv4 ending
            if (numberOfPeriods > 0) {
                if (numberOfPeriods != 3 || !isValidIP4Word(word)) {
                    return false;
                }
            } else {
                // If we're at then end and we haven't had 7 colons then there
                // is a problem unless we encountered a doubleColon
                if (numberOfColons != 7 && !doubleColon) {
                    return false;
                }

                // If we have an empty word at the end, it means we ended in
                // either a : or a .
                // If we did not end in :: then this is invalid
                if (word == "" && ipAddress.charAt(length - 1 - offset) != ':' //$NON-NLS-1$
                        && ipAddress.charAt(length - 2 - offset) != ':') {
                    return false;
                }
            }

            return true;
        }

        private boolean isValidIP4Word(String word) {
            char c;
            if (word.length() < 1 || word.length() > 3) {
                return false;
            }
            for (int i = 0; i < word.length(); i++) {
                c = word.charAt(i);
                if (!(c >= '0' && c <= '9')) {
                    return false;
                }
            }
            if (Integer.parseInt(word) > 255) {
                return false;
            }
            return true;
        }

        private boolean isValidHexChar(char c) {

            return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
                    || (c >= 'a' && c <= 'f');
        }
    }

    /*
     * Quote illegal chars for each component, but not the others
     * 
     * @param component java.lang.String the component to be converted @param
     * legalset java.lang.String the legal character set allowed in the
     * component s @return java.lang.String the converted string
     */
    private String quoteComponent(String component, String legalset) {
        try {
            /*
             * Use a different encoder than URLEncoder since: 1. chars like "/",
             * "#", "@" etc needs to be preserved instead of being encoded, 2.
             * UTF-8 char set needs to be used for encoding instead of default
             * platform one
             */
            return URIEncoderDecoder.quoteIllegal(component, legalset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Compares this URI with the given argument {@code uri}. This method will
     * return a negative value if this URI instance is less than the given
     * argument and a positive value if this URI instance is greater than the
     * given argument. The return value {@code 0} indicates that the two
     * instances represent the same URI. To define the order the single parts of
     * the URI are compared with each other. String components will be orderer
     * in the natural case-sensitive way. A hierarchical URI is less than an
     * opaque URI and if one part is {@code null} the URI with the undefined
     * part is less than the other one.
     *
     * @param uri
     *            the URI this instance has to compare with.
     * @return the value representing the order of the two instances.
     */
    public int compareTo(URI uri) {
        int ret = 0;

        // compare schemes
        if (scheme == null && uri.scheme != null) {
            return -1;
        } else if (scheme != null && uri.scheme == null) {
            return 1;
        } else if (scheme != null && uri.scheme != null) {
            ret = scheme.compareToIgnoreCase(uri.scheme);
            if (ret != 0) {
                return ret;
            }
        }

        // compare opacities
        if (!opaque && uri.opaque) {
            return -1;
        } else if (opaque && !uri.opaque) {
            return 1;
        } else if (opaque && uri.opaque) {
            ret = schemespecificpart.compareTo(uri.schemespecificpart);
            if (ret != 0) {
                return ret;
            }
        } else {

            // otherwise both must be hierarchical

            // compare authorities
            if (authority != null && uri.authority == null) {
                return 1;
            } else if (authority == null && uri.authority != null) {
                return -1;
            } else if (authority != null && uri.authority != null) {
                if (host != null && uri.host != null) {
                    // both are server based, so compare userinfo, host, port
                    if (userinfo != null && uri.userinfo == null) {
                        return 1;
                    } else if (userinfo == null && uri.userinfo != null) {
                        return -1;
                    } else if (userinfo != null && uri.userinfo != null) {
                        ret = userinfo.compareTo(uri.userinfo);
                        if (ret != 0) {
                            return ret;
                        }
                    }

                    // userinfo's are the same, compare hostname
                    ret = host.compareToIgnoreCase(uri.host);
                    if (ret != 0) {
                        return ret;
                    }

                    // compare port
                    if (port != uri.port) {
                        return port - uri.port;
                    }
                } else { // one or both are registry based, compare the whole
                    // authority
                    ret = authority.compareTo(uri.authority);
                    if (ret != 0) {
                        return ret;
                    }
                }
            }

            // authorities are the same
            // compare paths
            ret = path.compareTo(uri.path);
            if (ret != 0) {
                return ret;
            }

            // compare queries

            if (query != null && uri.query == null) {
                return 1;
            } else if (query == null && uri.query != null) {
                return -1;
            } else if (query != null && uri.query != null) {
                ret = query.compareTo(uri.query);
                if (ret != 0) {
                    return ret;
                }
            }
        }

        // everything else is identical, so compare fragments
        if (fragment != null && uri.fragment == null) {
            return 1;
        } else if (fragment == null && uri.fragment != null) {
            return -1;
        } else if (fragment != null && uri.fragment != null) {
            ret = fragment.compareTo(uri.fragment);
            if (ret != 0) {
                return ret;
            }
        }

        // identical
        return 0;
    }

    /**
     * Parses the given argument {@code uri} and creates an appropriate URI
     * instance.
     *
     * @param uri
     *            the string which has to be parsed to create the URI instance.
     * @return the created instance representing the given URI.
     */
    public static URI create(String uri) {
        URI result = null;
        try {
            result = new URI(uri);
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
        return result;
    }

    private URI duplicate() {
        URI clone = new URI();
        clone.absolute = absolute;
        clone.authority = authority;
        clone.fragment = fragment;
        clone.host = host;
        clone.opaque = opaque;
        clone.path = path;
        clone.port = port;
        clone.query = query;
        clone.scheme = scheme;
        clone.schemespecificpart = schemespecificpart;
        clone.userinfo = userinfo;
        clone.serverAuthority = serverAuthority;
        return clone;
    }

    /*
     * Takes a string that may contain hex sequences like %F1 or %2b and
     * converts the hex values following the '%' to lowercase
     */
    private String convertHexToLowerCase(String s) {
        StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
        if (s.indexOf('%') == -1) {
            return s;
        }

        int index = 0, previndex = 0;
        while ((index = s.indexOf('%', previndex)) != -1) {
            result.append(s.substring(previndex, index + 1));
            result.append(s.substring(index + 1, index + 3).toLowerCase());
            index += 3;
            previndex = index;
        }
        return result.toString();
    }

    /*
     * Takes two strings that may contain hex sequences like %F1 or %2b and
     * compares them, ignoring case for the hex values hex values must always
     * occur in pairs like above
     */
    private boolean equalsHexCaseInsensitive(String first, String second) {
        if (first.indexOf('%') != second.indexOf('%')) {
            return first.equals(second);
        }

        int index = 0, previndex = 0;
        while ((index = first.indexOf('%', previndex)) != -1
                && second.indexOf('%', previndex) == index) {
            boolean match = first.substring(previndex, index).equals(
                    second.substring(previndex, index));
            if (!match) {
                return false;
            }

            match = first.substring(index + 1, index + 3).equalsIgnoreCase(
                    second.substring(index + 1, index + 3));
            if (!match) {
                return false;
            }

            index += 3;
            previndex = index;
        }
        return first.substring(previndex).equals(second.substring(previndex));
    }

    /**
     * Compares this URI instance with the given argument {@code o} and
     * determines if both are equal. Two URI instances are equal if all single
     * parts are identical in their meaning.
     *
     * @param o
     *            the URI this instance has to be compared with.
     * @return {@code true} if both URI instances point to the same resource,
     *         {@code false} otherwise.
     */
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof URI)) {
            return false;
        }
        URI uri = (URI) o;

        if (uri.fragment == null && fragment != null || uri.fragment != null
                && fragment == null) {
            return false;
        } else if (uri.fragment != null && fragment != null) {
            if (!equalsHexCaseInsensitive(uri.fragment, fragment)) {
                return false;
            }
        }

        if (uri.scheme == null && scheme != null || uri.scheme != null
                && scheme == null) {
            return false;
        } else if (uri.scheme != null && scheme != null) {
            if (!uri.scheme.equalsIgnoreCase(scheme)) {
                return false;
            }
        }

        if (uri.opaque && opaque) {
            return equalsHexCaseInsensitive(uri.schemespecificpart,
                    schemespecificpart);
        } else if (!uri.opaque && !opaque) {
            if (!equalsHexCaseInsensitive(path, uri.path)) {
                return false;
            }

            if (uri.query != null && query == null || uri.query == null
                    && query != null) {
                return false;
            } else if (uri.query != null && query != null) {
                if (!equalsHexCaseInsensitive(uri.query, query)) {
                    return false;
                }
            }

            if (uri.authority != null && authority == null
                    || uri.authority == null && authority != null) {
                return false;
            } else if (uri.authority != null && authority != null) {
                if (uri.host != null && host == null || uri.host == null
                        && host != null) {
                    return false;
                } else if (uri.host == null && host == null) {
                    // both are registry based, so compare the whole authority
                    return equalsHexCaseInsensitive(uri.authority, authority);
                } else { // uri.host != null && host != null, so server-based
                    if (!host.equalsIgnoreCase(uri.host)) {
                        return false;
                    }

                    if (port != uri.port) {
                        return false;
                    }

                    if (uri.userinfo != null && userinfo == null
                            || uri.userinfo == null && userinfo != null) {
                        return false;
                    } else if (uri.userinfo != null && userinfo != null) {
                        return equalsHexCaseInsensitive(userinfo, uri.userinfo);
                    } else {
                        return true;
                    }
                }
            } else {
                // no authority
                return true;
            }

        } else {
            // one is opaque, the other hierarchical
            return false;
        }
    }

    /**
     * Gets the decoded authority part of this URI.
     *
     * @return the decoded authority part or {@code null} if undefined.
     */
    public String getAuthority() {
        return decode(authority);
    }

    /**
     * Gets the decoded fragment part of this URI.
     * 
     * @return the decoded fragment part or {@code null} if undefined.
     */
    public String getFragment() {
        return decode(fragment);
    }

    /**
     * Gets the host part of this URI.
     * 
     * @return the host part or {@code null} if undefined.
     */
    public String getHost() {
        return host;
    }

    /**
     * Gets the decoded path part of this URI.
     * 
     * @return the decoded path part or {@code null} if undefined.
     */
    public String getPath() {
        return decode(path);
    }

    /**
     * Gets the port number of this URI.
     * 
     * @return the port number or {@code -1} if undefined.
     */
    public int getPort() {
        return port;
    }

    /**
     * Gets the decoded query part of this URI.
     * 
     * @return the decoded query part or {@code null} if undefined.
     */
    public String getQuery() {
        return decode(query);
    }

    /**
     * Gets the authority part of this URI in raw form.
     * 
     * @return the encoded authority part or {@code null} if undefined.
     */
    public String getRawAuthority() {
        return authority;
    }

    /**
     * Gets the fragment part of this URI in raw form.
     * 
     * @return the encoded fragment part or {@code null} if undefined.
     */
    public String getRawFragment() {
        return fragment;
    }

    /**
     * Gets the path part of this URI in raw form.
     * 
     * @return the encoded path part or {@code null} if undefined.
     */
    public String getRawPath() {
        return path;
    }

    /**
     * Gets the query part of this URI in raw form.
     * 
     * @return the encoded query part or {@code null} if undefined.
     */
    public String getRawQuery() {
        return query;
    }

    /**
     * Gets the scheme-specific part of this URI in raw form.
     * 
     * @return the encoded scheme-specific part or {@code null} if undefined.
     */
    public String getRawSchemeSpecificPart() {
        return schemespecificpart;
    }

    /**
     * Gets the user-info part of this URI in raw form.
     * 
     * @return the encoded user-info part or {@code null} if undefined.
     */
    public String getRawUserInfo() {
        return userinfo;
    }

    /**
     * Gets the scheme part of this URI.
     * 
     * @return the scheme part or {@code null} if undefined.
     */
    public String getScheme() {
        return scheme;
    }

    /**
     * Gets the decoded scheme-specific part of this URI.
     * 
     * @return the decoded scheme-specific part or {@code null} if undefined.
     */
    public String getSchemeSpecificPart() {
        return decode(schemespecificpart);
    }

    /**
     * Gets the decoded user-info part of this URI.
     * 
     * @return the decoded user-info part or {@code null} if undefined.
     */
    public String getUserInfo() {
        return decode(userinfo);
    }

    /**
     * Gets the hashcode value of this URI instance.
     *
     * @return the appropriate hashcode value.
     */
    @Override
    public int hashCode() {
        if (hash == -1) {
            hash = getHashString().hashCode();
        }
        return hash;
    }

    /**
     * Indicates whether this URI is absolute, which means that a scheme part is
     * defined in this URI.
     * 
     * @return {@code true} if this URI is absolute, {@code false} otherwise.
     */
    public boolean isAbsolute() {
        return absolute;
    }

    /**
     * Indicates whether this URI is opaque or not. An opaque URI is absolute
     * and has a scheme-specific part which does not start with a slash
     * character. All parts except scheme, scheme-specific and fragment are
     * undefined.
     * 
     * @return {@code true} if the URI is opaque, {@code false} otherwise.
     */
    public boolean isOpaque() {
        return opaque;
    }

    /*
     * normalize path, and return the resulting string
     */
    private String normalize(String path) {
        // count the number of '/'s, to determine number of segments
        int index = -1;
        int pathlen = path.length();
        int size = 0;
        if (pathlen > 0 && path.charAt(0) != '/') {
            size++;
        }
        while ((index = path.indexOf('/', index + 1)) != -1) {
            if (index + 1 < pathlen && path.charAt(index + 1) != '/') {
                size++;
            }
        }

        String[] seglist = new String[size];
        boolean[] include = new boolean[size];

        // break the path into segments and store in the list
        int current = 0;
        int index2 = 0;
        index = (pathlen > 0 && path.charAt(0) == '/') ? 1 : 0;
        while ((index2 = path.indexOf('/', index + 1)) != -1) {
            seglist[current++] = path.substring(index, index2);
            index = index2 + 1;
        }

        // if current==size, then the last character was a slash
        // and there are no more segments
        if (current < size) {
            seglist[current] = path.substring(index);
        }

        // determine which segments get included in the normalized path
        for (int i = 0; i < size; i++) {
            include[i] = true;
            if (seglist[i].equals("..")) { //$NON-NLS-1$
                int remove = i - 1;
                // search back to find a segment to remove, if possible
                while (remove > -1 && !include[remove]) {
                    remove--;
                }
                // if we find a segment to remove, remove it and the ".."
                // segment
                if (remove > -1 && !seglist[remove].equals("..")) { //$NON-NLS-1$
                    include[remove] = false;
                    include[i] = false;
                }
            } else if (seglist[i].equals(".")) { //$NON-NLS-1$
                include[i] = false;
            }
        }

        // put the path back together
        StringBuilder newpath = new StringBuilder();
        if (path.startsWith("/")) { //$NON-NLS-1$
            newpath.append('/');
        }

        for (int i = 0; i < seglist.length; i++) {
            if (include[i]) {
                newpath.append(seglist[i]);
                newpath.append('/');
            }
        }

        // if we used at least one segment and the path previously ended with
        // a slash and the last segment is still used, then delete the extra
        // trailing '/'
        if (!path.endsWith("/") && seglist.length > 0 //$NON-NLS-1$
                && include[seglist.length - 1]) {
            newpath.deleteCharAt(newpath.length() - 1);
        }

        String result = newpath.toString();

        // check for a ':' in the first segment if one exists,
        // prepend "./" to normalize
        index = result.indexOf(':');
        index2 = result.indexOf('/');
        if (index != -1 && (index < index2 || index2 == -1)) {
            newpath.insert(0, "./"); //$NON-NLS-1$
            result = newpath.toString();
        }
        return result;
    }

    /**
     * Normalizes the path part of this URI.
     *
     * @return an URI object which represents this instance with a normalized
     *         path.
     */
    public URI normalize() {
        if (opaque) {
            return this;
        }
        String normalizedPath = normalize(path);
        // if the path is already normalized, return this
        if (path.equals(normalizedPath)) {
            return this;
        }
        // get an exact copy of the URI re-calculate the scheme specific part
        // since the path of the normalized URI is different from this URI.
        URI result = duplicate();
        result.path = normalizedPath;
        result.setSchemeSpecificPart();
        return result;
    }

    /**
     * Tries to parse the authority component of this URI to divide it into the
     * host, port, and user-info. If this URI is already determined as a
     * ServerAuthority this instance will be returned without changes.
     *
     * @return this instance with the components of the parsed server authority.
     * @throws URISyntaxException
     *             if the authority part could not be parsed as a server-based
     *             authority.
     */
    public URI parseServerAuthority() throws URISyntaxException {
        if (!serverAuthority) {
            new Helper().parseAuthority(true);
        }
        return this;
    }

    /**
     * Makes the given URI {@code relative} to a relative URI against the URI
     * represented by this instance.
     *
     * @param relative
     *            the URI which has to be relativized against this URI.
     * @return the relative URI.
     */
    public URI relativize(URI relative) {
        if (relative.opaque || opaque) {
            return relative;
        }

        if (scheme == null ? relative.scheme != null : !scheme
                .equals(relative.scheme)) {
            return relative;
        }

        if (authority == null ? relative.authority != null : !authority
                .equals(relative.authority)) {
            return relative;
        }

        // normalize both paths
        String thisPath = normalize(path);
        String relativePath = normalize(relative.path);

        /*
         * if the paths aren't equal, then we need to determine if this URI's
         * path is a parent path (begins with) the relative URI's path
         */
        if (!thisPath.equals(relativePath)) {
            // if this URI's path doesn't end in a '/', add one
            if (!thisPath.endsWith("/")) { //$NON-NLS-1$
                thisPath = thisPath + '/';
            }
            /*
             * if the relative URI's path doesn't start with this URI's path,
             * then just return the relative URI; the URIs have nothing in
             * common
             */
            if (!relativePath.startsWith(thisPath)) {
                return relative;
            }
        }

        URI result = new URI();
        result.fragment = relative.fragment;
        result.query = relative.query;
        // the result URI is the remainder of the relative URI's path
        result.path = relativePath.substring(thisPath.length());
        result.setSchemeSpecificPart();
        return result;
    }

    /**
     * Resolves the given URI {@code relative} against the URI represented by
     * this instance.
     *
     * @param relative
     *            the URI which has to be resolved against this URI.
     * @return the resolved URI.
     */
    public URI resolve(URI relative) {
        if (relative.absolute || opaque) {
            return relative;
        }

        URI result;
        if (relative.path.equals("") && relative.scheme == null //$NON-NLS-1$
                && relative.authority == null && relative.query == null
                && relative.fragment != null) {
            // if the relative URI only consists of fragment,
            // the resolved URI is very similar to this URI,
            // except that it has the fragement from the relative URI.
            result = duplicate();
            result.fragment = relative.fragment;
            // no need to re-calculate the scheme specific part,
            // since fragment is not part of scheme specific part.
            return result;
        }

        if (relative.authority != null) {
            // if the relative URI has authority,
            // the resolved URI is almost the same as the relative URI,
            // except that it has the scheme of this URI.
            result = relative.duplicate();
            result.scheme = scheme;
            result.absolute = absolute;
        } else {
            // since relative URI has no authority,
            // the resolved URI is very similar to this URI,
            // except that it has the query and fragment of the relative URI,
            // and the path is different.
            result = duplicate();
            result.fragment = relative.fragment;
            result.query = relative.query;
            if (relative.path.startsWith("/")) { //$NON-NLS-1$
                result.path = relative.path;
            } else {
                // resolve a relative reference
                int endindex = path.lastIndexOf('/') + 1;
                result.path = normalize(path.substring(0, endindex)
                        + relative.path);
            }
            // re-calculate the scheme specific part since
            // query and path of the resolved URI is different from this URI.
            result.setSchemeSpecificPart();
        }
        return result;
    }

    /**
     * Helper method used to re-calculate the scheme specific part of the
     * resolved or normalized URIs
     */
    private void setSchemeSpecificPart() {
        // ssp = [//authority][path][?query]
        StringBuilder ssp = new StringBuilder();
        if (authority != null) {
            ssp.append("//" + authority); //$NON-NLS-1$
        }
        if (path != null) {
            ssp.append(path);
        }
        if (query != null) {
            ssp.append("?" + query); //$NON-NLS-1$
        }
        schemespecificpart = ssp.toString();
        // reset string, so that it can be re-calculated correctly when asked.
        string = null;
    }

    /**
     * Creates a new URI instance by parsing the given string {@code relative}
     * and resolves the created URI against the URI represented by this
     * instance.
     *
     * @param relative
     *            the given string to create the new URI instance which has to
     *            be resolved later on.
     * @return the created and resolved URI.
     */
    public URI resolve(String relative) {
        return resolve(create(relative));
    }

    /*
     * Encode unicode chars that are not part of US-ASCII char set into the
     * escaped form
     * 
     * i.e. The Euro currency symbol is encoded as "%E2%82%AC".
     * 
     * @param component java.lang.String the component to be converted @param
     * legalset java.lang.String the legal character set allowed in the
     * component s @return java.lang.String the converted string
     */
    private String encodeOthers(String s) {
        try {
            /*
             * Use a different encoder than URLEncoder since: 1. chars like "/",
             * "#", "@" etc needs to be preserved instead of being encoded, 2.
             * UTF-8 char set needs to be used for encoding instead of default
             * platform one 3. Only other chars need to be converted
             */
            return URIEncoderDecoder.encodeOthers(s);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private String decode(String s) {
        if (s == null) {
            return s;
        }

        try {
            return URIEncoderDecoder.decode(s);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Returns the textual string representation of this URI instance using the
     * US-ASCII encoding.
     *
     * @return the US-ASCII string representation of this URI.
     */
    public String toASCIIString() {
        return encodeOthers(toString());
    }

    /**
     * Returns the textual string representation of this URI instance.
     *
     * @return the textual string representation of this URI.
     */
    @Override
    public String toString() {
        if (string == null) {
            StringBuilder result = new StringBuilder();
            if (scheme != null) {
                result.append(scheme);
                result.append(':');
            }
            if (opaque) {
                result.append(schemespecificpart);
            } else {
                if (authority != null) {
                    result.append("//"); //$NON-NLS-1$
                    result.append(authority);
                }

                if (path != null) {
                    result.append(path);
                }

                if (query != null) {
                    result.append('?');
                    result.append(query);
                }
            }

            if (fragment != null) {
                result.append('#');
                result.append(fragment);
            }

            string = result.toString();
        }
        return string;
    }

    /*
     * Form a string from the components of this URI, similarly to the
     * toString() method. But this method converts scheme and host to lowercase,
     * and converts escaped octets to lowercase.
     */
    private String getHashString() {
        StringBuilder result = new StringBuilder();
        if (scheme != null) {
            result.append(scheme.toLowerCase());
            result.append(':');
        }
        if (opaque) {
            result.append(schemespecificpart);
        } else {
            if (authority != null) {
                result.append("//"); //$NON-NLS-1$
                if (host == null) {
                    result.append(authority);
                } else {
                    if (userinfo != null) {
                        result.append(userinfo + "@"); //$NON-NLS-1$
                    }
                    result.append(host.toLowerCase());
                    if (port != -1) {
                        result.append(":" + port); //$NON-NLS-1$
                    }
                }
            }

            if (path != null) {
                result.append(path);
            }

            if (query != null) {
                result.append('?');
                result.append(query);
            }
        }

        if (fragment != null) {
            result.append('#');
            result.append(fragment);
        }

        return convertHexToLowerCase(result.toString());
    }

    /**
     * Converts this URI instance to a URL.
     *
     * @return the created URL representing the same resource as this URI.
     * @throws MalformedURLException
     *             if an error occurs while creating the URL or no protocol
     *             handler could be found.
     */
    public URL toURL() throws MalformedURLException {
        if (!absolute) {
            throw new IllegalArgumentException(Messages.getString("luni.91") + ": " //$NON-NLS-1$//$NON-NLS-2$
                    + toString());
        }
        return new URL(toString());
    }

    private void readObject(ObjectInputStream in) throws IOException,
            ClassNotFoundException {
        in.defaultReadObject();
        try {
            new Helper().parseURI(string, false);
        } catch (URISyntaxException e) {
            throw new IOException(e.toString());
        }
    }

    private void writeObject(ObjectOutputStream out) throws IOException,
            ClassNotFoundException {
        // call toString() to ensure the value of string field is calculated
        toString();
        out.defaultWriteObject();
    }
}
