/* URI.java -- An URI class
   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * A URI instance represents that defined by 
 * <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC3986</a>,
 * with some deviations.
 * </p>
 * <p>
 * At its highest level, a URI consists of:
 * </p>
 * <code>[<em>scheme</em><strong>:</strong>]<em>scheme-specific-part</em>
 * [<strong>#</strong><em>fragment</em>]</code>
 * </p>
 * <p>
 * where <strong>#</strong> and <strong>:</strong> are literal characters,
 * and those parts enclosed in square brackets are optional.
 * </p>
 * <p>
 * There are two main types of URI.  An <em>opaque</em> URI is one
 * which just consists of the above three parts, and is not further
 * defined.  An example of such a URI would be <em>mailto:</em> URI.
 * In contrast, <em>hierarchical</em> URIs give further definition
 * to the scheme-specific part, so as represent some part of a hierarchical
 * structure.
 * </p>
 * <p>
 * <code>[<strong>//</strong><em>authority</em>][<em>path</em>]
 * [<strong>?</strong><em>query</em>]</code>
 * </p>
 * <p>
 * with <strong>/</strong> and <strong>?</strong> being literal characters.
 * When server-based, the authority section is further subdivided into:
 * </p>
 * <p>
 * <code>[<em>user-info</em><strong>@</strong>]<em>host</em>
 * [<strong>:</strong><em>port</em>]</code>
 * </p>
 * <p>
 * with <strong>@</strong> and <strong>:</strong> as literal characters.
 * Authority sections that are not server-based are said to be registry-based.
 * </p>
 * <p>
 * Hierarchical URIs can be either relative or absolute.  Absolute URIs
 * always start with a `<strong>/</strong>', while relative URIs don't
 * specify a scheme.  Opaque URIs are always absolute.
 * </p>
 * <p>
 * Each part of the URI may have one of three states: undefined, empty
 * or containing some content.  The former two of these are represented
 * by <code>null</code> and the empty string in Java, respectively.
 * The scheme-specific part may never be undefined.  It also follows from
 * this that the path sub-part may also not be undefined, so as to ensure
 * the former.
 * </p>
 * <h2>Character Escaping and Quoting</h2>
 * <p>
 * The characters that can be used within a valid URI are restricted.
 * There are two main classes of characters which can't be used as is
 * within the URI:
 * </p>
 * <ol>
 * <li><strong>Characters outside the US-ASCII character set</strong>.
 * These have to be <strong>escaped</strong> in order to create
 * an RFC-compliant URI; this means replacing the character with the
 * appropriate hexadecimal value, preceded by a `%'.</li>
 * <li><strong>Illegal characters</strong> (e.g. space characters,
 * control characters) are quoted, which results in them being encoded
 * in the same way as non-US-ASCII characters.</li>
 * </ol>
 * <p>
 * The set of valid characters differs depending on the section of the URI:
 * </p>
 * <ul>
 * <li><strong>Scheme</strong>: Must be an alphanumeric, `-', `.' or '+'.</li>
 * <li><strong>Authority</strong>:Composed of the username, host, port, `@'
 * and `:'.</li>
 * <li><strong>Username</strong>: Allows unreserved or percent-encoded
 * characters, sub-delimiters and `:'.</li>
 * <li><strong>Host</strong>: Allows unreserved or percent-encoded
 * characters, sub-delimiters and square brackets (`[' and `]') for IPv6
 * addresses.</li>
 * <li><strong>Port</strong>: Digits only.</li>
 * <li><strong>Path</strong>: Allows the path characters and `/'.
 * <li><strong>Query</strong>: Allows the path characters, `?' and '/'.
 * <li><strong>Fragment</strong>: Allows the path characters, `?' and '/'.
 * </ul>
 * <p>
 * These definitions reference the following sets of characters:
 * </p>
 * <ul>
 * <li><strong>Unreserved characters</strong>: The alphanumerics plus
 * `-', `.', `_', and `~'.</li>
 * <li><strong>Sub-delimiters</strong>: `!', `$', `&', `(', `)', `*',
 * `+', `,', `;', `=' and the single-quote itself.</li>
 * <li><strong>Path characters</strong>: Unreserved and percent-encoded
 * characters and the sub-delimiters along with `@' and `:'.</li>
 * </ul>
 * <p>
 * The constructors and accessor methods allow the use and retrieval of
 * URI components which contain non-US-ASCII characters directly.
 * They are only escaped when the <code>toASCIIString()</code> method
 * is used.  In contrast, illegal characters are always quoted, with the
 * exception of the return values of the non-raw accessors.
 * </p>
 *
 * @author Ito Kazumitsu (ito.kazumitsu@hitachi-cable.co.jp)
 * @author Dalibor Topic (robilad@kaffe.org)
 * @author Michael Koch (konqueror@gmx.de)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.4
 */
public final class URI 
  implements Comparable, Serializable
{
  /**
   * For serialization compatability.
   */
  static final long serialVersionUID = -6052424284110960213L;

  /**
   * Regular expression for parsing URIs.
   *
   * Taken from RFC 2396, Appendix B.
   * This expression doesn't parse IPv6 addresses.
   */
  private static final String URI_REGEXP =
    "^(([^:/?#]+):)?((//([^/?#]*))?([^?#]*)(\\?([^#]*))?)?(#(.*))?";

  /**
   * Regular expression for parsing the authority segment.
   */
  private static final String AUTHORITY_REGEXP =
    "(([^?#]*)@)?([^?#:]*)(:([0-9]*))?";

  /**
   * Valid characters (taken from rfc2396/3986)
   */
  private static final String RFC2396_DIGIT = "0123456789";
  private static final String RFC2396_LOWALPHA = "abcdefghijklmnopqrstuvwxyz";
  private static final String RFC2396_UPALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  private static final String RFC2396_ALPHA =
    RFC2396_LOWALPHA + RFC2396_UPALPHA;
  private static final String RFC2396_ALPHANUM = RFC2396_DIGIT + RFC2396_ALPHA;
  private static final String RFC3986_UNRESERVED = RFC2396_ALPHANUM + "-._~";
  private static final String RFC3986_SUBDELIMS = "!$&'()*+,;=";
  private static final String RFC3986_REG_NAME =
    RFC3986_UNRESERVED + RFC3986_SUBDELIMS + "%";
  private static final String RFC3986_PCHAR = RFC3986_UNRESERVED + 
    RFC3986_SUBDELIMS + ":@%";
  private static final String RFC3986_SEGMENT = RFC3986_PCHAR;
  private static final String RFC3986_PATH_SEGMENTS = RFC3986_SEGMENT + "/";
  private static final String RFC3986_SSP = RFC3986_PCHAR + "?/";
  private static final String RFC3986_HOST = RFC3986_REG_NAME + "[]";
  private static final String RFC3986_USERINFO = RFC3986_REG_NAME + ":";

  /**
   * Index of scheme component in parsed URI.
   */
  private static final int SCHEME_GROUP = 2;

  /**
   * Index of scheme-specific-part in parsed URI.
   */
  private static final int SCHEME_SPEC_PART_GROUP = 3;

  /**
   * Index of authority component in parsed URI.
   */
  private static final int AUTHORITY_GROUP = 5;

  /**
   * Index of path component in parsed URI.
   */
  private static final int PATH_GROUP = 6;

  /**
   * Index of query component in parsed URI.
   */
  private static final int QUERY_GROUP = 8;

  /**
   * Index of fragment component in parsed URI.
   */
  private static final int FRAGMENT_GROUP = 10;
  
  /**
   * Index of userinfo component in parsed authority section.
   */
  private static final int AUTHORITY_USERINFO_GROUP = 2;

  /**
   * Index of host component in parsed authority section.
   */
  private static final int AUTHORITY_HOST_GROUP = 3;

  /**
   * Index of port component in parsed authority section.
   */
  private static final int AUTHORITY_PORT_GROUP = 5;

  /**
   * The compiled version of the URI regular expression.
   */
  private static final Pattern URI_PATTERN;

  /**
   * The compiled version of the authority regular expression.
   */
  private static final Pattern AUTHORITY_PATTERN;

  /**
   * The set of valid hexadecimal characters.
   */
  private static final String HEX = "0123456789ABCDEF";

  private transient String scheme;
  private transient String rawSchemeSpecificPart;
  private transient String schemeSpecificPart;
  private transient String rawAuthority;
  private transient String authority;
  private transient String rawUserInfo;
  private transient String userInfo;
  private transient String rawHost;
  private transient String host;
  private transient int port = -1;
  private transient String rawPath;
  private transient String path;
  private transient String rawQuery;
  private transient String query;
  private transient String rawFragment;
  private transient String fragment;
  private String string;

  /**
   * Static initializer to pre-compile the regular expressions.
   */
  static
  {
    URI_PATTERN = Pattern.compile(URI_REGEXP);
    AUTHORITY_PATTERN = Pattern.compile(AUTHORITY_REGEXP);
  }

  private void readObject(ObjectInputStream is)
    throws ClassNotFoundException, IOException
  {
    this.string = (String) is.readObject();
    try
      {
	parseURI(this.string);
      }
    catch (URISyntaxException x)
      {
	// Should not happen.
	throw new RuntimeException(x);
      }
  }

  private void writeObject(ObjectOutputStream os) throws IOException
  {
    if (string == null)
      string = toString(); 
    os.writeObject(string);
  }

  /**
   * <p>
   * Returns the string content of the specified group of the supplied
   * matcher.  The returned value is modified according to the following:
   * </p>
   * <ul>
   * <li>If the resulting string has a length greater than 0, then
   * that string is returned.</li>
   * <li>If a string of zero length, is matched, then the content
   * of the preceding group is considered.  If this is also an empty
   * string, then <code>null</code> is returned to indicate an undefined
   * value.  Otherwise, the value is truly the empty string and this is
   * the returned value.</li>
   * </ul>
   * <p>
   * This method is used for matching against all parts of the URI
   * that may be either undefined or empty (i.e. all those but the
   * scheme-specific part and the path).  In each case, the preceding
   * group is the content of the original group, along with some
   * additional distinguishing feature.  For example, the preceding
   * group for the query includes the preceding question mark,
   * while that of the fragment includes the hash symbol.  The presence
   * of these features enables disambiguation between the two cases
   * of a completely unspecified value and a simple non-existant value.
   * The scheme differs in that it will never return an empty string;
   * the delimiter follows the scheme rather than preceding it, so
   * it becomes part of the following section.  The same is true
   * of the user information.
   * </p>
   *
   * @param match the matcher, which contains the results of the URI
   *              matched against the URI regular expression.
   * @return either the matched content, <code>null</code> for undefined
   *         values, or an empty string for a URI part with empty content.
   */
  private static String getURIGroup(Matcher match, int group)
  {
    String matched = match.group(group);
    if (matched == null || matched.length() == 0)
      {
	String prevMatched = match.group(group -1);
	if (prevMatched == null || prevMatched.length() == 0)
	  return null;
	else
	  return "";
      }
    return matched;
  }

  /**
   * Sets fields of this URI by parsing the given string.
   *
   * @param str The string to parse
   *
   * @exception URISyntaxException If the given string violates RFC 2396
   */
  private void parseURI(String str) throws URISyntaxException
  {
    Matcher matcher = URI_PATTERN.matcher(str);
    
    if (matcher.matches())
      {
	scheme = getURIGroup(matcher, SCHEME_GROUP);
	rawSchemeSpecificPart = matcher.group(SCHEME_SPEC_PART_GROUP);
	schemeSpecificPart = unquote(rawSchemeSpecificPart);
	if (!isOpaque())
	  {
	    rawAuthority = getURIGroup(matcher, AUTHORITY_GROUP);
	    rawPath = matcher.group(PATH_GROUP);
	    rawQuery = getURIGroup(matcher, QUERY_GROUP);
	  }
	rawFragment = getURIGroup(matcher, FRAGMENT_GROUP);
      }
    else
      throw new URISyntaxException(str,
				   "doesn't match URI regular expression");
    parseServerAuthority();

    // We must eagerly unquote the parts, because this is the only time
    // we may throw an exception.
    authority = unquote(rawAuthority);
    userInfo = unquote(rawUserInfo);
    host = unquote(rawHost);
    path = unquote(rawPath);
    query = unquote(rawQuery);
    fragment = unquote(rawFragment);
  }

  /**
   * Unquote "%" + hex quotes characters
   *
   * @param str The string to unquote or null.
   *
   * @return The unquoted string or null if str was null.
   *
   * @exception URISyntaxException If the given string contains invalid
   * escape sequences.
   */
  private static String unquote(String str) throws URISyntaxException
  {
    if (str == null)
      return null;
    byte[] buf = new byte[str.length()];
    int pos = 0;
    for (int i = 0; i < str.length(); i++)
      {
	char c = str.charAt(i);
	if (c == '%')
	  {
	    if (i + 2 >= str.length())
	      throw new URISyntaxException(str, "Invalid quoted character");
	    int hi = Character.digit(str.charAt(++i), 16);
	    int lo = Character.digit(str.charAt(++i), 16);
	    if (lo < 0 || hi < 0)
	      throw new URISyntaxException(str, "Invalid quoted character");
	    buf[pos++] = (byte) (hi * 16 + lo);
	  }
	else
	  buf[pos++] = (byte) c;
      }
    try
      {
	return new String(buf, 0, pos, "utf-8");
      }
    catch (java.io.UnsupportedEncodingException x2)
      {
	throw (Error) new InternalError().initCause(x2);
      }
  }

  /**
   * Quote characters illegal in URIs in given string.
   *
   * Replace illegal characters by encoding their UTF-8
   * representation as "%" + hex code for each resulting
   * UTF-8 character.
   *
   * @param str The string to quote
   *
   * @return The quoted string.
   */
  private static String quote(String str)
  {
    return quote(str, RFC3986_SSP);
  }

  /**
   * Quote characters illegal in URI authorities in given string.
   *
   * Replace illegal characters by encoding their UTF-8
   * representation as "%" + hex code for each resulting
   * UTF-8 character.
   *
   * @param str The string to quote
   *
   * @return The quoted string.
   */
  private static String quoteAuthority(String str)
  {
    // Technically, we should be using RFC2396_AUTHORITY, but
    // it contains no additional characters.
    return quote(str, RFC3986_REG_NAME);
  }

  /**
   * Quotes the characters in the supplied string that are not part of
   * the specified set of legal characters.
   *
   * @param str the string to quote
   * @param legalCharacters the set of legal characters
   *
   * @return the quoted string.
   */
  private static String quote(String str, String legalCharacters)
  {
    StringBuffer sb = new StringBuffer(str.length());
    for (int i = 0; i < str.length(); i++)
      {
	char c = str.charAt(i);
	if ((legalCharacters.indexOf(c) == -1)
	    && (c <= 127))
	  {
	    sb.append('%');
	    sb.append(HEX.charAt(c / 16));
	    sb.append(HEX.charAt(c % 16));
	  }
      	else
	  sb.append(c);
      }
    return sb.toString();
  }

  /**
   * Quote characters illegal in URI hosts in given string.
   *
   * Replace illegal characters by encoding their UTF-8
   * representation as "%" + hex code for each resulting
   * UTF-8 character.
   *
   * @param str The string to quote
   *
   * @return The quoted string.
   */
  private static String quoteHost(String str)
  {
    return quote(str, RFC3986_HOST);
  }

  /**
   * Quote characters illegal in URI paths in given string.
   *
   * Replace illegal characters by encoding their UTF-8
   * representation as "%" + hex code for each resulting
   * UTF-8 character.
   *
   * @param str The string to quote
   *
   * @return The quoted string.
   */
  private static String quotePath(String str)
  {
    // Technically, we should be using RFC2396_PATH, but
    // it contains no additional characters.
    return quote(str, RFC3986_PATH_SEGMENTS);
  }

  /**
   * Quote characters illegal in URI user infos in given string.
   *
   * Replace illegal characters by encoding their UTF-8
   * representation as "%" + hex code for each resulting
   * UTF-8 character.
   *
   * @param str The string to quote
   *
   * @return The quoted string.
   */
  private static String quoteUserInfo(String str)
  {
    return quote(str, RFC3986_USERINFO);
  }

  /**
   * Creates an URI from the given string
   *
   * @param str The string to create the URI from
   *
   * @exception URISyntaxException If the given string violates RFC 2396
   * @exception NullPointerException If str is null
   */
  public URI(String str) throws URISyntaxException
  {
    this.string = str;
    parseURI(str);
  }

  /**
   * Create an URI from the given components
   *
   * @param scheme The scheme name
   * @param userInfo The username and authorization info
   * @param host The hostname
   * @param port The port number
   * @param path The path
   * @param query The query
   * @param fragment The fragment
   *
   * @exception URISyntaxException If the given string violates RFC 2396
   */
  public URI(String scheme, String userInfo, String host, int port,
             String path, String query, String fragment)
    throws URISyntaxException
  {
    this((scheme == null ? "" : scheme + ":")
         + (userInfo == null && host == null && port == -1 ? "" : "//")
         + (userInfo == null ? "" : quoteUserInfo(userInfo) + "@")
         + (host == null ? "" : quoteHost(host))
         + (port == -1 ? "" : ":" + String.valueOf(port))
         + (path == null ? "" : quotePath(path))
         + (query == null ? "" : "?" + quote(query))
         + (fragment == null ? "" : "#" + quote(fragment)));
  }

  /**
   * Create an URI from the given components
   *
   * @param scheme The scheme name
   * @param authority The authority
   * @param path The apth
   * @param query The query
   * @param fragment The fragment
   *
   * @exception URISyntaxException If the given string violates RFC 2396
   */
  public URI(String scheme, String authority, String path, String query,
             String fragment) throws URISyntaxException
  {
    this((scheme == null ? "" : scheme + ":")
         + (authority == null ? "" : "//" + quoteAuthority(authority))
         + (path == null ? "" : quotePath(path))
         + (query == null ? "" : "?" + quote(query))
         + (fragment == null ? "" : "#" + quote(fragment)));
  }

  /**
   * Create an URI from the given components
   *
   * @param scheme The scheme name
   * @param host The hostname
   * @param path The path
   * @param fragment The fragment
   *
   * @exception URISyntaxException If the given string violates RFC 2396
   */
  public URI(String scheme, String host, String path, String fragment)
    throws URISyntaxException
  {
    this(scheme, null, host, -1, path, null, fragment);
  }

  /**
   * Create an URI from the given components
   *
   * @param scheme The scheme name
   * @param ssp The scheme specific part
   * @param fragment The fragment
   *
   * @exception URISyntaxException If the given string violates RFC 2396
   */
  public URI(String scheme, String ssp, String fragment)
    throws URISyntaxException
  {
    this((scheme == null ? "" : scheme + ":")
         + (ssp == null ? "" : quote(ssp))
         + (fragment == null ? "" : "#" + quote(fragment)));
  }

  /**
   * Create an URI from the given string
   *
   * @param str The string to create the URI from
   *
   * @exception IllegalArgumentException If the given string violates RFC 2396
   * @exception NullPointerException If str is null
   */
  public static URI create(String str)
  {
    try
      {
	return new URI(str);
      }
    catch (URISyntaxException e)
      {
	throw (IllegalArgumentException) new IllegalArgumentException()
	      .initCause(e);
      }
  }

  /**
   * Attempts to parse this URI's authority component, if defined,
   * into user-information, host, and port components.  The purpose
   * of this method was to disambiguate between some authority sections,
   * which form invalid server-based authories, but valid registry
   * based authorities.  In the updated RFC 3986, the authority section
   * is defined differently, with registry-based authorities part of
   * the host section.  Thus, this method is now simply an explicit
   * way of parsing any authority section.
   *
   * @return the URI, with the authority section parsed into user
   *         information, host and port components.
   * @throws URISyntaxException if the given string violates RFC 2396
   */
  public URI parseServerAuthority() throws URISyntaxException
  {
    if (rawAuthority != null)
      {
	Matcher matcher = AUTHORITY_PATTERN.matcher(rawAuthority);

	if (matcher.matches())
	  {
	    rawUserInfo = getURIGroup(matcher, AUTHORITY_USERINFO_GROUP);
	    rawHost = getURIGroup(matcher, AUTHORITY_HOST_GROUP);
	    
	    String portStr = getURIGroup(matcher, AUTHORITY_PORT_GROUP);
	    
	    if (portStr != null)
	      try
		{
		  port = Integer.parseInt(portStr);
		}
	      catch (NumberFormatException e)
		{
		  URISyntaxException use =
		    new URISyntaxException
		      (string, "doesn't match URI regular expression");
		  use.initCause(e);
		  throw use;
		}
	  }
	else
	  throw new URISyntaxException(string,
				       "doesn't match URI regular expression");
      }
    return this;
  }

  /**
   * <p>
   * Returns a normalized version of the URI.  If the URI is opaque,
   * or its path is already in normal form, then this URI is simply
   * returned.  Otherwise, the following transformation of the path
   * element takes place:
   * </p>
   * <ol>
   * <li>All `.' segments are removed.</li>
   * <li>Each `..' segment which can be paired with a prior non-`..' segment
   * is removed along with the preceding segment.</li>
   * <li>A `.' segment is added to the front if the first segment contains
   * a colon (`:').  This is a deviation from the RFC, which prevents
   * confusion between the path and the scheme.</li>
   * </ol>
   * <p>
   * The resulting URI will be free of `.' and `..' segments, barring those
   * that were prepended or which couldn't be paired, respectively.
   * </p>
   *
   * @return the normalized URI.
   */
  public URI normalize()
  {
    if (isOpaque() || path.indexOf("/./") == -1 && path.indexOf("/../") == -1)
      return this;
    try
      {
	return new URI(scheme, authority, normalizePath(path), query,
		       fragment);
      }
    catch (URISyntaxException e)
      {
	throw (Error) new InternalError("Normalized URI variant could not "+
					"be constructed").initCause(e);
      }
  }

  /**
   * <p>
   * Normalize the given path.  The following transformation takes place:
   * </p>
   * <ol>
   * <li>All `.' segments are removed.</li>
   * <li>Each `..' segment which can be paired with a prior non-`..' segment
   * is removed along with the preceding segment.</li>
   * <li>A `.' segment is added to the front if the first segment contains
   * a colon (`:').  This is a deviation from the RFC, which prevents
   * confusion between the path and the scheme.</li>
   * </ol>
   * <p>
   * The resulting URI will be free of `.' and `..' segments, barring those
   * that were prepended or which couldn't be paired, respectively.
   * </p>
   * 
   * @param relativePath the relative path to be normalized.
   * @return the normalized path.
   */
  private String normalizePath(String relativePath)
  {
    /* 
       This follows the algorithm in section 5.2.4. of RFC3986,
       but doesn't modify the input buffer.
    */
    StringBuffer input = new StringBuffer(relativePath);
    StringBuffer output = new StringBuffer();
    int start = 0;
    while (start < input.length())
      {
	/* A */
	if (input.indexOf("../",start) == start)
	  {
	    start += 3;
	    continue;
	  }
	if (input.indexOf("./",start) == start)
	  {
	    start += 2;
	    continue;
	  }
	/* B */
	if (input.indexOf("/./",start) == start)
	  {
	    start += 2;
	    continue;
	  }
	if (input.indexOf("/.",start) == start
	    && input.charAt(start + 2) != '.')
	  {
	    start += 1;
	    input.setCharAt(start,'/');
	    continue;
	  }
	/* C */
	if (input.indexOf("/../",start) == start)
	  {
	    start += 3;
	    removeLastSegment(output);
	    continue;
	  }
	if (input.indexOf("/..",start) == start)
	  {
	    start += 2;
	    input.setCharAt(start,'/');
	    removeLastSegment(output);
	    continue;
	  }
	/* D */
	if (start == input.length() - 1 && input.indexOf(".",start) == start)
	  {
	    input.delete(0,1);
	    continue;
	  }
	if (start == input.length() - 2 && input.indexOf("..",start) == start)
	  {
	    input.delete(0,2);
	    continue;
	  }
	/* E */
	int indexOfSlash = input.indexOf("/",start);
	while (indexOfSlash == start)
	  {
	    output.append("/");
	    ++start;
	    indexOfSlash = input.indexOf("/",start);
	  }
	if (indexOfSlash == -1)
	  indexOfSlash = input.length();
	output.append(input.substring(start, indexOfSlash));
        start = indexOfSlash;
      }
    return output.toString();
  }

  /**
   * Removes the last segment of the path from the specified buffer.
   *
   * @param buffer the buffer containing the path.
   */
  private void removeLastSegment(StringBuffer buffer)
  {
    int lastSlash = buffer.lastIndexOf("/");
    if (lastSlash == -1)
      buffer.setLength(0);
    else
      buffer.setLength(lastSlash);
  }

  /**
   * Resolves the given URI against this URI
   *
   * @param uri The URI to resolve against this URI
   *
   * @return The resulting URI, or null when it couldn't be resolved
   * for some reason.
   *
   * @throws NullPointerException if uri is null
   */
  public URI resolve(URI uri)
  {
    if (uri.isAbsolute())
      return uri;
    if (uri.isOpaque())
      return uri;

    String scheme = uri.getScheme();
    String schemeSpecificPart = uri.getSchemeSpecificPart();
    String authority = uri.getAuthority();
    String path = uri.getPath();
    String query = uri.getQuery();
    String fragment = uri.getFragment();

    try
      {
	if (fragment != null && path != null && path.equals("")
	    && scheme == null && authority == null && query == null)
	  return new URI(this.scheme, this.schemeSpecificPart, fragment);

	if (authority == null)
	  {
	    authority = this.authority;
	    if (path == null)
	      path = "";
	    if (! (path.startsWith("/")))
	      {
		StringBuffer basepath = new StringBuffer(this.path);
		int i = this.path.lastIndexOf('/');

		if (i >= 0)
		  basepath.delete(i + 1, basepath.length());

		basepath.append(path);
		path = normalizePath(basepath.toString());
	      }
	  }
	return new URI(this.scheme, authority, path, query, fragment);
      }
    catch (URISyntaxException e)
      {
	throw (Error) new InternalError("Resolved URI variant could not "+
					"be constructed").initCause(e);
      }
  }

  /**
   * Resolves the given URI string against this URI
   *
   * @param str The URI as string to resolve against this URI
   *
   * @return The resulting URI
   *
   * @throws IllegalArgumentException If the given URI string
   * violates RFC 2396
   * @throws NullPointerException If uri is null
   */
  public URI resolve(String str) throws IllegalArgumentException
  {
    return resolve(create(str));
  }

  /**
   * <p>
   * Relativizes the given URI against this URI.  The following
   * algorithm is used:
   * </p>
   * <ul>
   * <li>If either URI is opaque, the given URI is returned.</li>
   * <li>If the schemes of the URIs differ, the given URI is returned.</li>
   * <li>If the authority components of the URIs differ, then the given
   * URI is returned.</li>
   * <li>If the path of this URI is not a prefix of the supplied URI,
   * then the given URI is returned.</li>
   * <li>If all the above conditions hold, a new URI is created using the
   * query and fragment components of the given URI, along with a path
   * computed by removing the path of this URI from the start of the path
   * of the supplied URI.</li>
   * </ul>
   *
   * @param uri the URI to relativize agsint this URI
   * @return the resulting URI
   * @throws NullPointerException if the uri is null
   */
  public URI relativize(URI uri)
  {
    if (isOpaque() || uri.isOpaque())
      return uri;
    if (scheme == null && uri.getScheme() != null)
      return uri;
    if (scheme != null && !(scheme.equals(uri.getScheme())))
      return uri;
    if (rawAuthority == null && uri.getRawAuthority() != null)
      return uri;
    if (rawAuthority != null && !(rawAuthority.equals(uri.getRawAuthority())))
      return uri;
    if (!(uri.getRawPath().startsWith(rawPath)))
      return uri;
    try
      {
	return new URI(null, null, 
		       uri.getRawPath().substring(rawPath.length()),
		       uri.getRawQuery(), uri.getRawFragment());
      }
    catch (URISyntaxException e)
      {
	throw (Error) new InternalError("Relativized URI variant could not "+
					"be constructed").initCause(e);       
      }
  }

  /**
   * Creates an URL from an URI
   *
   * @throws MalformedURLException If a protocol handler for the URL could
   * not be found, or if some other error occurred while constructing the URL
   * @throws IllegalArgumentException If the URI is not absolute
   */
  public URL toURL() throws IllegalArgumentException, MalformedURLException
  {
    if (isAbsolute())
      return new URL(this.toString());

    throw new IllegalArgumentException("not absolute");
  }

  /**
   * Returns the scheme of the URI
   */
  public String getScheme()
  {
    return scheme;
  }

  /**
   * Tells whether this URI is absolute or not
   */
  public boolean isAbsolute()
  {
    return scheme != null;
  }

  /**
   * Tell whether this URI is opaque or not
   */
  public boolean isOpaque()
  {
    return ((scheme != null) && ! (schemeSpecificPart.startsWith("/")));
  }

  /**
   * Returns the raw scheme specific part of this URI.
   * The scheme-specific part is never undefined, though it may be empty
   */
  public String getRawSchemeSpecificPart()
  {
    return rawSchemeSpecificPart;
  }

  /**
   * Returns the decoded scheme specific part of this URI.
   */
  public String getSchemeSpecificPart()
  {
    return schemeSpecificPart;
  }

  /**
   * Returns the raw authority part of this URI
   */
  public String getRawAuthority()
  {
    return rawAuthority;
  }

  /**
   * Returns the decoded authority part of this URI
   */
  public String getAuthority()
  {
    return authority;
  }

  /**
   * Returns the raw user info part of this URI
   */
  public String getRawUserInfo()
  {
    return rawUserInfo;
  }

  /**
   * Returns the decoded user info part of this URI
   */
  public String getUserInfo()
  {
    return userInfo;
  }

  /**
   * Returns the hostname of the URI
   */
  public String getHost()
  {
    return host;
  }

  /**
   * Returns the port number of the URI
   */
  public int getPort()
  {
    return port;
  }

  /**
   * Returns the raw path part of this URI
   */
  public String getRawPath()
  {
    return rawPath;
  }

  /**
   * Returns the path of the URI
   */
  public String getPath()
  {
    return path;
  }

  /**
   * Returns the raw query part of this URI
   */
  public String getRawQuery()
  {
    return rawQuery;
  }

  /**
   * Returns the query of the URI
   */
  public String getQuery()
  {
    return query;
  }

  /**
   * Return the raw fragment part of this URI
   */
  public String getRawFragment()
  {
    return rawFragment;
  }

  /**
   * Returns the fragment of the URI
   */
  public String getFragment()
  {
    return fragment;
  }

  /**
   * <p> 
   * Compares the URI with the given object for equality.  If the
   * object is not a <code>URI</code>, then the method returns false.
   * Otherwise, the following criteria are observed:
   * </p>
   * <ul>
   * <li>The scheme of the URIs must either be null (undefined) in both cases,
   * or equal, ignorant of case.</li>
   * <li>The raw fragment of the URIs must either be null (undefined) in both
   * cases, or equal, ignorant of case.</li>
   * <li>Both URIs must be of the same type (opaque or hierarchial)</li>
   * <li><strong>For opaque URIs:</strong></li>
   * <ul>
   * <li>The raw scheme-specific parts must be equal.</li>
   * </ul>
   * <li>For hierarchical URIs:</li>
   * <ul>
   * <li>The raw paths must be equal, ignorant of case.</li>
   * <li>The raw queries are either both undefined or both equal, ignorant
   * of case.</li>
   * <li>The raw authority sections are either both undefined or:</li>
   * <li><strong>For registry-based authorities:</strong></li>
   * <ul><li>they are equal.</li></ul>
   * <li><strong>For server-based authorities:</strong></li>
   * <ul>
   * <li>the hosts are equal, ignoring case</li>
   * <li>the ports are equal</li>
   * <li>the user information components are equal</li>
   * </ul>
   * </ul>
   * </ul>
   *
   * @param obj the obj to compare the URI with.
   * @return <code>true</code> if the objects are equal, according to
   *         the specification above.
   */
  public boolean equals(Object obj)
  {
    if (!(obj instanceof URI))
      return false;
    URI uriObj = (URI) obj;
    if (scheme == null)
      {
	if (uriObj.getScheme() != null)
	  return false;
      }
    else
      if (!(scheme.equalsIgnoreCase(uriObj.getScheme())))
	return false;
    if (rawFragment == null)
      {
	if (uriObj.getRawFragment() != null)
	  return false;
      }
    else
      if (!(rawFragment.equalsIgnoreCase(uriObj.getRawFragment())))
	return false;
    boolean opaqueThis = isOpaque();
    boolean opaqueObj = uriObj.isOpaque();
    if (opaqueThis && opaqueObj)
      return rawSchemeSpecificPart.equals(uriObj.getRawSchemeSpecificPart());
    else if (!opaqueThis && !opaqueObj)
      {
	boolean common = rawPath.equalsIgnoreCase(uriObj.getRawPath())
	  && ((rawQuery == null && uriObj.getRawQuery() == null)
	      || rawQuery.equalsIgnoreCase(uriObj.getRawQuery()));
	if (rawAuthority == null && uriObj.getRawAuthority() == null)
	  return common;
	if (host == null)
	  return common 
	    && rawAuthority.equalsIgnoreCase(uriObj.getRawAuthority());
	return common 
	  && host.equalsIgnoreCase(uriObj.getHost())
	  && port == uriObj.getPort()
	  && (rawUserInfo == null ?
	      uriObj.getRawUserInfo() == null :
	      rawUserInfo.equalsIgnoreCase(uriObj.getRawUserInfo()));
      }
    else
      return false;
  }

  /**
   * Computes the hashcode of the URI
   */
  public int hashCode()
  {
    return (getScheme() == null ? 0 : 13 * getScheme().hashCode())
      + 17 * getRawSchemeSpecificPart().hashCode()
      + (getRawFragment() == null ? 0 : 21 + getRawFragment().hashCode());
  }

  /**
   * Compare the URI with another object that must also be a URI.
   * Undefined components are taken to be less than any other component.
   * The following criteria are observed:
   * </p>
   * <ul>
   * <li>Two URIs with different schemes are compared according to their
   * scheme, regardless of case.</li>
   * <li>A hierarchical URI is less than an opaque URI with the same
   * scheme.</li>
   * <li><strong>For opaque URIs:</strong></li>
   * <ul>
   * <li>URIs with differing scheme-specific parts are ordered according
   * to the ordering of the scheme-specific part.</li>
   * <li>URIs with the same scheme-specific part are ordered by the
   * raw fragment.</li>
   * </ul>
   * <li>For hierarchical URIs:</li>
   * <ul>
   * <li>URIs are ordered according to their raw authority sections,
   * if they are unequal.</li>
   * <li><strong>For registry-based authorities:</strong></li>
   * <ul><li>they are ordered according to the ordering of the authority
   * component.</li></ul>
   * <li><strong>For server-based authorities:</strong></li>
   * <ul>
   * <li>URIs are ordered according to the raw user information.</li>
   * <li>URIs with the same user information are ordered by the host,
   * ignoring case.</li>
   * <lI>URIs with the same host are ordered by the port.</li>
   * </ul>
   * <li>URIs with the same authority section are ordered by the raw path.</li>
   * <li>URIs with the same path are ordered by their raw query.</li>
   * <li>URIs with the same query are ordered by their raw fragments.</li>
   * </ul>
   * </ul>
   *
   * @param obj This object to compare this URI with
   * @return a negative integer, zero or a positive integer depending
   *         on whether this URI is less than, equal to or greater
   *         than that supplied, respectively.
   * @throws ClassCastException if the given object is not a URI
   */
  public int compareTo(Object obj) 
    throws ClassCastException
  {
    URI uri = (URI) obj;
    if (scheme == null && uri.getScheme() != null)
      return -1;
    if (scheme != null)
      {
	int sCompare = scheme.compareToIgnoreCase(uri.getScheme()); 
	if (sCompare != 0)
	  return sCompare;
      }
    boolean opaqueThis = isOpaque();
    boolean opaqueObj = uri.isOpaque();
    if (opaqueThis && !opaqueObj)
      return 1;
    if (!opaqueThis && opaqueObj)
      return -1;
    if (opaqueThis)
      {
	int ssCompare = 
	  rawSchemeSpecificPart.compareTo(uri.getRawSchemeSpecificPart());
	if (ssCompare == 0)
	  return compareFragments(uri);
	else
	  return ssCompare;
      }
    if (rawAuthority == null && uri.getRawAuthority() != null)
      return -1;
    if (rawAuthority != null)
      {
	int aCompare = rawAuthority.compareTo(uri.getRawAuthority());
	if (aCompare != 0)
	  {
	    if (host == null)
	      return aCompare;
	    if (rawUserInfo == null && uri.getRawUserInfo() != null)
	      return -1;
	    int uCompare = rawUserInfo.compareTo(uri.getRawUserInfo());
	    if (uCompare != 0)
	      return uCompare;
	    if (host == null && uri.getHost() != null)
	      return -1;
	    int hCompare = host.compareTo(uri.getHost());
	    if (hCompare != 0)
	      return hCompare;
	    return new Integer(port).compareTo(new Integer(uri.getPort()));
	  }
      }
    if (rawPath == null && uri.getRawPath() != null)
      return -1;
    if (rawPath != null)
      {
	int pCompare = rawPath.compareTo(uri.getRawPath()); 
	if (pCompare != 0)
	  return pCompare;
      }
    if (rawQuery == null && uri.getRawQuery() != null)
      return -1;
    if (rawQuery != null)
      {
	int qCompare = rawQuery.compareTo(uri.getRawQuery());
	if (qCompare != 0)
	  return qCompare;
      }
    return compareFragments(uri);
  }

  /**
   * Compares the fragment of this URI with that of the supplied URI.
   *
   * @param uri the URI to compare with this one.
   * @return a negative integer, zero or a positive integer depending
   *         on whether this uri's fragment is less than, equal to
   *         or greater than the fragment of the uri supplied, respectively.
   */
  private int compareFragments(URI uri)
  {
    if (rawFragment == null && uri.getRawFragment() != null)
      return -1;
    else if (rawFragment == null)
      return 0;
    else
      return rawFragment.compareTo(uri.getRawFragment());
  }

  /**
   * Returns the URI as a String.  If the URI was created using a constructor,
   * then this will be the same as the original input string.
   *
   * @return a string representation of the URI.
   */
  public String toString()
  {
    return (scheme == null ? "" : scheme + ":")
      + rawSchemeSpecificPart
      + (rawFragment == null ? "" : "#" + rawFragment);
  }

  /**
   * Returns the URI as US-ASCII string.  This is the same as the result
   * from <code>toString()</code> for URIs that don't contain any non-US-ASCII
   * characters.  Otherwise, the non-US-ASCII characters are replaced
   * by their percent-encoded representations.
   *
   * @return a string representation of the URI, containing only US-ASCII
   *         characters.
   */
  public String toASCIIString()
  {
    String strRep = toString();
    boolean inNonAsciiBlock = false;
    StringBuffer buffer = new StringBuffer();
    StringBuffer encBuffer = null;
    for (int i = 0; i < strRep.length(); i++)
      {
	char c = strRep.charAt(i);
	if (c <= 127)
	  {
	    if (inNonAsciiBlock)
	      {
		buffer.append(escapeCharacters(encBuffer.toString()));
		inNonAsciiBlock = false;
	      }
	    buffer.append(c);
	  }
	else
	  {
	    if (!inNonAsciiBlock)
	      {
		encBuffer = new StringBuffer();
		inNonAsciiBlock = true;
	      }
	    encBuffer.append(c);
	  }
      }
    return buffer.toString();
  }

  /**
   * Converts the non-ASCII characters in the supplied string
   * to their equivalent percent-encoded representations.
   * That is, they are replaced by "%" followed by their hexadecimal value.
   *
   * @param str a string including non-ASCII characters.
   * @return the string with the non-ASCII characters converted to their
   *         percent-encoded representations.
   */
  private static String escapeCharacters(String str)
  {
    try
      {
	StringBuffer sb = new StringBuffer(); 
	// this is far from optimal, but it works
	byte[] utf8 = str.getBytes("utf-8");
	for (int j = 0; j < utf8.length; j++)
	  {
	    sb.append('%');
	    sb.append(HEX.charAt((utf8[j] & 0xff) / 16));
	    sb.append(HEX.charAt((utf8[j] & 0xff) % 16));
	  }
	return sb.toString();
      }
    catch (java.io.UnsupportedEncodingException x)
      {
	throw (Error) new InternalError("Escaping error").initCause(x);
      }
  }

}
