Index: branches/version-2_13-dev/data/module/Net/Socket.php
===================================================================
--- branches/version-2_13-dev/data/module/Net/Socket.php	(revision 23125)
+++ branches/version-2_13-dev/data/module/Net/Socket.php	(revision 23141)
@@ -5,5 +5,5 @@
  * PHP Version 4
  *
- * Copyright (c) 1997-2013 The PHP Group
+ * Copyright (c) 1997-2003 The PHP Group
  *
  * This source file is subject to version 2.0 of the PHP license,
@@ -24,4 +24,5 @@
  * @copyright 1997-2003 The PHP Group
  * @license   http://www.php.net/license/2_02.txt PHP 2.02
+ * @version   CVS: $Id$
  * @link      http://pear.php.net/packages/Net_Socket
  */
@@ -77,9 +78,9 @@
 
     /**
-     * Number of seconds to wait on socket operations before assuming
+     * Number of seconds to wait on socket connections before assuming
      * there's no more data. Defaults to no timeout.
-     * @var integer|float $timeout
-     */
-    var $timeout = null;
+     * @var integer $timeout
+     */
+    var $timeout = false;
 
     /**
@@ -100,15 +101,15 @@
      * already connected, it disconnects and connects again.
      *
-     * @param string  $addr       IP address or host name (may be with protocol prefix).
+     * @param string  $addr       IP address or host name.
      * @param integer $port       TCP port number.
      * @param boolean $persistent (optional) Whether the connection is
      *                            persistent (kept open between requests
      *                            by the web server).
-     * @param integer $timeout    (optional) Connection socket timeout.
+     * @param integer $timeout    (optional) How long to wait for data.
      * @param array   $options    See options for stream_context_create.
      *
      * @access public
      *
-     * @return boolean|PEAR_Error  True on success or a PEAR_Error on failure.
+     * @return boolean | PEAR_Error  True on success or a PEAR_Error on failure.
      */
     function connect($addr, $port = 0, $persistent = null,
@@ -122,8 +123,9 @@
         if (!$addr) {
             return $this->raiseError('$addr cannot be empty');
-        } else if (strspn($addr, ':.0123456789') == strlen($addr)) {
-            $this->addr = strpos($addr, ':') !== false ? '['.$addr.']' : $addr;
+        } elseif (strspn($addr, '.0123456789') == strlen($addr) ||
+                  strstr($addr, '/') !== false) {
+            $this->addr = $addr;
         } else {
-            $this->addr = $addr;
+            $this->addr = @gethostbyname($addr);
         }
 
@@ -132,4 +134,8 @@
         if ($persistent !== null) {
             $this->persistent = $persistent;
+        }
+
+        if ($timeout !== null) {
+            $this->timeout = $timeout;
         }
 
@@ -140,9 +146,10 @@
         $old_track_errors = @ini_set('track_errors', 1);
 
-        if ($timeout <= 0) {
-            $timeout = @ini_get('default_socket_timeout');
-        }
-
         if ($options && function_exists('stream_context_create')) {
+            if ($this->timeout) {
+                $timeout = $this->timeout;
+            } else {
+                $timeout = 0;
+            }
             $context = stream_context_create($options);
 
@@ -163,5 +170,10 @@
             }
         } else {
-            $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout);
+            if ($this->timeout) {
+                $fp = @$openfunc($this->addr, $this->port, $errno,
+                                 $errstr, $this->timeout);
+            } else {
+                $fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
+            }
         }
 
@@ -176,5 +188,5 @@
         @ini_set('track_errors', $old_track_errors);
         $this->fp = $fp;
-        $this->setTimeout();
+
         return $this->setBlocking($this->blocking);
     }
@@ -247,29 +259,16 @@
      *
      * @param integer $seconds      Seconds.
-     * @param integer $microseconds Microseconds, optional.
-     *
-     * @access public
-     * @return mixed True on success or false on failure or
-     *               a PEAR_Error instance when not connected
-     */
-    function setTimeout($seconds = null, $microseconds = null)
-    {
-        if (!is_resource($this->fp)) {
-            return $this->raiseError('not connected');
-        }
-
-        if ($seconds === null && $microseconds === null) {
-            $seconds      = (int) $this->timeout;
-            $microseconds = (int) (($this->timeout - $seconds) * 1000000);
-        } else {
-            $this->timeout = $seconds + $microseconds/1000000;
-        }
-
-        if ($this->timeout > 0) {
-            return stream_set_timeout($this->fp, (int) $seconds, (int) $microseconds);
-        }
-        else {
-            return false;
-        }
+     * @param integer $microseconds Microseconds.
+     *
+     * @access public
+     * @return mixed true on success or a PEAR_Error instance otherwise
+     */
+    function setTimeout($seconds, $microseconds)
+    {
+        if (!is_resource($this->fp)) {
+            return $this->raiseError('not connected');
+        }
+
+        return socket_set_timeout($this->fp, $seconds, $microseconds);
     }
 
@@ -317,5 +316,5 @@
         }
 
-        return stream_get_meta_data($this->fp);
+        return socket_get_status($this->fp);
     }
 
@@ -323,12 +322,9 @@
      * Get a specified line of data
      *
-     * @param int $size Reading ends when size - 1 bytes have been read,
-     *                  or a newline or an EOF (whichever comes first).
-     *                  If no size is specified, it will keep reading from
-     *                  the stream until it reaches the end of the line.
-     *
-     * @access public
-     * @return mixed $size bytes of data from the socket, or a PEAR_Error if
-     *         not connected. If an error occurs, FALSE is returned.
+     * @param int $size ??
+     *
+     * @access public
+     * @return $size bytes of data from the socket, or a PEAR_Error if
+     *         not connected.
      */
     function gets($size = null)
@@ -375,8 +371,7 @@
      * @access public
      * @return mixed If the socket is not connected, returns an instance of
-     *               PEAR_Error.
-     *               If the write succeeds, returns the number of bytes written.
+     *               PEAR_Error
+     *               If the write succeeds, returns the number of bytes written
      *               If the write fails, returns false.
-     *               If the socket times out, returns an instance of PEAR_Error.
      */
     function write($data, $blocksize = null)
@@ -387,20 +382,5 @@
 
         if (is_null($blocksize) && !OS_WINDOWS) {
-            $written = @fwrite($this->fp, $data);
-
-            // Check for timeout or lost connection
-            if (!$written) {
-                $meta_data = $this->getStatus();
-
-                if (!is_array($meta_data)) {
-                    return $meta_data; // PEAR_Error
-                }
-
-                if (!empty($meta_data['timed_out'])) {
-                    return $this->raiseError('timed out');
-                }
-            }
-
-            return $written;
+            return @fwrite($this->fp, $data);
         } else {
             if (is_null($blocksize)) {
@@ -412,20 +392,7 @@
             while ($pos < $size) {
                 $written = @fwrite($this->fp, substr($data, $pos, $blocksize));
-
-                // Check for timeout or lost connection
                 if (!$written) {
-                    $meta_data = $this->getStatus();
-
-                    if (!is_array($meta_data)) {
-                        return $meta_data; // PEAR_Error
-                    }
-
-                    if (!empty($meta_data['timed_out'])) {
-                        return $this->raiseError('timed out');
-                    }
-
                     return $written;
                 }
-
                 $pos += $written;
             }
@@ -441,5 +408,5 @@
      *
      * @access public
-     * @return mixed fwrite() result, or PEAR_Error when not connected
+     * @return mixed fputs result, or an error
      */
     function writeLine($data)
Index: branches/version-2_13-dev/data/module/Net/URL.php
===================================================================
--- branches/version-2_13-dev/data/module/Net/URL.php	(revision 23125)
+++ branches/version-2_13-dev/data/module/Net/URL.php	(revision 23141)
@@ -33,5 +33,5 @@
 // +-----------------------------------------------------------------------+
 //
-// $Id: URL.php,v 1.49 2007/06/28 14:43:07 davidc Exp $
+// $Id$
 //
 // Net_URL Class
Index: branches/version-2_13-dev/data/module/Net/URL2.php
===================================================================
--- branches/version-2_13-dev/data/module/Net/URL2.php	(revision 23125)
+++ 	(revision )
@@ -1,942 +1,0 @@
-<?php
-/**
- * Net_URL2, a class representing a URL as per RFC 3986.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * Copyright (c) 2007-2009, Peytz & Co. A/S
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in
- *     the documentation and/or other materials provided with the distribution.
- *   * Neither the name of the Net_URL2 nor the names of its contributors may
- *     be used to endorse or promote products derived from this software
- *     without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category  Networking
- * @package   Net_URL2
- * @author    Christian Schmidt <schmidt@php.net>
- * @copyright 2007-2009 Peytz & Co. A/S
- * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version   CVS: $Id: URL2.php 309223 2011-03-14 14:26:32Z till $
- * @link      http://www.rfc-editor.org/rfc/rfc3986.txt
- */
-
-/**
- * Represents a URL as per RFC 3986.
- *
- * @category  Networking
- * @package   Net_URL2
- * @author    Christian Schmidt <schmidt@php.net>
- * @copyright 2007-2009 Peytz & Co. A/S
- * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version   Release: @package_version@
- * @link      http://pear.php.net/package/Net_URL2
- */
-class Net_URL2
-{
-    /**
-     * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default
-     * is true.
-     */
-    const OPTION_STRICT = 'strict';
-
-    /**
-     * Represent arrays in query using PHP's [] notation. Default is true.
-     */
-    const OPTION_USE_BRACKETS = 'use_brackets';
-
-    /**
-     * URL-encode query variable keys. Default is true.
-     */
-    const OPTION_ENCODE_KEYS = 'encode_keys';
-
-    /**
-     * Query variable separators when parsing the query string. Every character
-     * is considered a separator. Default is "&".
-     */
-    const OPTION_SEPARATOR_INPUT = 'input_separator';
-
-    /**
-     * Query variable separator used when generating the query string. Default
-     * is "&".
-     */
-    const OPTION_SEPARATOR_OUTPUT = 'output_separator';
-
-    /**
-     * Default options corresponds to how PHP handles $_GET.
-     */
-    private $_options = array(
-        self::OPTION_STRICT           => true,
-        self::OPTION_USE_BRACKETS     => true,
-        self::OPTION_ENCODE_KEYS      => true,
-        self::OPTION_SEPARATOR_INPUT  => '&',
-        self::OPTION_SEPARATOR_OUTPUT => '&',
-        );
-
-    /**
-     * @var  string|bool
-     */
-    private $_scheme = false;
-
-    /**
-     * @var  string|bool
-     */
-    private $_userinfo = false;
-
-    /**
-     * @var  string|bool
-     */
-    private $_host = false;
-
-    /**
-     * @var  string|bool
-     */
-    private $_port = false;
-
-    /**
-     * @var  string
-     */
-    private $_path = '';
-
-    /**
-     * @var  string|bool
-     */
-    private $_query = false;
-
-    /**
-     * @var  string|bool
-     */
-    private $_fragment = false;
-
-    /**
-     * Constructor.
-     *
-     * @param string $url     an absolute or relative URL
-     * @param array  $options an array of OPTION_xxx constants
-     *
-     * @return $this
-     * @uses   self::parseUrl()
-     */
-    public function __construct($url, array $options = array())
-    {
-        foreach ($options as $optionName => $value) {
-            if (array_key_exists($optionName, $this->_options)) {
-                $this->_options[$optionName] = $value;
-            }
-        }
-
-        $this->parseUrl($url);
-    }
-
-    /**
-     * Magic Setter.
-     *
-     * This method will magically set the value of a private variable ($var)
-     * with the value passed as the args
-     *
-     * @param  string $var      The private variable to set.
-     * @param  mixed  $arg      An argument of any type.
-     * @return void
-     */
-    public function __set($var, $arg)
-    {
-        $method = 'set' . $var;
-        if (method_exists($this, $method)) {
-            $this->$method($arg);
-        }
-    }
-
-    /**
-     * Magic Getter.
-     *
-     * This is the magic get method to retrieve the private variable
-     * that was set by either __set() or it's setter...
-     *
-     * @param  string $var         The property name to retrieve.
-     * @return mixed  $this->$var  Either a boolean false if the
-     *                             property is not set or the value
-     *                             of the private property.
-     */
-    public function __get($var)
-    {
-        $method = 'get' . $var;
-        if (method_exists($this, $method)) {
-            return $this->$method();
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the scheme, e.g. "http" or "urn", or false if there is no
-     * scheme specified, i.e. if this is a relative URL.
-     *
-     * @return  string|bool
-     */
-    public function getScheme()
-    {
-        return $this->_scheme;
-    }
-
-    /**
-     * Sets the scheme, e.g. "http" or "urn". Specify false if there is no
-     * scheme specified, i.e. if this is a relative URL.
-     *
-     * @param string|bool $scheme e.g. "http" or "urn", or false if there is no
-     *                            scheme specified, i.e. if this is a relative
-     *                            URL
-     *
-     * @return $this
-     * @see    getScheme()
-     */
-    public function setScheme($scheme)
-    {
-        $this->_scheme = $scheme;
-        return $this;
-    }
-
-    /**
-     * Returns the user part of the userinfo part (the part preceding the first
-     *  ":"), or false if there is no userinfo part.
-     *
-     * @return  string|bool
-     */
-    public function getUser()
-    {
-        return $this->_userinfo !== false
-            ? preg_replace('@:.*$@', '', $this->_userinfo)
-            : false;
-    }
-
-    /**
-     * Returns the password part of the userinfo part (the part after the first
-     *  ":"), or false if there is no userinfo part (i.e. the URL does not
-     * contain "@" in front of the hostname) or the userinfo part does not
-     * contain ":".
-     *
-     * @return  string|bool
-     */
-    public function getPassword()
-    {
-        return $this->_userinfo !== false
-            ? substr(strstr($this->_userinfo, ':'), 1)
-            : false;
-    }
-
-    /**
-     * Returns the userinfo part, or false if there is none, i.e. if the
-     * authority part does not contain "@".
-     *
-     * @return  string|bool
-     */
-    public function getUserinfo()
-    {
-        return $this->_userinfo;
-    }
-
-    /**
-     * Sets the userinfo part. If two arguments are passed, they are combined
-     * in the userinfo part as username ":" password.
-     *
-     * @param string|bool $userinfo userinfo or username
-     * @param string|bool $password optional password, or false
-     *
-     * @return $this
-     */
-    public function setUserinfo($userinfo, $password = false)
-    {
-        $this->_userinfo = $userinfo;
-        if ($password !== false) {
-            $this->_userinfo .= ':' . $password;
-        }
-        return $this;
-    }
-
-    /**
-     * Returns the host part, or false if there is no authority part, e.g.
-     * relative URLs.
-     *
-     * @return  string|bool a hostname, an IP address, or false
-     */
-    public function getHost()
-    {
-        return $this->_host;
-    }
-
-    /**
-     * Sets the host part. Specify false if there is no authority part, e.g.
-     * relative URLs.
-     *
-     * @param string|bool $host a hostname, an IP address, or false
-     *
-     * @return $this
-     */
-    public function setHost($host)
-    {
-        $this->_host = $host;
-        return $this;
-    }
-
-    /**
-     * Returns the port number, or false if there is no port number specified,
-     * i.e. if the default port is to be used.
-     *
-     * @return  string|bool
-     */
-    public function getPort()
-    {
-        return $this->_port;
-    }
-
-    /**
-     * Sets the port number. Specify false if there is no port number specified,
-     * i.e. if the default port is to be used.
-     *
-     * @param string|bool $port a port number, or false
-     *
-     * @return $this
-     */
-    public function setPort($port)
-    {
-        $this->_port = $port;
-        return $this;
-    }
-
-    /**
-     * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or
-     * false if there is no authority.
-     *
-     * @return string|bool
-     */
-    public function getAuthority()
-    {
-        if (!$this->_host) {
-            return false;
-        }
-
-        $authority = '';
-
-        if ($this->_userinfo !== false) {
-            $authority .= $this->_userinfo . '@';
-        }
-
-        $authority .= $this->_host;
-
-        if ($this->_port !== false) {
-            $authority .= ':' . $this->_port;
-        }
-
-        return $authority;
-    }
-
-    /**
-     * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
-     * false if there is no authority.
-     *
-     * @param string|false $authority a hostname or an IP addresse, possibly
-     *                                with userinfo prefixed and port number
-     *                                appended, e.g. "foo:bar@example.org:81".
-     *
-     * @return $this
-     */
-    public function setAuthority($authority)
-    {
-        $this->_userinfo = false;
-        $this->_host     = false;
-        $this->_port     = false;
-        if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
-            if ($reg[1]) {
-                $this->_userinfo = $reg[2];
-            }
-
-            $this->_host = $reg[3];
-            if (isset($reg[5])) {
-                $this->_port = $reg[5];
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Returns the path part (possibly an empty string).
-     *
-     * @return string
-     */
-    public function getPath()
-    {
-        return $this->_path;
-    }
-
-    /**
-     * Sets the path part (possibly an empty string).
-     *
-     * @param string $path a path
-     *
-     * @return $this
-     */
-    public function setPath($path)
-    {
-        $this->_path = $path;
-        return $this;
-    }
-
-    /**
-     * Returns the query string (excluding the leading "?"), or false if "?"
-     * is not present in the URL.
-     *
-     * @return  string|bool
-     * @see     self::getQueryVariables()
-     */
-    public function getQuery()
-    {
-        return $this->_query;
-    }
-
-    /**
-     * Sets the query string (excluding the leading "?"). Specify false if "?"
-     * is not present in the URL.
-     *
-     * @param string|bool $query a query string, e.g. "foo=1&bar=2"
-     *
-     * @return $this
-     * @see    self::setQueryVariables()
-     */
-    public function setQuery($query)
-    {
-        $this->_query = $query;
-        return $this;
-    }
-
-    /**
-     * Returns the fragment name, or false if "#" is not present in the URL.
-     *
-     * @return  string|bool
-     */
-    public function getFragment()
-    {
-        return $this->_fragment;
-    }
-
-    /**
-     * Sets the fragment name. Specify false if "#" is not present in the URL.
-     *
-     * @param string|bool $fragment a fragment excluding the leading "#", or
-     *                              false
-     *
-     * @return $this
-     */
-    public function setFragment($fragment)
-    {
-        $this->_fragment = $fragment;
-        return $this;
-    }
-
-    /**
-     * Returns the query string like an array as the variables would appear in
-     * $_GET in a PHP script. If the URL does not contain a "?", an empty array
-     * is returned.
-     *
-     * @return  array
-     */
-    public function getQueryVariables()
-    {
-        $pattern = '/[' .
-                   preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
-                   ']/';
-        $parts   = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
-        $return  = array();
-
-        foreach ($parts as $part) {
-            if (strpos($part, '=') !== false) {
-                list($key, $value) = explode('=', $part, 2);
-            } else {
-                $key   = $part;
-                $value = null;
-            }
-
-            if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
-                $key = rawurldecode($key);
-            }
-            $value = rawurldecode($value);
-
-            if ($this->getOption(self::OPTION_USE_BRACKETS) &&
-                preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
-
-                $key = $matches[1];
-                $idx = $matches[2];
-
-                // Ensure is an array
-                if (empty($return[$key]) || !is_array($return[$key])) {
-                    $return[$key] = array();
-                }
-
-                // Add data
-                if ($idx === '') {
-                    $return[$key][] = $value;
-                } else {
-                    $return[$key][$idx] = $value;
-                }
-            } elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
-                      && !empty($return[$key])
-            ) {
-                $return[$key]   = (array) $return[$key];
-                $return[$key][] = $value;
-            } else {
-                $return[$key] = $value;
-            }
-        }
-
-        return $return;
-    }
-
-    /**
-     * Sets the query string to the specified variable in the query string.
-     *
-     * @param array $array (name => value) array
-     *
-     * @return $this
-     */
-    public function setQueryVariables(array $array)
-    {
-        if (!$array) {
-            $this->_query = false;
-        } else {
-            $this->_query = $this->buildQuery(
-                $array,
-                $this->getOption(self::OPTION_SEPARATOR_OUTPUT)
-            );
-        }
-        return $this;
-    }
-
-    /**
-     * Sets the specified variable in the query string.
-     *
-     * @param string $name  variable name
-     * @param mixed  $value variable value
-     *
-     * @return $this
-     */
-    public function setQueryVariable($name, $value)
-    {
-        $array = $this->getQueryVariables();
-        $array[$name] = $value;
-        $this->setQueryVariables($array);
-        return $this;
-    }
-
-    /**
-     * Removes the specifed variable from the query string.
-     *
-     * @param string $name a query string variable, e.g. "foo" in "?foo=1"
-     *
-     * @return void
-     */
-    public function unsetQueryVariable($name)
-    {
-        $array = $this->getQueryVariables();
-        unset($array[$name]);
-        $this->setQueryVariables($array);
-    }
-
-    /**
-     * Returns a string representation of this URL.
-     *
-     * @return  string
-     */
-    public function getURL()
-    {
-        // See RFC 3986, section 5.3
-        $url = "";
-
-        if ($this->_scheme !== false) {
-            $url .= $this->_scheme . ':';
-        }
-
-        $authority = $this->getAuthority();
-        if ($authority !== false) {
-            $url .= '//' . $authority;
-        }
-        $url .= $this->_path;
-
-        if ($this->_query !== false) {
-            $url .= '?' . $this->_query;
-        }
-
-        if ($this->_fragment !== false) {
-            $url .= '#' . $this->_fragment;
-        }
-    
-        return $url;
-    }
-
-    /**
-     * Returns a string representation of this URL.
-     *
-     * @return  string
-     * @see toString()
-     */
-    public function __toString()
-    {
-        return $this->getURL();
-    }
-
-    /** 
-     * Returns a normalized string representation of this URL. This is useful
-     * for comparison of URLs.
-     *
-     * @return  string
-     */
-    public function getNormalizedURL()
-    {
-        $url = clone $this;
-        $url->normalize();
-        return $url->getUrl();
-    }
-
-    /** 
-     * Returns a normalized Net_URL2 instance.
-     *
-     * @return  Net_URL2
-     */
-    public function normalize()
-    {
-        // See RFC 3886, section 6
-
-        // Schemes are case-insensitive
-        if ($this->_scheme) {
-            $this->_scheme = strtolower($this->_scheme);
-        }
-
-        // Hostnames are case-insensitive
-        if ($this->_host) {
-            $this->_host = strtolower($this->_host);
-        }
-
-        // Remove default port number for known schemes (RFC 3986, section 6.2.3)
-        if ($this->_port &&
-            $this->_scheme &&
-            $this->_port == getservbyname($this->_scheme, 'tcp')) {
-
-            $this->_port = false;
-        }
-
-        // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
-        foreach (array('_userinfo', '_host', '_path') as $part) {
-            if ($this->$part) {
-                $this->$part = preg_replace('/%[0-9a-f]{2}/ie',
-                                            'strtoupper("\0")',
-                                            $this->$part);
-            }
-        }
-
-        // Path segment normalization (RFC 3986, section 6.2.2.3)
-        $this->_path = self::removeDotSegments($this->_path);
-
-        // Scheme based normalization (RFC 3986, section 6.2.3)
-        if ($this->_host && !$this->_path) {
-            $this->_path = '/';
-        }
-    }
-
-    /**
-     * Returns whether this instance represents an absolute URL.
-     *
-     * @return  bool
-     */
-    public function isAbsolute()
-    {
-        return (bool) $this->_scheme;
-    }
-
-    /**
-     * Returns an Net_URL2 instance representing an absolute URL relative to
-     * this URL.
-     *
-     * @param Net_URL2|string $reference relative URL
-     *
-     * @return Net_URL2
-     */
-    public function resolve($reference)
-    {
-        if (!$reference instanceof Net_URL2) {
-            $reference = new self($reference);
-        }
-        if (!$this->isAbsolute()) {
-            throw new Exception('Base-URL must be absolute');
-        }
-
-        // A non-strict parser may ignore a scheme in the reference if it is
-        // identical to the base URI's scheme.
-        if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
-            $reference->_scheme = false;
-        }
-
-        $target = new self('');
-        if ($reference->_scheme !== false) {
-            $target->_scheme = $reference->_scheme;
-            $target->setAuthority($reference->getAuthority());
-            $target->_path  = self::removeDotSegments($reference->_path);
-            $target->_query = $reference->_query;
-        } else {
-            $authority = $reference->getAuthority();
-            if ($authority !== false) {
-                $target->setAuthority($authority);
-                $target->_path  = self::removeDotSegments($reference->_path);
-                $target->_query = $reference->_query;
-            } else {
-                if ($reference->_path == '') {
-                    $target->_path = $this->_path;
-                    if ($reference->_query !== false) {
-                        $target->_query = $reference->_query;
-                    } else {
-                        $target->_query = $this->_query;
-                    }
-                } else {
-                    if (substr($reference->_path, 0, 1) == '/') {
-                        $target->_path = self::removeDotSegments($reference->_path);
-                    } else {
-                        // Merge paths (RFC 3986, section 5.2.3)
-                        if ($this->_host !== false && $this->_path == '') {
-                            $target->_path = '/' . $this->_path;
-                        } else {
-                            $i = strrpos($this->_path, '/');
-                            if ($i !== false) {
-                                $target->_path = substr($this->_path, 0, $i + 1);
-                            }
-                            $target->_path .= $reference->_path;
-                        }
-                        $target->_path = self::removeDotSegments($target->_path);
-                    }
-                    $target->_query = $reference->_query;
-                }
-                $target->setAuthority($this->getAuthority());
-            }
-            $target->_scheme = $this->_scheme;
-        }
-
-        $target->_fragment = $reference->_fragment;
-
-        return $target;
-    }
-
-    /**
-     * Removes dots as described in RFC 3986, section 5.2.4, e.g.
-     * "/foo/../bar/baz" => "/bar/baz"
-     *
-     * @param string $path a path
-     *
-     * @return string a path
-     */
-    public static function removeDotSegments($path)
-    {
-        $output = '';
-
-        // Make sure not to be trapped in an infinite loop due to a bug in this
-        // method
-        $j = 0;
-        while ($path && $j++ < 100) {
-            if (substr($path, 0, 2) == './') {
-                // Step 2.A
-                $path = substr($path, 2);
-            } elseif (substr($path, 0, 3) == '../') {
-                // Step 2.A
-                $path = substr($path, 3);
-            } elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
-                // Step 2.B
-                $path = '/' . substr($path, 3);
-            } elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
-                // Step 2.C
-                $path   = '/' . substr($path, 4);
-                $i      = strrpos($output, '/');
-                $output = $i === false ? '' : substr($output, 0, $i);
-            } elseif ($path == '.' || $path == '..') {
-                // Step 2.D
-                $path = '';
-            } else {
-                // Step 2.E
-                $i = strpos($path, '/');
-                if ($i === 0) {
-                    $i = strpos($path, '/', 1);
-                }
-                if ($i === false) {
-                    $i = strlen($path);
-                }
-                $output .= substr($path, 0, $i);
-                $path = substr($path, $i);
-            }
-        }
-
-        return $output;
-    }
-
-    /**
-     * Percent-encodes all non-alphanumeric characters except these: _ . - ~
-     * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
-     * 5.2.x and earlier.
-     *
-     * @param  $raw the string to encode
-     * @return string
-     */
-    public static function urlencode($string)
-    {
-    	$encoded = rawurlencode($string);
-
-        // This is only necessary in PHP < 5.3.
-        $encoded = str_replace('%7E', '~', $encoded);
-        return $encoded;
-    }
-
-    /**
-     * Returns a Net_URL2 instance representing the canonical URL of the
-     * currently executing PHP script.
-     *
-     * @return  string
-     */
-    public static function getCanonical()
-    {
-        if (!isset($_SERVER['REQUEST_METHOD'])) {
-            // ALERT - no current URL
-            throw new Exception('Script was not called through a webserver');
-        }
-
-        // Begin with a relative URL
-        $url = new self($_SERVER['PHP_SELF']);
-        $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
-        $url->_host   = $_SERVER['SERVER_NAME'];
-        $port = $_SERVER['SERVER_PORT'];
-        if ($url->_scheme == 'http' && $port != 80 ||
-            $url->_scheme == 'https' && $port != 443) {
-
-            $url->_port = $port;
-        }
-        return $url;
-    }
-
-    /**
-     * Returns the URL used to retrieve the current request.
-     *
-     * @return  string
-     */
-    public static function getRequestedURL()
-    {
-        return self::getRequested()->getUrl();
-    }
-
-    /**
-     * Returns a Net_URL2 instance representing the URL used to retrieve the
-     * current request.
-     *
-     * @return  Net_URL2
-     */
-    public static function getRequested()
-    {
-        if (!isset($_SERVER['REQUEST_METHOD'])) {
-            // ALERT - no current URL
-            throw new Exception('Script was not called through a webserver');
-        }
-
-        // Begin with a relative URL
-        $url = new self($_SERVER['REQUEST_URI']);
-        $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
-        // Set host and possibly port
-        $url->setAuthority($_SERVER['HTTP_HOST']);
-        return $url;
-    }
-
-    /**
-     * Returns the value of the specified option.
-     *
-     * @param string $optionName The name of the option to retrieve
-     *
-     * @return  mixed
-     */
-    public function getOption($optionName)
-    {
-        return isset($this->_options[$optionName])
-            ? $this->_options[$optionName] : false;
-    }
-
-    /**
-     * A simple version of http_build_query in userland. The encoded string is
-     * percentage encoded according to RFC 3986.
-     *
-     * @param array  $data      An array, which has to be converted into
-     *                          QUERY_STRING. Anything is possible.
-     * @param string $seperator See {@link self::OPTION_SEPARATOR_OUTPUT}
-     * @param string $key       For stacked values (arrays in an array).
-     *
-     * @return string
-     */
-    protected function buildQuery(array $data, $separator, $key = null)
-    {
-        $query = array();
-        foreach ($data as $name => $value) {
-            if ($this->getOption(self::OPTION_ENCODE_KEYS) === true) {
-                $name = rawurlencode($name);
-            }
-            if ($key !== null) {
-                if ($this->getOption(self::OPTION_USE_BRACKETS) === true) {
-                    $name = $key . '[' . $name . ']';
-                } else {
-                    $name = $key;
-                }
-            }
-            if (is_array($value)) {
-                $query[] = $this->buildQuery($value, $separator, $name);
-            } else {
-                $query[] = $name . '=' . rawurlencode($value);
-            }
-        }
-        return implode($separator, $query);
-    }
-
-    /**
-     * This method uses a funky regex to parse the url into the designated parts.
-     *
-     * @param string $url
-     *
-     * @return void
-     * @uses   self::$_scheme, self::setAuthority(), self::$_path, self::$_query,
-     *         self::$_fragment
-     * @see    self::__construct()
-     */
-    protected function parseUrl($url)
-    {
-        // The regular expression is copied verbatim from RFC 3986, appendix B.
-        // The expression does not validate the URL but matches any string.
-        preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!',
-                   $url,
-                   $matches);
-
-        // "path" is always present (possibly as an empty string); the rest
-        // are optional.
-        $this->_scheme   = !empty($matches[1]) ? $matches[2] : false;
-        $this->setAuthority(!empty($matches[3]) ? $matches[4] : false);
-        $this->_path     = $matches[5];
-        $this->_query    = !empty($matches[6]) ? $matches[7] : false;
-        $this->_fragment = !empty($matches[8]) ? $matches[9] : false;
-    }
-}
