From 5acc58092025d08753f59c0a19f24e3a785b1ecb Mon Sep 17 00:00:00 2001
From: Eric Rasmussen <erasmussen2@unl.edu>
Date: Wed, 27 Apr 2011 19:10:58 +0000
Subject: [PATCH] Add UNL_Auth and SimpleCAS packages to lib

---
 .../configsnapshot-2011-04-27 13-54-20.xml    |    2 +
 lib/.pear2registry                            |  Bin 199680 -> 252928 bytes
 .../channel-simplecas.googlecode.com##svn.xml |   15 +
 .../channels/channelalias-simplecas.txt       |    1 +
 .../HTTP_Request2/2.0.0beta3-info.xml         |  456 ++
 .../pear.php.net/Net_URL2/0.3.1-info.xml      |  100 +
 .../pear.unl.edu/UNL_Auth/0.4.0-info.xml      |  178 +
 .../SimpleCAS/0.5.0-info.xml                  |  225 +
 lib/data/HTTP_Request2/HTTP/generate-list.php |   98 +
 .../HTTP_Request2/HTTP/public-suffix-list.php | 4464 +++++++++++++++++
 .../HTTP/examples/upload-rapidshare.php       |   60 +
 lib/docs/Net_URL2/Net/docs/6470.php           |   75 +
 lib/docs/Net_URL2/Net/docs/example.php        |   74 +
 .../examples/Zend_Auth_Adapter_SimpleCAS.php  |  134 +
 lib/docs/SimpleCAS/docs/examples/simple.php   |   27 +
 .../docs/examples/CASPEARAuth_example.php     |   26 +
 .../UNL_Auth/docs/examples/CAS_example.php    |   22 +
 .../docs/examples/SimpleCAS_example.php       |   22 +
 .../docs/examples/Zend_SimpleCAS_example.php  |   26 +
 lib/downloads/HTTP_Request2-2.0.0beta3.tgz    |  Bin 0 -> 95266 bytes
 lib/downloads/Net_URL2-0.3.1.tgz              |  Bin 0 -> 8488 bytes
 lib/downloads/SimpleCAS-0.5.0.tgz             |  Bin 0 -> 7565 bytes
 lib/downloads/UNL_Auth-0.4.0.tgz              |  Bin 0 -> 5633 bytes
 lib/php/HTTP/Request2.php                     | 1015 ++++
 lib/php/HTTP/Request2/Adapter.php             |  154 +
 lib/php/HTTP/Request2/Adapter/Curl.php        |  562 +++
 lib/php/HTTP/Request2/Adapter/Mock.php        |  171 +
 lib/php/HTTP/Request2/Adapter/Socket.php      | 1084 ++++
 lib/php/HTTP/Request2/CookieJar.php           |  499 ++
 lib/php/HTTP/Request2/Exception.php           |  160 +
 lib/php/HTTP/Request2/MultipartBody.php       |  274 +
 lib/php/HTTP/Request2/Observer/Log.php        |  215 +
 lib/php/HTTP/Request2/Response.php            |  629 +++
 lib/php/Net/URL2.php                          |  894 ++++
 lib/php/SimpleCAS.php                         |  274 +
 lib/php/SimpleCAS/Autoload.php                |   62 +
 lib/php/SimpleCAS/Protocol.php                |   83 +
 lib/php/SimpleCAS/Protocol/Version1.php       |  133 +
 lib/php/SimpleCAS/Protocol/Version2.php       |   94 +
 .../Protocol/Version2/ValidationResponse.php  |   62 +
 lib/php/SimpleCAS/ProxyGranting.php           |   31 +
 lib/php/SimpleCAS/ProxyGranting/Storage.php   |    7 +
 .../SimpleCAS/ProxyGranting/Storage/File.php  |   14 +
 lib/php/SimpleCAS/SingleSignOut.php           |   24 +
 lib/php/UNL/Auth.php                          |  118 +
 lib/php/UNL/Auth/CAS.php                      |  157 +
 lib/php/UNL/Auth/CAS/PEARAuth.php             |   65 +
 lib/php/UNL/Auth/SimpleCAS.php                |  107 +
 lib/php/UNL/Auth/SimpleCAS/ZendAuth.php       |   78 +
 lib/tests/HTTP_Request2/HTTP/AllTests.php     |   77 +
 .../HTTP_Request2/HTTP/NetworkConfig.php.dist |   72 +
 lib/tests/HTTP_Request2/HTTP/ObserverTest.php |  118 +
 .../HTTP/Request2/Adapter/AllTests.php        |   93 +
 .../Request2/Adapter/CommonNetworkTest.php    |  309 ++
 .../HTTP/Request2/Adapter/CurlTest.php        |  143 +
 .../HTTP/Request2/Adapter/MockTest.php        |  145 +
 .../HTTP/Request2/Adapter/SkippedTests.php    |   79 +
 .../HTTP/Request2/Adapter/SocketProxyTest.php |   77 +
 .../HTTP/Request2/Adapter/SocketTest.php      |   78 +
 .../HTTP_Request2/HTTP/Request2/AllTests.php  |   79 +
 .../HTTP/Request2/CookieJarTest.php           |  393 ++
 .../HTTP/Request2/MultipartBodyTest.php       |  125 +
 .../HTTP/Request2/ResponseTest.php            |  151 +
 lib/tests/HTTP_Request2/HTTP/Request2Test.php |  381 ++
 lib/tests/HTTP_Request2/HTTP/TestHelper.php   |   62 +
 lib/tests/HTTP_Request2/HTTP/_files/bug_15305 |  Bin 0 -> 16338 bytes
 lib/tests/HTTP_Request2/HTTP/_files/bug_18169 |    9 +
 lib/tests/HTTP_Request2/HTTP/_files/empty.gif |  Bin 0 -> 43 bytes
 .../HTTP_Request2/HTTP/_files/plaintext.txt   |    1 +
 .../HTTP/_files/response_cookies              |   13 +
 .../HTTP/_files/response_deflate              |  Bin 0 -> 1654 bytes
 .../HTTP_Request2/HTTP/_files/response_gzip   |  Bin 0 -> 1672 bytes
 .../HTTP/_files/response_gzip_broken          |  Bin 0 -> 221 bytes
 .../HTTP/_files/response_headers              |   12 +
 .../HTTP_Request2/HTTP/_network/basicauth.php |   56 +
 .../HTTP_Request2/HTTP/_network/cookies.php   |   47 +
 .../HTTP/_network/digestauth.php              |  106 +
 .../HTTP/_network/getparameters.php           |   47 +
 .../HTTP/_network/postparameters.php          |   47 +
 .../HTTP/_network/rawpostdata.php             |   45 +
 .../HTTP_Request2/HTTP/_network/redirects.php |   70 +
 .../HTTP_Request2/HTTP/_network/setcookie.php |   50 +
 .../HTTP_Request2/HTTP/_network/timeout.php   |   46 +
 .../HTTP_Request2/HTTP/_network/uploads.php   |   55 +
 84 files changed, 15957 insertions(+)
 create mode 100644 lib/.configsnapshots/configsnapshot-2011-04-27 13-54-20.xml
 create mode 100644 lib/.xmlregistry/channels/channel-simplecas.googlecode.com##svn.xml
 create mode 100644 lib/.xmlregistry/channels/channelalias-simplecas.txt
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/2.0.0beta3-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/Net_URL2/0.3.1-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.unl.edu/UNL_Auth/0.4.0-info.xml
 create mode 100644 lib/.xmlregistry/packages/simplecas.googlecode.com!svn/SimpleCAS/0.5.0-info.xml
 create mode 100644 lib/data/HTTP_Request2/HTTP/generate-list.php
 create mode 100644 lib/data/HTTP_Request2/HTTP/public-suffix-list.php
 create mode 100644 lib/docs/HTTP_Request2/HTTP/examples/upload-rapidshare.php
 create mode 100644 lib/docs/Net_URL2/Net/docs/6470.php
 create mode 100644 lib/docs/Net_URL2/Net/docs/example.php
 create mode 100644 lib/docs/SimpleCAS/docs/examples/Zend_Auth_Adapter_SimpleCAS.php
 create mode 100644 lib/docs/SimpleCAS/docs/examples/simple.php
 create mode 100644 lib/docs/UNL_Auth/docs/examples/CASPEARAuth_example.php
 create mode 100644 lib/docs/UNL_Auth/docs/examples/CAS_example.php
 create mode 100644 lib/docs/UNL_Auth/docs/examples/SimpleCAS_example.php
 create mode 100644 lib/docs/UNL_Auth/docs/examples/Zend_SimpleCAS_example.php
 create mode 100644 lib/downloads/HTTP_Request2-2.0.0beta3.tgz
 create mode 100644 lib/downloads/Net_URL2-0.3.1.tgz
 create mode 100644 lib/downloads/SimpleCAS-0.5.0.tgz
 create mode 100644 lib/downloads/UNL_Auth-0.4.0.tgz
 create mode 100644 lib/php/HTTP/Request2.php
 create mode 100644 lib/php/HTTP/Request2/Adapter.php
 create mode 100644 lib/php/HTTP/Request2/Adapter/Curl.php
 create mode 100644 lib/php/HTTP/Request2/Adapter/Mock.php
 create mode 100644 lib/php/HTTP/Request2/Adapter/Socket.php
 create mode 100644 lib/php/HTTP/Request2/CookieJar.php
 create mode 100644 lib/php/HTTP/Request2/Exception.php
 create mode 100644 lib/php/HTTP/Request2/MultipartBody.php
 create mode 100644 lib/php/HTTP/Request2/Observer/Log.php
 create mode 100644 lib/php/HTTP/Request2/Response.php
 create mode 100644 lib/php/Net/URL2.php
 create mode 100644 lib/php/SimpleCAS.php
 create mode 100644 lib/php/SimpleCAS/Autoload.php
 create mode 100644 lib/php/SimpleCAS/Protocol.php
 create mode 100644 lib/php/SimpleCAS/Protocol/Version1.php
 create mode 100644 lib/php/SimpleCAS/Protocol/Version2.php
 create mode 100644 lib/php/SimpleCAS/Protocol/Version2/ValidationResponse.php
 create mode 100644 lib/php/SimpleCAS/ProxyGranting.php
 create mode 100644 lib/php/SimpleCAS/ProxyGranting/Storage.php
 create mode 100644 lib/php/SimpleCAS/ProxyGranting/Storage/File.php
 create mode 100644 lib/php/SimpleCAS/SingleSignOut.php
 create mode 100644 lib/php/UNL/Auth.php
 create mode 100644 lib/php/UNL/Auth/CAS.php
 create mode 100644 lib/php/UNL/Auth/CAS/PEARAuth.php
 create mode 100644 lib/php/UNL/Auth/SimpleCAS.php
 create mode 100644 lib/php/UNL/Auth/SimpleCAS/ZendAuth.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/AllTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/NetworkConfig.php.dist
 create mode 100644 lib/tests/HTTP_Request2/HTTP/ObserverTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/AllTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CommonNetworkTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CurlTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/MockTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SkippedTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketProxyTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/AllTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/CookieJarTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/MultipartBodyTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2/ResponseTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/Request2Test.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/TestHelper.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/bug_15305
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/bug_18169
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/empty.gif
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/plaintext.txt
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/response_cookies
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/response_deflate
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/response_gzip
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/response_gzip_broken
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_files/response_headers
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/basicauth.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/cookies.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/digestauth.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/getparameters.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/postparameters.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/rawpostdata.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/redirects.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/setcookie.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/timeout.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/_network/uploads.php

diff --git a/lib/.configsnapshots/configsnapshot-2011-04-27 13-54-20.xml b/lib/.configsnapshots/configsnapshot-2011-04-27 13-54-20.xml
new file mode 100644
index 0000000..69268a5
--- /dev/null
+++ b/lib/.configsnapshots/configsnapshot-2011-04-27 13-54-20.xml	
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<pearconfig version="1.0"><php_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/php</php_dir><ext_dir>/usr/lib/php/extensions/no-debug-non-zts-20090626</ext_dir><cfg_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/cfg</cfg_dir><doc_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/docs</doc_dir><bin_dir>/usr/bin</bin_dir><data_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/data</data_dir><www_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/www</www_dir><test_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/tests</test_dir><src_dir>/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/src</src_dir><php_bin>/usr/bin/php</php_bin><php_ini>/private/etc/php.ini</php_ini><php_prefix></php_prefix><php_suffix></php_suffix></pearconfig>
diff --git a/lib/.pear2registry b/lib/.pear2registry
index 981d851a89012802bf650edc0cf7e399f415cbc1..2c744411401dd7b7a83105483f03f40659058bd2 100644
GIT binary patch
delta 37736
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

delta 2308
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
a84f1KKMYL&82@Y*<oUq3{SPZM3mX7QCwkog

diff --git a/lib/.xmlregistry/channels/channel-simplecas.googlecode.com##svn.xml b/lib/.xmlregistry/channels/channel-simplecas.googlecode.com##svn.xml
new file mode 100644
index 0000000..dc7b714
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-simplecas.googlecode.com##svn.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<channel version="1.0" xmlns="http://pear.php.net/channel-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/channel-1.0http://pear.php.net/dtd/channel-1.0.xsd">
+ <name>simplecas.googlecode.com/svn</name>
+ <suggestedalias>simplecas</suggestedalias>
+ <summary>simplecas</summary>
+ <servers>
+  <primary>
+   <rest>
+    <baseurl type="REST1.0">http://simplecas.googlecode.com/svn/rest/</baseurl>
+    <baseurl type="REST1.1">http://simplecas.googlecode.com/svn/rest/</baseurl>
+    <baseurl type="REST1.3">http://simplecas.googlecode.com/svn/rest/</baseurl>
+   </rest>
+  </primary>
+ </servers>
+</channel>
diff --git a/lib/.xmlregistry/channels/channelalias-simplecas.txt b/lib/.xmlregistry/channels/channelalias-simplecas.txt
new file mode 100644
index 0000000..fdae489
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-simplecas.txt
@@ -0,0 +1 @@
+simplecas.googlecode.com/svn
\ No newline at end of file
diff --git a/lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/2.0.0beta3-info.xml b/lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/2.0.0beta3-info.xml
new file mode 100644
index 0000000..6a1f8a8
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/2.0.0beta3-info.xml
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.2" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>HTTP_Request2</name>
+ <channel>pear.php.net</channel>
+ <extends>HTTP_Request</extends>
+ <summary>Provides an easy way to perform HTTP requests.</summary>
+ <description>PHP5 rewrite of HTTP_Request package (with parts of HTTP_Client). Provides
+cleaner API and pluggable Adapters:
+  * Socket adapter, based on old HTTP_Request code,
+  * Curl adapter, wraps around PHP's cURL extension,
+  * Mock adapter, to use for testing packages dependent on HTTP_Request2.
+Supports POST requests with data and file uploads, basic and digest 
+authentication, cookies, managing cookies across requests, proxies, gzip and
+deflate encodings, redirects, monitoring the request progress with Observers...</description>
+ <lead>
+  <name>Alexey Borzov</name>
+  <user>avb</user>
+  <email>avb@php.net</email>
+  <active>yes</active>
+ </lead>
+ <date>2011-04-27</date>
+ <time>13:58:16</time>
+ <version>
+  <release>2.0.0beta3</release>
+  <api>2.0.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+ <notes>
+* Added getEffectiveUrl() method to Response object, it returns the URL
+  response was received from, possibly after redirects (request #18412)
+* Curl Adapter didn't send body for PUT requests sometimes (bug #18421)
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="HTTP" md5sum="1740e401dcff9571ad169bf19aa448cc" name="tests/_network/uploads.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="5e7fd3d5d3b00d47e00537c439f0a41a" name="tests/_network/timeout.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="c46e248a0638a6e020526be68693d988" name="tests/_network/setcookie.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="fda4c343b048f49ecc1e6028e03f17d7" name="tests/_network/redirects.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="91254800e447670614c62002717d92da" name="tests/_network/rawpostdata.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="db9014f908c679bdbea37b5c00b62dab" name="tests/_network/postparameters.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="21da3787253321dde0c4d7991f2d8a9c" name="tests/_network/getparameters.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="9d9f06f2307c02781238eb2532774c27" name="tests/_network/digestauth.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="7d29cd6f3df453a40f362ea31f079fb7" name="tests/_network/cookies.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="415f4b4ff843b6cb7530b9571ae3f962" name="tests/_network/basicauth.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="1fb55dfe18831f8fe6280280e72ad216" name="tests/_files/response_headers" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="722328bfe89a9c9f7de5a020ed2c4589" name="tests/_files/response_gzip_broken" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="c36530c79c044fde1745b244c38d381f" name="tests/_files/response_gzip" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="12d80db889f528922a31b5c03f693647" name="tests/_files/response_deflate" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="d1d2beb78782f56e8611100a009fb1f6" name="tests/_files/response_cookies" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="120ea8a25e5d487bf68b5f7096440019" name="tests/_files/plaintext.txt" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="fc94fb0c3ed8a8f909dbc7630a0987ff" name="tests/_files/empty.gif" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="16f23f14921a2aa607c85664efa47d41" name="tests/_files/bug_18169" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="22d7f11b85dd00bd8919a4226a5a0388" name="tests/_files/bug_15305" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="6dc93662dd42cf76a457c6fff5b8df20" name="tests/TestHelper.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="c9839810b6416ce1521ab1c721853ef6" name="tests/Request2Test.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="9be337588f6c6d2b795d27d185cd1c92" name="tests/Request2/ResponseTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="c427be4a318a1002ef0df67b05a39276" name="tests/Request2/MultipartBodyTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="fc16142b51b1a110455911d3d5f4685a" name="tests/Request2/CookieJarTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="8bdcae5a16da6a577681309c7958fe68" name="tests/Request2/AllTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="866a71b2fcf1632f3ffddf11142fd20e" name="tests/Request2/Adapter/SocketTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="416ae359f326d574871755d6d630a2b0" name="tests/Request2/Adapter/SocketProxyTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="6ac2d3e86cb81eb739a094b72f18a609" name="tests/Request2/Adapter/SkippedTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="4ba446d73bb389557284233c88f26dbd" name="tests/Request2/Adapter/MockTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="d825a52bb83675833ec0f022efa50688" name="tests/Request2/Adapter/CurlTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="8a9c7037d525fc6c723db266f74ecddf" name="tests/Request2/Adapter/CommonNetworkTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="80b934c16d2876f8ef1fb6e5afc7ae19" name="tests/Request2/Adapter/AllTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="f9fa9893f4241ba54d8b9f758f4a5dd5" name="tests/ObserverTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="62c675708ac7a594cfd18137ac869dfc" name="tests/NetworkConfig.php.dist" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="0d6142d9cbf8b81c5b22c9982a750215" name="tests/AllTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="0ec6a02c97f25ef76ead19b0cdbd87d3" name="Request2/Response.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="cf5d76e80409a85597a91de1e91c6ee1" name="Request2/Observer/Log.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="68ec0b653d74c8eb279882e5ee9dc8ad" name="Request2/MultipartBody.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="2df8b0b6b1393db00621fea5c12adb25" name="Request2/Exception.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="88bca86278b570e760d1b4bece6ebbb0" name="Request2/CookieJar.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+    <tasks:replace from="@data_dir@" to="data_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="f276265e7e4b84a85c8215e2f74caea7" name="Request2/Adapter/Socket.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="aa47b70e43fda0e597cd91e3b13fe717" name="Request2/Adapter/Mock.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="448312f853d4447325c974486e5d6b3c" name="Request2/Adapter/Curl.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="0d68ac49d4a4b87c13e0f523c069ee3b" name="Request2/Adapter.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="0a34a995006ebace077e2dd87a292a8f" name="Request2.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="7e6017dfdf042dbd443ce6c8c024f40d" name="docs/examples/upload-rapidshare.php" role="doc"/>
+   <file baseinstalldir="HTTP" md5sum="46d7644aa37dd6bf9b200820a29a277c" name="data/public-suffix-list.php" role="data"/>
+   <file baseinstalldir="HTTP" md5sum="389143b973e6c1d87926d803ca5fceec" name="data/generate-list.php" role="data"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.5.4</min>
+   </pearinstaller>
+   <package>
+    <name>Net_URL2</name>
+    <channel>pear.php.net</channel>
+    <min>0.3.0</min>
+   </package>
+  </required>
+  <optional>
+   <extension>
+    <name>curl</name>
+   </extension>
+   <extension>
+    <name>fileinfo</name>
+   </extension>
+   <extension>
+    <name>zlib</name>
+   </extension>
+   <extension>
+    <name>openssl</name>
+   </extension>
+  </optional>
+ </dependencies>
+ <phprelease>
+  <filelist>
+   <install as="generate-list.php" name="data/generate-list.php"/>
+   <install as="public-suffix-list.php" name="data/public-suffix-list.php"/>
+   <install as="examples/upload-rapidshare.php" name="docs/examples/upload-rapidshare.php"/>
+   <install as="AllTests.php" name="tests/AllTests.php"/>
+   <install as="NetworkConfig.php.dist" name="tests/NetworkConfig.php.dist"/>
+   <install as="ObserverTest.php" name="tests/ObserverTest.php"/>
+   <install as="Request2/Adapter/AllTests.php" name="tests/Request2/Adapter/AllTests.php"/>
+   <install as="Request2/Adapter/CommonNetworkTest.php" name="tests/Request2/Adapter/CommonNetworkTest.php"/>
+   <install as="Request2/Adapter/CurlTest.php" name="tests/Request2/Adapter/CurlTest.php"/>
+   <install as="Request2/Adapter/MockTest.php" name="tests/Request2/Adapter/MockTest.php"/>
+   <install as="Request2/Adapter/SkippedTests.php" name="tests/Request2/Adapter/SkippedTests.php"/>
+   <install as="Request2/Adapter/SocketProxyTest.php" name="tests/Request2/Adapter/SocketProxyTest.php"/>
+   <install as="Request2/Adapter/SocketTest.php" name="tests/Request2/Adapter/SocketTest.php"/>
+   <install as="Request2/AllTests.php" name="tests/Request2/AllTests.php"/>
+   <install as="Request2/CookieJarTest.php" name="tests/Request2/CookieJarTest.php"/>
+   <install as="Request2/MultipartBodyTest.php" name="tests/Request2/MultipartBodyTest.php"/>
+   <install as="Request2/ResponseTest.php" name="tests/Request2/ResponseTest.php"/>
+   <install as="Request2Test.php" name="tests/Request2Test.php"/>
+   <install as="TestHelper.php" name="tests/TestHelper.php"/>
+   <install as="_files/bug_15305" name="tests/_files/bug_15305"/>
+   <install as="_files/bug_18169" name="tests/_files/bug_18169"/>
+   <install as="_files/empty.gif" name="tests/_files/empty.gif"/>
+   <install as="_files/plaintext.txt" name="tests/_files/plaintext.txt"/>
+   <install as="_files/response_cookies" name="tests/_files/response_cookies"/>
+   <install as="_files/response_deflate" name="tests/_files/response_deflate"/>
+   <install as="_files/response_gzip" name="tests/_files/response_gzip"/>
+   <install as="_files/response_gzip_broken" name="tests/_files/response_gzip_broken"/>
+   <install as="_files/response_headers" name="tests/_files/response_headers"/>
+   <install as="_network/basicauth.php" name="tests/_network/basicauth.php"/>
+   <install as="_network/cookies.php" name="tests/_network/cookies.php"/>
+   <install as="_network/digestauth.php" name="tests/_network/digestauth.php"/>
+   <install as="_network/getparameters.php" name="tests/_network/getparameters.php"/>
+   <install as="_network/postparameters.php" name="tests/_network/postparameters.php"/>
+   <install as="_network/rawpostdata.php" name="tests/_network/rawpostdata.php"/>
+   <install as="_network/redirects.php" name="tests/_network/redirects.php"/>
+   <install as="_network/setcookie.php" name="tests/_network/setcookie.php"/>
+   <install as="_network/timeout.php" name="tests/_network/timeout.php"/>
+   <install as="_network/uploads.php" name="tests/_network/uploads.php"/>
+  </filelist>
+ </phprelease>
+ <changelog>
+  <release>
+   <version>
+    <release>2.0.0beta2</release>
+    <api>2.0.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2011-03-25</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+* Unit tests can now be run under recent PHPUnit versions (3.5+)
+* Public Suffix List updated to current version
+* PHP warning produced by stream_socket_client() in Socket adapter is now 
+  added to Exception message (bug #18331)
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>2.0.0beta1</release>
+    <api>2.0.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2011-02-27</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+Additions and changes:
+  * Implemented cookie jar that allows to store and pass cookies across HTTP
+    requests (see request #18225)
+  * Added several specialized subclasses of HTTP_Request2_Exception, they are
+    now thrown instead of the parent. Also added error codes and possibility
+    to get native error code (as returned by stream_socket_client() and 
+    curl_errno()) (request #16762)
+  * An additional 'sentBody' event is now sent to Observers (request #16828) 
+  * setBody() and addUpload() can now accept file pointers (request #16863)
+
+Bugfixes:
+  * Incorrect check in Socket Adapter prevented Keep-alive from working in
+    some cases (bug #17031)
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.6.0</release>
+    <api>0.6.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2011-02-14</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+Additions and changes:
+  * Added test suite that interacts with a webserver. Please refer to 
+    tests/NetworkConfig.php.dist for instructions.
+  * Packaging changes: docs/ and tests/ contents are installed without
+    redundant subdirectories.
+  * Added a $replace parameter to HTTP_Request2::setHeader() that controls
+    whether new header value will overwrite previous one or be appended
+    to it (request #17507)
+
+Bugfixes:
+  * Fixed a typo in Curl Adapter that prevented 'strict_redirects' from working
+  * Curl Adapter will throw an exception if CURLOPT_FOLLOWLOCATION can not be
+    enabled due to PHP setup (bug #17450)
+  * Allow parameters in manually set Content-Type headers (bug #17460)
+  * Properly reset redirect limit if multiple requests are performed with the
+    same instance of Socket Adapter (bug #17826)
+  * Response::getBody() no longer tries to decode empty strings (bug #18169)
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.5.2</release>
+    <api>0.5.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2010-04-21</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+* magic_quotes_runtime PHP setting could be incorrectly enabled after
+  performing the request (bug #16440)
+* Unit tests fixes (bugs #17079, #17106, #17326)
+* Observer_Log now appends to the log file rather than rewrites it (thanks to
+  troelskn at gmail dot com for reporting)
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.5.1</release>
+    <api>0.5.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2009-11-21</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+* Content-Type request header is no longer removed for POST and PUT requests
+  with empty request body (request #16799).
+* CURLOPT_NOBODY option is now set when doing HEAD requests with Curl adapter.
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.5.0</release>
+    <api>0.5.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2009-11-18</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+* Redirect support added, new configuration parameters 'follow_redirects',
+  'max_redirects' and 'strict_redirects' available
+
+* Implemented workaround for PHP bug #47204, Curl Adapter can now handle
+  Digest authentication and redirects when doing POST requests, unfortunately
+  this requires loading the entire request body into memory.
+* Config parameter 'use_brackets' is propagated to created instances of Net_URL2
+* Prevent memory leaks due to circular references (request #16646)
+* Fixed a misleading error message when timing out due to default_socket_timeout
+* HTTP_Request2::setBody() can now accept an instance of HTTP_Request2_MultipartBody
+  without trying to convert it to string
+* Calling HTTP_Request2::setBody() now clears post parameters and uploads
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.4.1</release>
+    <api>0.4.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2009-09-14</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+* Decoding of gzipped responses failed if mbstring.func_overload was enabled
+  (bug #16555)
+* Changed boundary generation in multipart bodies to work correctly with
+  rapidshare.com, added first usage example: file uploading to rapidshare.com
+* Added forgotten optional dependency on OpenSSL PHP extension
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.4.0</release>
+    <api>0.4.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2009-05-03</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+* Added 'store_body' config parameter, if set to false it will prevent storing
+  the response body in Response object (request #15881)
+* HTTP_Request2::setHeader() method now works as documented, setHeader('name') 
+  will remove the 'name' header, while setHeader('name', '') will set 'name'
+  header to empty value (bug #15937)
+* Custom 'Host' header will not be overwritten by generated one (bug #16146)
+* When trying to reuse the connected socket in Socket adapter, make sure that
+  it is still connected (bug #16149)
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.3.0</release>
+    <api>0.3.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2009-01-28</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+API changes:
+ * Removed HTTP_Request2::getConfigValue() method
+
+Feature additions:
+ * Added digest authentication (RFC 2617) support to Socket adapter. Thanks
+   to Tom Snyder (tomsn at inetoffice dot com) who sent me a prototype
+   implementation for HTTP_Request a couple of years ago.
+ * Added HTTPS proxy support to Socket adapter, this works through CONNECT
+   request described in RFC 2817.
+ * Mock adapter can now throw an Exception instead of returning a response
+   if Exception object is added via its addResponse() method (request #15629)
+
+Other changes and fixes:
+ * Support RFC 3986 by not encoding '~' in POST body (request #15368)
+ * Prevent an error with particular versions of PHP and Curl (bug #15617)
+ * Regular expressions used in HTTP_Request2 are now class constants 
+   (request #15630)
+ * Curl adapter now throws an exception in case of malformed (non-HTTP) 
+   response rather than dies with a fatal error (bug #15716)
+ * Curl handle wasn't closed in Curl adapter in case of error (bug #15721)
+ * Curl adapter sent an extra 'sentHeaders' event and returned bogus 
+   response status when server returned 100-Continue response (bug #15785)
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.2.0</release>
+    <api>0.2.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2009-01-07</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+API changes:
+ * HTTP_Request2::getConfigValue() is deprecated and will be removed in next 
+   release. Use HTTP_Request2::getConfig().
+ * Changed HTTP_Request2::setConfig() to accept a pair of parameter name and
+   parameter value in addition to array('parameter name' =&gt; 'value')
+ * Added HTTP_Request2::getConfig() method that can return a single 
+   configuration parameter or the whole configuration array
+
+Other additions and changes:
+ * Added a debug Observer that can log request progress to a file or an 
+   instance of PEAR::Log (thanks to David Jean Louis, request #15424)
+ * Added a new 'timeout' parameter that limits total number of seconds
+   a request can take (see requests #5735 and #8964)
+ * Added various SSL protocol options: 'ssl_verify_peer', 'ssl_verify_host',
+   'ssl_cafile', 'ssl_capath', 'ssl_local_cert', 'ssl_passphrase'. Note that
+   'ssl_verify_host' option behaves differently in Socket and Curl Adapters:
+   http://bugs.php.net/bug.php?id=47030
+
+Fixes:
+ * Fixed 'data error' when processing response encoded by 'deflate'
+   encoding (bug #15305)
+ * Curl Adapter now passes full request headers in 'sentHeaders' event
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.1.0</release>
+    <api>0.1.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2008-11-17</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">BSD License</license>
+   <notes>
+Initial release. The features supported are mostly the same as those of
+HTTP_Request, with the following additional feature requests implemented:
+  * cURL extension support (request #5463)
+  * It is now possible to monitor the file upload progress with Observers
+	(request #7630)
+  * Added 'sentHeaders' notification providing the request headers to the
+    Observers (request #7633)
+  * Added support for 'deflate' encoding (request #11246)
+   </notes>
+  </release>
+ </changelog>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.php.net/Net_URL2/0.3.1-info.xml b/lib/.xmlregistry/packages/pear.php.net/Net_URL2/0.3.1-info.xml
new file mode 100644
index 0000000..295977a
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/Net_URL2/0.3.1-info.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.7.1" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Net_URL2</name>
+ <channel>pear.php.net</channel>
+ <summary>Class for parsing and handling URL.</summary>
+ <description>Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of relative URLs.</description>
+ <lead>
+  <name>David Coallier</name>
+  <user>davidc</user>
+  <email>davidc@php.net</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Christian Schmidt</name>
+  <user>schmidt</user>
+  <email>schmidt@php.net</email>
+  <active>yes</active>
+ </lead>
+ <date>2011-04-27</date>
+ <time>13:58:16</time>
+ <version>
+  <release>0.3.1</release>
+  <api>0.3.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD</license>
+ <notes>* BC break: Removed setOption() to avoid undefined behaviour (bug #16674)
+* Fixed Bug #16854: Invalid package.xml making it impossible to install with Pyrus
+* Fixed Bug #16651: Port may be an empty string
+* Fixed Bug #16653: Don't make OPTION_SEPARATOR_(IN|OUT)PUT default to arg_separator.(in|out)put</notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="Net" md5sum="f0a637e921da7a47373e2b065107c7a0" name="URL2.php" role="php"/>
+   <file baseinstalldir="Net" md5sum="587a224d39fbffa47cacb9fb67b51da1" name="docs/example.php" role="doc"/>
+   <file baseinstalldir="Net" md5sum="ea8b73061588566519fd0e55a230f2a6" name="docs/6470.php" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.0b1</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>0.3.0</release>
+     <api>0.3.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-09-05</date>
+    <license>BSD</license>
+    <notes>* Fixed #14399 (Errors in URL parsing (items #1 and #3))
+* Fixed #14735 (Encode query string values)
+* Fixed #15546 (Add adding __toString())
+* Fixed #15367 (Use RFC 3986-compliant version of rawurlencode() in PHP &lt; 5.2)
+* Fixed #14289 (Add __get() and __set())</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2.0</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-06-18</date>
+    <license>BSD</license>
+    <notes>Major rewrite to comply with RFC3986 (bug 11574).
+   Much better support for resolving relative URLs.
+   WARNING: Method and property names has changed to reflect the terminology used in the RFC - THIS RELEASE IS NOT BACKWARDS COMPATIBLE WITH VERSION 0.1.0.</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.0</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2007-05-08</date>
+    <license>BSD</license>
+    <notes>Convert to PHP5 only. PHP4 users should continue with version 1.0.15</notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.unl.edu/UNL_Auth/0.4.0-info.xml b/lib/.xmlregistry/packages/pear.unl.edu/UNL_Auth/0.4.0-info.xml
new file mode 100644
index 0000000..f93fca7
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.unl.edu/UNL_Auth/0.4.0-info.xml
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0     http://pear.php.net/dtd/tasks-1.0.xsd     http://pear.php.net/dtd/package-2.0     http://pear.php.net/dtd/package-2.0.xsd">
+ <name>UNL_Auth</name>
+ <channel>pear.unl.edu</channel>
+ <summary>An authentication framework for PHP Applications at UNL</summary>
+ <description>This package provides an authentication framework for web 
+applications developed at UNL.</description>
+ <lead>
+  <name>Brett Bieber</name>
+  <user>saltybeagle</user>
+  <email>brett.bieber@gmail.com</email>
+  <active>yes</active>
+ </lead>
+ <date>2011-04-27</date>
+ <time>13:54:20</time>
+ <version>
+  <release>0.4.0</release>
+  <api>0.4.0</api>
+ </version>
+ <stability>
+  <release>alpha</release>
+  <api>alpha</api>
+ </stability>
+ <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+ <notes>
+* Fix E_STRICT warning about static methods.
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="/" md5sum="b7a35f1bfe174ef2725733df1539f212" name="UNL/Auth/SimpleCAS/ZendAuth.php" role="php"/>
+   <file baseinstalldir="/" md5sum="6def037a77fd9fa49bcc5e752cbb8170" name="UNL/Auth/SimpleCAS.php" role="php"/>
+   <file baseinstalldir="/" md5sum="ada4bb738641430ba2420da94ec3e749" name="UNL/Auth/CAS/PEARAuth.php" role="php"/>
+   <file baseinstalldir="/" md5sum="76deaf815ba781ca6f7f6bbcc7095912" name="UNL/Auth/CAS.php" role="php"/>
+   <file baseinstalldir="/" md5sum="f0bb48dadf42f6511b718032203f9c28" name="UNL/Auth.php" role="php"/>
+   <file baseinstalldir="/" md5sum="c4ee1094cd276ff40fbd2b16d66068fe" name="docs/examples/Zend_SimpleCAS_example.php" role="doc"/>
+   <file baseinstalldir="/" md5sum="3a80ba084e5bc5f8b17d188b15e6a7aa" name="docs/examples/SimpleCAS_example.php" role="doc"/>
+   <file baseinstalldir="/" md5sum="3759e0e8f63d4161653c158b08cdd0ed" name="docs/examples/CAS_example.php" role="doc"/>
+   <file baseinstalldir="/" md5sum="e89e49dca8497ec59459d17140c6e63a" name="docs/examples/CASPEARAuth_example.php" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+  </required>
+  <optional>
+   <package>
+    <name>Auth</name>
+    <channel>pear.php.net</channel>
+    <min>1.0</min>
+   </package>
+   <package>
+    <name>CAS</name>
+    <channel>pear.unl.edu</channel>
+    <min>1.0.0</min>
+   </package>
+   <package>
+    <name>SimpleCAS</name>
+    <channel>simplecas.googlecode.com/svn</channel>
+    <min>0.3.0</min>
+   </package>
+  </optional>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>0.1.0</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2007-12-17</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+First Release - only CAS is available.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.1</release>
+     <api>0.1.1</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-05-20</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Check if session is already started - kabel
+* Improve PHP docs and fix example. - bbieber
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2.0</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-08-22</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Upgrade CAS driver dependency to 1.0.0
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3.0</release>
+     <api>0.3.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-12-09</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Enable SimpleCAS support. http://code.google.com/p/simplecas/
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3.1</release>
+     <api>0.3.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-02-12</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Increase SimpleCAS dependency of 0.2.0 to take advantage of getRequest() so we can ignore the ssl peer verification.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3.2</release>
+     <api>0.3.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-03-03</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Increase SimpleCAS dependency of 0.3.0 to use new object names and array options for the constructor.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.4.0</release>
+     <api>0.4.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-11-18</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Fix E_STRICT warning about static methods.
+   </notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/simplecas.googlecode.com!svn/SimpleCAS/0.5.0-info.xml b/lib/.xmlregistry/packages/simplecas.googlecode.com!svn/SimpleCAS/0.5.0-info.xml
new file mode 100644
index 0000000..5fc5b35
--- /dev/null
+++ b/lib/.xmlregistry/packages/simplecas.googlecode.com!svn/SimpleCAS/0.5.0-info.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.1" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0     http://pear.php.net/dtd/tasks-1.0.xsd     http://pear.php.net/dtd/package-2.0     http://pear.php.net/dtd/package-2.0.xsd">
+ <name>SimpleCAS</name>
+ <channel>simplecas.googlecode.com/svn</channel>
+ <summary>A PHP5 library for CAS Authentication.</summary>
+ <description>This package is a PHP5 only library for identifying users
+in a JA-SIG CAS secured environment.</description>
+ <lead>
+  <name>Brett Bieber</name>
+  <user>saltybeagle</user>
+  <email>brett.bieber@gmail.com</email>
+  <active>yes</active>
+ </lead>
+ <helper>
+  <name>John Thiltges</name>
+  <user>jthiltges</user>
+  <email>jthiltges@gmail.com</email>
+  <active>yes</active>
+ </helper>
+ <helper>
+  <name>Kevin Abel</name>
+  <user>kevin.abel.0</user>
+  <email>kevin.abel.0@gmail.com</email>
+  <active>yes</active>
+ </helper>
+ <helper>
+  <name>Eric Rasmussen</name>
+  <user>ericrasmussen1</user>
+  <email>ericrasmussen1@gmail.com</email>
+  <active>yes</active>
+ </helper>
+ <date>2011-04-27</date>
+ <time>13:58:16</time>
+ <version>
+  <release>0.5.0</release>
+  <api>0.5.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+ <notes>
+* Allow service url to be customized with SimpleCAS::setURL($url); [ericrasmussen1]
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="/" md5sum="ad9c06f186ce8fa739d6e716f6c9b48d" name="SimpleCAS/SingleSignOut.php" role="php"/>
+   <file baseinstalldir="/" md5sum="7a49aa1c67563ed628202c3e9244dcdc" name="SimpleCAS/ProxyGranting/Storage/File.php" role="php"/>
+   <file baseinstalldir="/" md5sum="26b6d753c3f9098be6493c818aabd959" name="SimpleCAS/ProxyGranting/Storage.php" role="php"/>
+   <file baseinstalldir="/" md5sum="e96b4c13218c39664fdeb8dc8d4e7541" name="SimpleCAS/ProxyGranting.php" role="php"/>
+   <file baseinstalldir="/" md5sum="46feaaf938c6eb0f7f260125a646b3fb" name="SimpleCAS/Protocol/Version2/ValidationResponse.php" role="php"/>
+   <file baseinstalldir="/" md5sum="f4ed06c8ae5918cfb9790ca72c6256d0" name="SimpleCAS/Protocol/Version2.php" role="php"/>
+   <file baseinstalldir="/" md5sum="80862315b001dcfa1fde9348341ff432" name="SimpleCAS/Protocol/Version1.php" role="php"/>
+   <file baseinstalldir="/" md5sum="daf05e7a073e2ac47ddb0c7ea6a83e33" name="SimpleCAS/Protocol.php" role="php"/>
+   <file baseinstalldir="/" md5sum="d93480efa786598948935145b06352a6" name="SimpleCAS/Autoload.php" role="php"/>
+   <file baseinstalldir="/" md5sum="a9d96c7d2032b5432306ffba5438d0f1" name="SimpleCAS.php" role="php"/>
+   <file baseinstalldir="/" md5sum="9d686c3553b6c8be0af988ddfb363f0c" name="docs/examples/Zend_Auth_Adapter_SimpleCAS.php" role="doc"/>
+   <file baseinstalldir="/" md5sum="2254593f10efc23cd0eadab309506e15" name="docs/examples/simple.php" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.5</min>
+   </php>
+   <pearinstaller>
+    <min>1.5.4</min>
+   </pearinstaller>
+   <package>
+    <name>HTTP_Request2</name>
+    <channel>pear.php.net</channel>
+    <min>0.1.0</min>
+   </package>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>0.1.0</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-12-08</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+First Release.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.1</release>
+     <api>0.1.1</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-12-08</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Fix Notice: Trying to get property of non-object in SimpleCAS/Server/Version2/ValidationResponse.php on line 23
+* Change PHP dependency to 5.2.5
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.2</release>
+     <api>0.1.1</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-02-05</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Update PEAR dependency to 1.5.4
+* Match case for variables (jthiltges)
+* In CAS v2 validateTicket, typecast successful return value to string (jthiltges)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2.0</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-02-11</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Allow setting HTTP_Request2 object so configuration can be set.
+  $server-&gt;getRequest()-&gt;setConfig('ssl_verify_peer', false);
+* Add $server-&gt;getRequest(), $server-&gt;setRequest(HTTP_Request2 $http_request)
+Change interface for server to abstract class.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2.1</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-02-12</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Explicitly call __toString() for PHP 5.1 compatibility. [jthiltges]
+* Add Zend_Auth_Adapter_SimpleCAS to the examples. [jthiltges]
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3.0</release>
+     <api>0.3.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-03-03</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Issue 1: Rename SimpleCAS_Server to SimpleCAS_Protocol [saltybeagle]
+* Issue 2: Switch to arrays for the protocol constructors. [saltybeagle]
+* Exit immediately after re-direct.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3.1</release>
+     <api>0.3.1</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2009-04-06</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Prefix session variables with __SIMPLECAS [saltybeagle]
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.4.0</release>
+     <api>0.4.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2010-01-08</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Allow request adapter to be customized. [Kevin]
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.0</release>
+     <api>0.5.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2010-01-27</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+* Allow service url to be customized with SimpleCAS::setURL($url); [ericrasmussen1]
+   </notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/data/HTTP_Request2/HTTP/generate-list.php b/lib/data/HTTP_Request2/HTTP/generate-list.php
new file mode 100644
index 0000000..839266b
--- /dev/null
+++ b/lib/data/HTTP_Request2/HTTP/generate-list.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Helper file for downloading Public Suffix List and converting it to PHP array
+ *
+ * You can run this script to update PSL to the current version instead of
+ * waiting for a new release of HTTP_Request2.
+ *
+ * @version SVN: $Id: generate-list.php 308480 2011-02-19 11:27:13Z avb $
+ */
+
+/** URL to download Public Suffix List from */
+define('LIST_URL',    'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1');
+/** Name of PHP file to write */
+define('OUTPUT_FILE', dirname(__FILE__) . '/public-suffix-list.php');
+
+require_once 'HTTP/Request2.php';
+
+function buildSubdomain(&$node, $tldParts)
+{
+    $part = trim(array_pop($tldParts));
+
+    if (!array_key_exists($part, $node)) {
+        $node[$part] = array();
+    }
+
+    if (0 < count($tldParts)) {
+        buildSubdomain($node[$part], $tldParts);
+    }
+}
+
+function writeNode($fp, $valueTree, $key = null, $indent = 0)
+{
+    if (is_null($key)) {
+        fwrite($fp, "return ");
+
+    } else {
+        fwrite($fp, str_repeat(' ', $indent) . "'$key' => ");
+    }
+
+    if (0 == ($count = count($valueTree))) {
+        fwrite($fp, 'true');
+    } else {
+        fwrite($fp, "array(\n");
+        for ($keys = array_keys($valueTree), $i = 0; $i < $count; $i++) {
+            writeNode($fp, $valueTree[$keys[$i]], $keys[$i], $indent + 1);
+            if ($i + 1 != $count) {
+                fwrite($fp, ",\n");
+            } else {
+                fwrite($fp, "\n");
+            }
+        }
+        fwrite($fp, str_repeat(' ', $indent) . ")");
+    }
+}
+
+
+try {
+    $request  = new HTTP_Request2(LIST_URL);
+    $response = $request->send();
+    if (200 != $response->getStatus()) {
+        throw new Exception("List download URL returned status: " .
+                            $response->getStatus() . ' ' . $response->getReasonPhrase());
+    }
+    $list     = $response->getBody();
+    if (false === strpos($list, 'The Original Code is the Public Suffix List.')) {
+        throw new Exception("List download URL does not contain expected phrase");
+    }
+    if (!($fp = @fopen(OUTPUT_FILE, 'wt'))) {
+        throw new Exception("Unable to open " . OUTPUT_FILE);
+    }
+
+} catch (Exception $e) {
+    die($e->getMessage());
+}
+
+$tldTree = array();
+$license = true;
+
+fwrite($fp, "<?php\n");
+
+foreach (array_filter(array_map('trim', explode("\n", $list))) as $line) {
+    if ('//' != substr($line, 0, 2)) {
+        buildSubdomain($tldTree, explode('.', $line));
+
+    } elseif ($license) {
+        fwrite($fp, $line . "\n");
+
+        if (0 === strpos($line, "// ***** END LICENSE BLOCK")) {
+            $license = false;
+            fwrite($fp, "\n");
+        }
+    }
+}
+
+writeNode($fp, $tldTree);
+fwrite($fp, ";\n?>");
+fclose($fp);
+?>
\ No newline at end of file
diff --git a/lib/data/HTTP_Request2/HTTP/public-suffix-list.php b/lib/data/HTTP_Request2/HTTP/public-suffix-list.php
new file mode 100644
index 0000000..eb68660
--- /dev/null
+++ b/lib/data/HTTP_Request2/HTTP/public-suffix-list.php
@@ -0,0 +1,4464 @@
+<?php
+// ***** BEGIN LICENSE BLOCK *****
+// Version: MPL 1.1/GPL 2.0/LGPL 2.1
+//
+// The contents of this file are subject to the Mozilla Public License Version
+// 1.1 (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.mozilla.org/MPL/
+//
+// Software distributed under the License is distributed on an "AS IS" basis,
+// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+// for the specific language governing rights and limitations under the
+// License.
+//
+// The Original Code is the Public Suffix List.
+//
+// The Initial Developer of the Original Code is
+// Jo Hermans <jo.hermans@gmail.com>.
+// Portions created by the Initial Developer are Copyright (C) 2007
+// the Initial Developer. All Rights Reserved.
+//
+// Contributor(s):
+//   Ruben Arakelyan <ruben@wackomenace.co.uk>
+//   Gervase Markham <gerv@gerv.net>
+//   Pamela Greene <pamg.bugs@gmail.com>
+//   David Triendl <david@triendl.name>
+//   Jothan Frakes <jothan@gmail.com>
+//   The kind representatives of many TLD registries
+//
+// Alternatively, the contents of this file may be used under the terms of
+// either the GNU General Public License Version 2 or later (the "GPL"), or
+// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+// in which case the provisions of the GPL or the LGPL are applicable instead
+// of those above. If you wish to allow use of your version of this file only
+// under the terms of either the GPL or the LGPL, and not to allow others to
+// use your version of this file under the terms of the MPL, indicate your
+// decision by deleting the provisions above and replace them with the notice
+// and other provisions required by the GPL or the LGPL. If you do not delete
+// the provisions above, a recipient may use your version of this file under
+// the terms of any one of the MPL, the GPL or the LGPL.
+//
+// ***** END LICENSE BLOCK *****
+
+return array(
+ 'ac' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'mil' => true,
+  'org' => true
+ ),
+ 'ad' => array(
+  'nom' => true
+ ),
+ 'ae' => array(
+  'co' => true,
+  'net' => true,
+  'org' => true,
+  'sch' => true,
+  'ac' => true,
+  'gov' => true,
+  'mil' => true
+ ),
+ 'aero' => array(
+  'accident-investigation' => true,
+  'accident-prevention' => true,
+  'aerobatic' => true,
+  'aeroclub' => true,
+  'aerodrome' => true,
+  'agents' => true,
+  'aircraft' => true,
+  'airline' => true,
+  'airport' => true,
+  'air-surveillance' => true,
+  'airtraffic' => true,
+  'air-traffic-control' => true,
+  'ambulance' => true,
+  'amusement' => true,
+  'association' => true,
+  'author' => true,
+  'ballooning' => true,
+  'broker' => true,
+  'caa' => true,
+  'cargo' => true,
+  'catering' => true,
+  'certification' => true,
+  'championship' => true,
+  'charter' => true,
+  'civilaviation' => true,
+  'club' => true,
+  'conference' => true,
+  'consultant' => true,
+  'consulting' => true,
+  'control' => true,
+  'council' => true,
+  'crew' => true,
+  'design' => true,
+  'dgca' => true,
+  'educator' => true,
+  'emergency' => true,
+  'engine' => true,
+  'engineer' => true,
+  'entertainment' => true,
+  'equipment' => true,
+  'exchange' => true,
+  'express' => true,
+  'federation' => true,
+  'flight' => true,
+  'freight' => true,
+  'fuel' => true,
+  'gliding' => true,
+  'government' => true,
+  'groundhandling' => true,
+  'group' => true,
+  'hanggliding' => true,
+  'homebuilt' => true,
+  'insurance' => true,
+  'journal' => true,
+  'journalist' => true,
+  'leasing' => true,
+  'logistics' => true,
+  'magazine' => true,
+  'maintenance' => true,
+  'marketplace' => true,
+  'media' => true,
+  'microlight' => true,
+  'modelling' => true,
+  'navigation' => true,
+  'parachuting' => true,
+  'paragliding' => true,
+  'passenger-association' => true,
+  'pilot' => true,
+  'press' => true,
+  'production' => true,
+  'recreation' => true,
+  'repbody' => true,
+  'res' => true,
+  'research' => true,
+  'rotorcraft' => true,
+  'safety' => true,
+  'scientist' => true,
+  'services' => true,
+  'show' => true,
+  'skydiving' => true,
+  'software' => true,
+  'student' => true,
+  'taxi' => true,
+  'trader' => true,
+  'trading' => true,
+  'trainer' => true,
+  'union' => true,
+  'workinggroup' => true,
+  'works' => true
+ ),
+ 'af' => array(
+  'gov' => true,
+  'com' => true,
+  'org' => true,
+  'net' => true,
+  'edu' => true
+ ),
+ 'ag' => array(
+  'com' => true,
+  'org' => true,
+  'net' => true,
+  'co' => true,
+  'nom' => true
+ ),
+ 'ai' => array(
+  'off' => true,
+  'com' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'al' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'am' => true,
+ 'an' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true
+ ),
+ 'ao' => array(
+  'ed' => true,
+  'gv' => true,
+  'og' => true,
+  'co' => true,
+  'pb' => true,
+  'it' => true
+ ),
+ 'aq' => true,
+ 'ar' => array(
+  '*' => true,
+  '!congresodelalengua3' => true,
+  '!educ' => true,
+  '!gobiernoelectronico' => true,
+  '!mecon' => true,
+  '!nacion' => true,
+  '!nic' => true,
+  '!promocion' => true,
+  '!retina' => true,
+  '!uba' => true
+ ),
+ 'arpa' => array(
+  'e164' => true,
+  'in-addr' => true,
+  'ip6' => true,
+  'iris' => true,
+  'uri' => true,
+  'urn' => true
+ ),
+ 'as' => array(
+  'gov' => true
+ ),
+ 'asia' => true,
+ 'at' => array(
+  'ac' => true,
+  'co' => true,
+  'gv' => true,
+  'or' => true,
+  'biz' => true,
+  'info' => true,
+  'priv' => true
+ ),
+ 'au' => array(
+  '*' => true,
+  'edu' => array(
+   'act' => true,
+   'nsw' => true,
+   'nt' => true,
+   'qld' => true,
+   'sa' => true,
+   'tas' => true,
+   'vic' => true,
+   'wa' => true
+  ),
+  'gov' => array(
+   'act' => true,
+   'nt' => true,
+   'qld' => true,
+   'sa' => true,
+   'tas' => true,
+   'vic' => true,
+   'wa' => true
+  ),
+  'act' => true,
+  'nsw' => true,
+  'nt' => true,
+  'qld' => true,
+  'sa' => true,
+  'tas' => true,
+  'vic' => true,
+  'wa' => true
+ ),
+ 'aw' => array(
+  'com' => true
+ ),
+ 'ax' => true,
+ 'az' => array(
+  'com' => true,
+  'net' => true,
+  'int' => true,
+  'gov' => true,
+  'org' => true,
+  'edu' => true,
+  'info' => true,
+  'pp' => true,
+  'mil' => true,
+  'name' => true,
+  'pro' => true,
+  'biz' => true
+ ),
+ 'ba' => array(
+  'org' => true,
+  'net' => true,
+  'edu' => true,
+  'gov' => true,
+  'mil' => true,
+  'unsa' => true,
+  'unbi' => true,
+  'co' => true,
+  'com' => true,
+  'rs' => true
+ ),
+ 'bb' => array(
+  'biz' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'info' => true,
+  'net' => true,
+  'org' => true,
+  'store' => true
+ ),
+ 'bd' => array(
+  '*' => true
+ ),
+ 'be' => array(
+  'ac' => true
+ ),
+ 'bf' => array(
+  'gov' => true
+ ),
+ 'bg' => array(
+  'a' => true,
+  'b' => true,
+  'c' => true,
+  'd' => true,
+  'e' => true,
+  'f' => true,
+  'g' => true,
+  'h' => true,
+  'i' => true,
+  'j' => true,
+  'k' => true,
+  'l' => true,
+  'm' => true,
+  'n' => true,
+  'o' => true,
+  'p' => true,
+  'q' => true,
+  'r' => true,
+  's' => true,
+  't' => true,
+  'u' => true,
+  'v' => true,
+  'w' => true,
+  'x' => true,
+  'y' => true,
+  'z' => true,
+  '0' => true,
+  '1' => true,
+  '2' => true,
+  '3' => true,
+  '4' => true,
+  '5' => true,
+  '6' => true,
+  '7' => true,
+  '8' => true,
+  '9' => true
+ ),
+ 'bh' => array(
+  'com' => true,
+  'edu' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true
+ ),
+ 'bi' => array(
+  'co' => true,
+  'com' => true,
+  'edu' => true,
+  'or' => true,
+  'org' => true
+ ),
+ 'biz' => true,
+ 'bj' => array(
+  'asso' => true,
+  'barreau' => true,
+  'gouv' => true
+ ),
+ 'bm' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'bn' => array(
+  '*' => true
+ ),
+ 'bo' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'gob' => true,
+  'int' => true,
+  'org' => true,
+  'net' => true,
+  'mil' => true,
+  'tv' => true
+ ),
+ 'br' => array(
+  'adm' => true,
+  'adv' => true,
+  'agr' => true,
+  'am' => true,
+  'arq' => true,
+  'art' => true,
+  'ato' => true,
+  'bio' => true,
+  'blog' => true,
+  'bmd' => true,
+  'can' => true,
+  'cim' => true,
+  'cng' => true,
+  'cnt' => true,
+  'com' => true,
+  'coop' => true,
+  'ecn' => true,
+  'edu' => true,
+  'eng' => true,
+  'esp' => true,
+  'etc' => true,
+  'eti' => true,
+  'far' => true,
+  'flog' => true,
+  'fm' => true,
+  'fnd' => true,
+  'fot' => true,
+  'fst' => true,
+  'g12' => true,
+  'ggf' => true,
+  'gov' => true,
+  'imb' => true,
+  'ind' => true,
+  'inf' => true,
+  'jor' => true,
+  'jus' => true,
+  'lel' => true,
+  'mat' => true,
+  'med' => true,
+  'mil' => true,
+  'mus' => true,
+  'net' => true,
+  'nom' => true,
+  'not' => true,
+  'ntr' => true,
+  'odo' => true,
+  'org' => true,
+  'ppg' => true,
+  'pro' => true,
+  'psc' => true,
+  'psi' => true,
+  'qsl' => true,
+  'rec' => true,
+  'slg' => true,
+  'srv' => true,
+  'tmp' => true,
+  'trd' => true,
+  'tur' => true,
+  'tv' => true,
+  'vet' => true,
+  'vlog' => true,
+  'wiki' => true,
+  'zlg' => true
+ ),
+ 'bs' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true
+ ),
+ 'bt' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'bw' => array(
+  'co' => true,
+  'org' => true
+ ),
+ 'by' => array(
+  'gov' => true,
+  'mil' => true,
+  'com' => true,
+  'of' => true
+ ),
+ 'bz' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true
+ ),
+ 'ca' => array(
+  'ab' => true,
+  'bc' => true,
+  'mb' => true,
+  'nb' => true,
+  'nf' => true,
+  'nl' => true,
+  'ns' => true,
+  'nt' => true,
+  'nu' => true,
+  'on' => true,
+  'pe' => true,
+  'qc' => true,
+  'sk' => true,
+  'yk' => true,
+  'gc' => true
+ ),
+ 'cat' => true,
+ 'cc' => true,
+ 'cd' => array(
+  'gov' => true
+ ),
+ 'cf' => true,
+ 'cg' => true,
+ 'ch' => true,
+ 'ci' => array(
+  'org' => true,
+  'or' => true,
+  'com' => true,
+  'co' => true,
+  'edu' => true,
+  'ed' => true,
+  'ac' => true,
+  'net' => true,
+  'go' => true,
+  'asso' => true,
+  'aéroport' => true,
+  'int' => true,
+  'presse' => true,
+  'md' => true,
+  'gouv' => true
+ ),
+ 'ck' => array(
+  '*' => true
+ ),
+ 'cl' => array(
+  'gov' => true,
+  'gob' => true
+ ),
+ 'cm' => array(
+  'gov' => true
+ ),
+ 'cn' => array(
+  'ac' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true,
+  'mil' => true,
+  '公司' => true,
+  '网络' => true,
+  '網絡' => true,
+  'ah' => true,
+  'bj' => true,
+  'cq' => true,
+  'fj' => true,
+  'gd' => true,
+  'gs' => true,
+  'gz' => true,
+  'gx' => true,
+  'ha' => true,
+  'hb' => true,
+  'he' => true,
+  'hi' => true,
+  'hl' => true,
+  'hn' => true,
+  'jl' => true,
+  'js' => true,
+  'jx' => true,
+  'ln' => true,
+  'nm' => true,
+  'nx' => true,
+  'qh' => true,
+  'sc' => true,
+  'sd' => true,
+  'sh' => true,
+  'sn' => true,
+  'sx' => true,
+  'tj' => true,
+  'xj' => true,
+  'xz' => true,
+  'yn' => true,
+  'zj' => true,
+  'hk' => true,
+  'mo' => true,
+  'tw' => true
+ ),
+ 'co' => array(
+  'arts' => true,
+  'com' => true,
+  'edu' => true,
+  'firm' => true,
+  'gov' => true,
+  'info' => true,
+  'int' => true,
+  'mil' => true,
+  'net' => true,
+  'nom' => true,
+  'org' => true,
+  'rec' => true,
+  'web' => true
+ ),
+ 'com' => array(
+  'ar' => true,
+  'br' => true,
+  'cn' => true,
+  'de' => true,
+  'eu' => true,
+  'gb' => true,
+  'hu' => true,
+  'jpn' => true,
+  'kr' => true,
+  'no' => true,
+  'qc' => true,
+  'ru' => true,
+  'sa' => true,
+  'se' => true,
+  'uk' => true,
+  'us' => true,
+  'uy' => true,
+  'za' => true,
+  'operaunite' => true,
+  'appspot' => true
+ ),
+ 'coop' => true,
+ 'cr' => array(
+  'ac' => true,
+  'co' => true,
+  'ed' => true,
+  'fi' => true,
+  'go' => true,
+  'or' => true,
+  'sa' => true
+ ),
+ 'cu' => array(
+  'com' => true,
+  'edu' => true,
+  'org' => true,
+  'net' => true,
+  'gov' => true,
+  'inf' => true
+ ),
+ 'cv' => true,
+ 'cx' => array(
+  'gov' => true
+ ),
+ 'cy' => array(
+  '*' => true
+ ),
+ 'cz' => true,
+ 'de' => true,
+ 'dj' => true,
+ 'dk' => true,
+ 'dm' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true
+ ),
+ 'do' => array(
+  '*' => true
+ ),
+ 'dz' => array(
+  'com' => true,
+  'org' => true,
+  'net' => true,
+  'gov' => true,
+  'edu' => true,
+  'asso' => true,
+  'pol' => true,
+  'art' => true
+ ),
+ 'ec' => array(
+  'com' => true,
+  'info' => true,
+  'net' => true,
+  'fin' => true,
+  'k12' => true,
+  'med' => true,
+  'pro' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true,
+  'gob' => true,
+  'mil' => true
+ ),
+ 'edu' => true,
+ 'ee' => array(
+  'edu' => true,
+  'gov' => true,
+  'riik' => true,
+  'lib' => true,
+  'med' => true,
+  'com' => true,
+  'pri' => true,
+  'aip' => true,
+  'org' => true,
+  'fie' => true
+ ),
+ 'eg' => array(
+  '*' => true
+ ),
+ 'er' => array(
+  '*' => true
+ ),
+ 'es' => array(
+  'com' => true,
+  'nom' => true,
+  'org' => true,
+  'gob' => true,
+  'edu' => true
+ ),
+ 'et' => array(
+  '*' => true
+ ),
+ 'eu' => true,
+ 'fi' => array(
+  'aland' => true,
+  'iki' => true
+ ),
+ 'fj' => array(
+  '*' => true
+ ),
+ 'fk' => array(
+  '*' => true
+ ),
+ 'fm' => true,
+ 'fo' => true,
+ 'fr' => array(
+  'com' => true,
+  'asso' => true,
+  'nom' => true,
+  'prd' => true,
+  'presse' => true,
+  'tm' => true,
+  'aeroport' => true,
+  'assedic' => true,
+  'avocat' => true,
+  'avoues' => true,
+  'cci' => true,
+  'chambagri' => true,
+  'chirurgiens-dentistes' => true,
+  'experts-comptables' => true,
+  'geometre-expert' => true,
+  'gouv' => true,
+  'greta' => true,
+  'huissier-justice' => true,
+  'medecin' => true,
+  'notaires' => true,
+  'pharmacien' => true,
+  'port' => true,
+  'veterinaire' => true
+ ),
+ 'ga' => true,
+ 'gd' => true,
+ 'ge' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'mil' => true,
+  'net' => true,
+  'pvt' => true
+ ),
+ 'gf' => true,
+ 'gg' => array(
+  'co' => true,
+  'org' => true,
+  'net' => true,
+  'sch' => true,
+  'gov' => true
+ ),
+ 'gh' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'mil' => true
+ ),
+ 'gi' => array(
+  'com' => true,
+  'ltd' => true,
+  'gov' => true,
+  'mod' => true,
+  'edu' => true,
+  'org' => true
+ ),
+ 'gl' => true,
+ 'gm' => true,
+ 'gn' => array(
+  'ac' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'net' => true
+ ),
+ 'gov' => true,
+ 'gp' => array(
+  'com' => true,
+  'net' => true,
+  'mobi' => true,
+  'edu' => true,
+  'org' => true,
+  'asso' => true
+ ),
+ 'gq' => true,
+ 'gr' => array(
+  'com' => true,
+  'edu' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true
+ ),
+ 'gs' => true,
+ 'gt' => array(
+  '*' => true
+ ),
+ 'gu' => array(
+  '*' => true
+ ),
+ 'gw' => true,
+ 'gy' => array(
+  'co' => true,
+  'com' => true,
+  'net' => true
+ ),
+ 'hk' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'idv' => true,
+  'net' => true,
+  'org' => true,
+  '公司' => true,
+  '教育' => true,
+  '敎育' => true,
+  '政府' => true,
+  '個人' => true,
+  '个人' => true,
+  '箇人' => true,
+  '網络' => true,
+  '网络' => true,
+  '组織' => true,
+  '網絡' => true,
+  '网絡' => true,
+  '组织' => true,
+  '組織' => true,
+  '組织' => true
+ ),
+ 'hm' => true,
+ 'hn' => array(
+  'com' => true,
+  'edu' => true,
+  'org' => true,
+  'net' => true,
+  'mil' => true,
+  'gob' => true
+ ),
+ 'hr' => array(
+  'iz' => true,
+  'from' => true,
+  'name' => true,
+  'com' => true
+ ),
+ 'ht' => array(
+  'com' => true,
+  'shop' => true,
+  'firm' => true,
+  'info' => true,
+  'adult' => true,
+  'net' => true,
+  'pro' => true,
+  'org' => true,
+  'med' => true,
+  'art' => true,
+  'coop' => true,
+  'pol' => true,
+  'asso' => true,
+  'edu' => true,
+  'rel' => true,
+  'gouv' => true,
+  'perso' => true
+ ),
+ 'hu' => array(
+  'co' => true,
+  'info' => true,
+  'org' => true,
+  'priv' => true,
+  'sport' => true,
+  'tm' => true,
+  '2000' => true,
+  'agrar' => true,
+  'bolt' => true,
+  'casino' => true,
+  'city' => true,
+  'erotica' => true,
+  'erotika' => true,
+  'film' => true,
+  'forum' => true,
+  'games' => true,
+  'hotel' => true,
+  'ingatlan' => true,
+  'jogasz' => true,
+  'konyvelo' => true,
+  'lakas' => true,
+  'media' => true,
+  'news' => true,
+  'reklam' => true,
+  'sex' => true,
+  'shop' => true,
+  'suli' => true,
+  'szex' => true,
+  'tozsde' => true,
+  'utazas' => true,
+  'video' => true
+ ),
+ 'id' => array(
+  'ac' => true,
+  'co' => true,
+  'go' => true,
+  'mil' => true,
+  'net' => true,
+  'or' => true,
+  'sch' => true,
+  'web' => true
+ ),
+ 'ie' => array(
+  'gov' => true
+ ),
+ 'il' => array(
+  '*' => true
+ ),
+ 'im' => array(
+  'co' => array(
+   'ltd' => true,
+   'plc' => true
+  ),
+  'net' => true,
+  'gov' => true,
+  'org' => true,
+  'nic' => true,
+  'ac' => true
+ ),
+ 'in' => array(
+  'co' => true,
+  'firm' => true,
+  'net' => true,
+  'org' => true,
+  'gen' => true,
+  'ind' => true,
+  'nic' => true,
+  'ac' => true,
+  'edu' => true,
+  'res' => true,
+  'gov' => true,
+  'mil' => true
+ ),
+ 'info' => true,
+ 'int' => array(
+  'eu' => true
+ ),
+ 'io' => array(
+  'com' => true
+ ),
+ 'iq' => array(
+  'gov' => true,
+  'edu' => true,
+  'mil' => true,
+  'com' => true,
+  'org' => true,
+  'net' => true
+ ),
+ 'ir' => array(
+  'ac' => true,
+  'co' => true,
+  'gov' => true,
+  'id' => true,
+  'net' => true,
+  'org' => true,
+  'sch' => true,
+  'ایران' => true,
+  'ايران' => true
+ ),
+ 'is' => array(
+  'net' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'int' => true
+ ),
+ 'it' => array(
+  'gov' => true,
+  'edu' => true,
+  'agrigento' => true,
+  'ag' => true,
+  'alessandria' => true,
+  'al' => true,
+  'ancona' => true,
+  'an' => true,
+  'aosta' => true,
+  'aoste' => true,
+  'ao' => true,
+  'arezzo' => true,
+  'ar' => true,
+  'ascoli-piceno' => true,
+  'ascolipiceno' => true,
+  'ap' => true,
+  'asti' => true,
+  'at' => true,
+  'avellino' => true,
+  'av' => true,
+  'bari' => true,
+  'ba' => true,
+  'andria-barletta-trani' => true,
+  'andriabarlettatrani' => true,
+  'trani-barletta-andria' => true,
+  'tranibarlettaandria' => true,
+  'barletta-trani-andria' => true,
+  'barlettatraniandria' => true,
+  'andria-trani-barletta' => true,
+  'andriatranibarletta' => true,
+  'trani-andria-barletta' => true,
+  'traniandriabarletta' => true,
+  'bt' => true,
+  'belluno' => true,
+  'bl' => true,
+  'benevento' => true,
+  'bn' => true,
+  'bergamo' => true,
+  'bg' => true,
+  'biella' => true,
+  'bi' => true,
+  'bologna' => true,
+  'bo' => true,
+  'bolzano' => true,
+  'bozen' => true,
+  'balsan' => true,
+  'alto-adige' => true,
+  'altoadige' => true,
+  'suedtirol' => true,
+  'bz' => true,
+  'brescia' => true,
+  'bs' => true,
+  'brindisi' => true,
+  'br' => true,
+  'cagliari' => true,
+  'ca' => true,
+  'caltanissetta' => true,
+  'cl' => true,
+  'campobasso' => true,
+  'cb' => true,
+  'carboniaiglesias' => true,
+  'carbonia-iglesias' => true,
+  'iglesias-carbonia' => true,
+  'iglesiascarbonia' => true,
+  'ci' => true,
+  'caserta' => true,
+  'ce' => true,
+  'catania' => true,
+  'ct' => true,
+  'catanzaro' => true,
+  'cz' => true,
+  'chieti' => true,
+  'ch' => true,
+  'como' => true,
+  'co' => true,
+  'cosenza' => true,
+  'cs' => true,
+  'cremona' => true,
+  'cr' => true,
+  'crotone' => true,
+  'kr' => true,
+  'cuneo' => true,
+  'cn' => true,
+  'dell-ogliastra' => true,
+  'dellogliastra' => true,
+  'ogliastra' => true,
+  'og' => true,
+  'enna' => true,
+  'en' => true,
+  'ferrara' => true,
+  'fe' => true,
+  'fermo' => true,
+  'fm' => true,
+  'firenze' => true,
+  'florence' => true,
+  'fi' => true,
+  'foggia' => true,
+  'fg' => true,
+  'forli-cesena' => true,
+  'forlicesena' => true,
+  'cesena-forli' => true,
+  'cesenaforli' => true,
+  'fc' => true,
+  'frosinone' => true,
+  'fr' => true,
+  'genova' => true,
+  'genoa' => true,
+  'ge' => true,
+  'gorizia' => true,
+  'go' => true,
+  'grosseto' => true,
+  'gr' => true,
+  'imperia' => true,
+  'im' => true,
+  'isernia' => true,
+  'is' => true,
+  'laquila' => true,
+  'aquila' => true,
+  'aq' => true,
+  'la-spezia' => true,
+  'laspezia' => true,
+  'sp' => true,
+  'latina' => true,
+  'lt' => true,
+  'lecce' => true,
+  'le' => true,
+  'lecco' => true,
+  'lc' => true,
+  'livorno' => true,
+  'li' => true,
+  'lodi' => true,
+  'lo' => true,
+  'lucca' => true,
+  'lu' => true,
+  'macerata' => true,
+  'mc' => true,
+  'mantova' => true,
+  'mn' => true,
+  'massa-carrara' => true,
+  'massacarrara' => true,
+  'carrara-massa' => true,
+  'carraramassa' => true,
+  'ms' => true,
+  'matera' => true,
+  'mt' => true,
+  'medio-campidano' => true,
+  'mediocampidano' => true,
+  'campidano-medio' => true,
+  'campidanomedio' => true,
+  'vs' => true,
+  'messina' => true,
+  'me' => true,
+  'milano' => true,
+  'milan' => true,
+  'mi' => true,
+  'modena' => true,
+  'mo' => true,
+  'monza' => true,
+  'monza-brianza' => true,
+  'monzabrianza' => true,
+  'monzaebrianza' => true,
+  'monzaedellabrianza' => true,
+  'monza-e-della-brianza' => true,
+  'mb' => true,
+  'napoli' => true,
+  'naples' => true,
+  'na' => true,
+  'novara' => true,
+  'no' => true,
+  'nuoro' => true,
+  'nu' => true,
+  'oristano' => true,
+  'or' => true,
+  'padova' => true,
+  'padua' => true,
+  'pd' => true,
+  'palermo' => true,
+  'pa' => true,
+  'parma' => true,
+  'pr' => true,
+  'pavia' => true,
+  'pv' => true,
+  'perugia' => true,
+  'pg' => true,
+  'pescara' => true,
+  'pe' => true,
+  'pesaro-urbino' => true,
+  'pesarourbino' => true,
+  'urbino-pesaro' => true,
+  'urbinopesaro' => true,
+  'pu' => true,
+  'piacenza' => true,
+  'pc' => true,
+  'pisa' => true,
+  'pi' => true,
+  'pistoia' => true,
+  'pt' => true,
+  'pordenone' => true,
+  'pn' => true,
+  'potenza' => true,
+  'pz' => true,
+  'prato' => true,
+  'po' => true,
+  'ragusa' => true,
+  'rg' => true,
+  'ravenna' => true,
+  'ra' => true,
+  'reggio-calabria' => true,
+  'reggiocalabria' => true,
+  'rc' => true,
+  'reggio-emilia' => true,
+  'reggioemilia' => true,
+  're' => true,
+  'rieti' => true,
+  'ri' => true,
+  'rimini' => true,
+  'rn' => true,
+  'roma' => true,
+  'rome' => true,
+  'rm' => true,
+  'rovigo' => true,
+  'ro' => true,
+  'salerno' => true,
+  'sa' => true,
+  'sassari' => true,
+  'ss' => true,
+  'savona' => true,
+  'sv' => true,
+  'siena' => true,
+  'si' => true,
+  'siracusa' => true,
+  'sr' => true,
+  'sondrio' => true,
+  'so' => true,
+  'taranto' => true,
+  'ta' => true,
+  'tempio-olbia' => true,
+  'tempioolbia' => true,
+  'olbia-tempio' => true,
+  'olbiatempio' => true,
+  'ot' => true,
+  'teramo' => true,
+  'te' => true,
+  'terni' => true,
+  'tr' => true,
+  'torino' => true,
+  'turin' => true,
+  'to' => true,
+  'trapani' => true,
+  'tp' => true,
+  'trento' => true,
+  'trentino' => true,
+  'tn' => true,
+  'treviso' => true,
+  'tv' => true,
+  'trieste' => true,
+  'ts' => true,
+  'udine' => true,
+  'ud' => true,
+  'varese' => true,
+  'va' => true,
+  'venezia' => true,
+  'venice' => true,
+  've' => true,
+  'verbania' => true,
+  'vb' => true,
+  'vercelli' => true,
+  'vc' => true,
+  'verona' => true,
+  'vr' => true,
+  'vibo-valentia' => true,
+  'vibovalentia' => true,
+  'vv' => true,
+  'vicenza' => true,
+  'vi' => true,
+  'viterbo' => true,
+  'vt' => true
+ ),
+ 'je' => array(
+  'co' => true,
+  'org' => true,
+  'net' => true,
+  'sch' => true,
+  'gov' => true
+ ),
+ 'jm' => array(
+  '*' => true
+ ),
+ 'jo' => array(
+  'com' => true,
+  'org' => true,
+  'net' => true,
+  'edu' => true,
+  'sch' => true,
+  'gov' => true,
+  'mil' => true,
+  'name' => true
+ ),
+ 'jobs' => true,
+ 'jp' => array(
+  'ac' => true,
+  'ad' => true,
+  'co' => true,
+  'ed' => true,
+  'go' => true,
+  'gr' => true,
+  'lg' => true,
+  'ne' => true,
+  'or' => true,
+  'aichi' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'akita' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'aomori' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'chiba' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'ehime' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'fukui' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'fukuoka' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'fukushima' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'gifu' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'gunma' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'hiroshima' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'hokkaido' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'hyogo' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'ibaraki' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'ishikawa' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'iwate' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'kagawa' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'kagoshima' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'kanagawa' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'kawasaki' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'kitakyushu' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'kobe' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'kochi' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'kumamoto' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'kyoto' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'mie' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'miyagi' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'miyazaki' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'nagano' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'nagasaki' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'nagoya' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'nara' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'niigata' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'oita' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'okayama' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'okinawa' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'osaka' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'saga' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'saitama' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'sapporo' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'sendai' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'shiga' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'shimane' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'shizuoka' => array(
+   '*' => true,
+   '!pref' => true,
+   '!city' => true
+  ),
+  'tochigi' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'tokushima' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'tokyo' => array(
+   '*' => true,
+   '!metro' => true
+  ),
+  'tottori' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'toyama' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'wakayama' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'yamagata' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'yamaguchi' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'yamanashi' => array(
+   '*' => true,
+   '!pref' => true
+  ),
+  'yokohama' => array(
+   '*' => true,
+   '!city' => true
+  )
+ ),
+ 'ke' => array(
+  '*' => true
+ ),
+ 'kg' => array(
+  'org' => true,
+  'net' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'mil' => true
+ ),
+ 'kh' => array(
+  '*' => true
+ ),
+ 'ki' => array(
+  'edu' => true,
+  'biz' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'info' => true,
+  'com' => true
+ ),
+ 'km' => array(
+  'org' => true,
+  'nom' => true,
+  'gov' => true,
+  'prd' => true,
+  'tm' => true,
+  'edu' => true,
+  'mil' => true,
+  'ass' => true,
+  'com' => true,
+  'coop' => true,
+  'asso' => true,
+  'presse' => true,
+  'medecin' => true,
+  'notaires' => true,
+  'pharmaciens' => true,
+  'veterinaire' => true,
+  'gouv' => true
+ ),
+ 'kn' => array(
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true
+ ),
+ 'kp' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'rep' => true,
+  'tra' => true
+ ),
+ 'kr' => array(
+  'ac' => true,
+  'co' => true,
+  'es' => true,
+  'go' => true,
+  'hs' => true,
+  'kg' => true,
+  'mil' => true,
+  'ms' => true,
+  'ne' => true,
+  'or' => true,
+  'pe' => true,
+  're' => true,
+  'sc' => true,
+  'busan' => true,
+  'chungbuk' => true,
+  'chungnam' => true,
+  'daegu' => true,
+  'daejeon' => true,
+  'gangwon' => true,
+  'gwangju' => true,
+  'gyeongbuk' => true,
+  'gyeonggi' => true,
+  'gyeongnam' => true,
+  'incheon' => true,
+  'jeju' => true,
+  'jeonbuk' => true,
+  'jeonnam' => true,
+  'seoul' => true,
+  'ulsan' => true
+ ),
+ 'kw' => array(
+  '*' => true
+ ),
+ 'ky' => array(
+  'edu' => true,
+  'gov' => true,
+  'com' => true,
+  'org' => true,
+  'net' => true
+ ),
+ 'kz' => array(
+  'org' => true,
+  'edu' => true,
+  'net' => true,
+  'gov' => true,
+  'mil' => true,
+  'com' => true
+ ),
+ 'la' => array(
+  'int' => true,
+  'net' => true,
+  'info' => true,
+  'edu' => true,
+  'gov' => true,
+  'per' => true,
+  'com' => true,
+  'org' => true,
+  'c' => true
+ ),
+ 'lb' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'lc' => array(
+  'com' => true,
+  'net' => true,
+  'co' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true
+ ),
+ 'li' => true,
+ 'lk' => array(
+  'gov' => true,
+  'sch' => true,
+  'net' => true,
+  'int' => true,
+  'com' => true,
+  'org' => true,
+  'edu' => true,
+  'ngo' => true,
+  'soc' => true,
+  'web' => true,
+  'ltd' => true,
+  'assn' => true,
+  'grp' => true,
+  'hotel' => true
+ ),
+ 'local' => true,
+ 'lr' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'net' => true
+ ),
+ 'ls' => array(
+  'co' => true,
+  'org' => true
+ ),
+ 'lt' => array(
+  'gov' => true
+ ),
+ 'lu' => true,
+ 'lv' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true,
+  'mil' => true,
+  'id' => true,
+  'net' => true,
+  'asn' => true,
+  'conf' => true
+ ),
+ 'ly' => array(
+  'com' => true,
+  'net' => true,
+  'gov' => true,
+  'plc' => true,
+  'edu' => true,
+  'sch' => true,
+  'med' => true,
+  'org' => true,
+  'id' => true
+ ),
+ 'ma' => array(
+  'co' => true,
+  'net' => true,
+  'gov' => true,
+  'org' => true,
+  'ac' => true,
+  'press' => true
+ ),
+ 'mc' => array(
+  'tm' => true,
+  'asso' => true
+ ),
+ 'md' => true,
+ 'me' => array(
+  'co' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'ac' => true,
+  'gov' => true,
+  'its' => true,
+  'priv' => true
+ ),
+ 'mg' => array(
+  'org' => true,
+  'nom' => true,
+  'gov' => true,
+  'prd' => true,
+  'tm' => true,
+  'edu' => true,
+  'mil' => true,
+  'com' => true
+ ),
+ 'mh' => true,
+ 'mil' => true,
+ 'mk' => array(
+  'com' => true,
+  'org' => true,
+  'net' => true,
+  'edu' => true,
+  'gov' => true,
+  'inf' => true,
+  'name' => true
+ ),
+ 'ml' => array(
+  'com' => true,
+  'edu' => true,
+  'gouv' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true,
+  'presse' => true
+ ),
+ 'mm' => array(
+  '*' => true
+ ),
+ 'mn' => array(
+  'gov' => true,
+  'edu' => true,
+  'org' => true
+ ),
+ 'mo' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true
+ ),
+ 'mobi' => true,
+ 'mp' => true,
+ 'mq' => true,
+ 'mr' => array(
+  'gov' => true
+ ),
+ 'ms' => true,
+ 'mt' => array(
+  '*' => true
+ ),
+ 'mu' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'ac' => true,
+  'co' => true,
+  'or' => true
+ ),
+ 'museum' => array(
+  'academy' => true,
+  'agriculture' => true,
+  'air' => true,
+  'airguard' => true,
+  'alabama' => true,
+  'alaska' => true,
+  'amber' => true,
+  'ambulance' => true,
+  'american' => true,
+  'americana' => true,
+  'americanantiques' => true,
+  'americanart' => true,
+  'amsterdam' => true,
+  'and' => true,
+  'annefrank' => true,
+  'anthro' => true,
+  'anthropology' => true,
+  'antiques' => true,
+  'aquarium' => true,
+  'arboretum' => true,
+  'archaeological' => true,
+  'archaeology' => true,
+  'architecture' => true,
+  'art' => true,
+  'artanddesign' => true,
+  'artcenter' => true,
+  'artdeco' => true,
+  'arteducation' => true,
+  'artgallery' => true,
+  'arts' => true,
+  'artsandcrafts' => true,
+  'asmatart' => true,
+  'assassination' => true,
+  'assisi' => true,
+  'association' => true,
+  'astronomy' => true,
+  'atlanta' => true,
+  'austin' => true,
+  'australia' => true,
+  'automotive' => true,
+  'aviation' => true,
+  'axis' => true,
+  'badajoz' => true,
+  'baghdad' => true,
+  'bahn' => true,
+  'bale' => true,
+  'baltimore' => true,
+  'barcelona' => true,
+  'baseball' => true,
+  'basel' => true,
+  'baths' => true,
+  'bauern' => true,
+  'beauxarts' => true,
+  'beeldengeluid' => true,
+  'bellevue' => true,
+  'bergbau' => true,
+  'berkeley' => true,
+  'berlin' => true,
+  'bern' => true,
+  'bible' => true,
+  'bilbao' => true,
+  'bill' => true,
+  'birdart' => true,
+  'birthplace' => true,
+  'bonn' => true,
+  'boston' => true,
+  'botanical' => true,
+  'botanicalgarden' => true,
+  'botanicgarden' => true,
+  'botany' => true,
+  'brandywinevalley' => true,
+  'brasil' => true,
+  'bristol' => true,
+  'british' => true,
+  'britishcolumbia' => true,
+  'broadcast' => true,
+  'brunel' => true,
+  'brussel' => true,
+  'brussels' => true,
+  'bruxelles' => true,
+  'building' => true,
+  'burghof' => true,
+  'bus' => true,
+  'bushey' => true,
+  'cadaques' => true,
+  'california' => true,
+  'cambridge' => true,
+  'can' => true,
+  'canada' => true,
+  'capebreton' => true,
+  'carrier' => true,
+  'cartoonart' => true,
+  'casadelamoneda' => true,
+  'castle' => true,
+  'castres' => true,
+  'celtic' => true,
+  'center' => true,
+  'chattanooga' => true,
+  'cheltenham' => true,
+  'chesapeakebay' => true,
+  'chicago' => true,
+  'children' => true,
+  'childrens' => true,
+  'childrensgarden' => true,
+  'chiropractic' => true,
+  'chocolate' => true,
+  'christiansburg' => true,
+  'cincinnati' => true,
+  'cinema' => true,
+  'circus' => true,
+  'civilisation' => true,
+  'civilization' => true,
+  'civilwar' => true,
+  'clinton' => true,
+  'clock' => true,
+  'coal' => true,
+  'coastaldefence' => true,
+  'cody' => true,
+  'coldwar' => true,
+  'collection' => true,
+  'colonialwilliamsburg' => true,
+  'coloradoplateau' => true,
+  'columbia' => true,
+  'columbus' => true,
+  'communication' => true,
+  'communications' => true,
+  'community' => true,
+  'computer' => true,
+  'computerhistory' => true,
+  'comunicações' => true,
+  'contemporary' => true,
+  'contemporaryart' => true,
+  'convent' => true,
+  'copenhagen' => true,
+  'corporation' => true,
+  'correios-e-telecomunicações' => true,
+  'corvette' => true,
+  'costume' => true,
+  'countryestate' => true,
+  'county' => true,
+  'crafts' => true,
+  'cranbrook' => true,
+  'creation' => true,
+  'cultural' => true,
+  'culturalcenter' => true,
+  'culture' => true,
+  'cyber' => true,
+  'cymru' => true,
+  'dali' => true,
+  'dallas' => true,
+  'database' => true,
+  'ddr' => true,
+  'decorativearts' => true,
+  'delaware' => true,
+  'delmenhorst' => true,
+  'denmark' => true,
+  'depot' => true,
+  'design' => true,
+  'detroit' => true,
+  'dinosaur' => true,
+  'discovery' => true,
+  'dolls' => true,
+  'donostia' => true,
+  'durham' => true,
+  'eastafrica' => true,
+  'eastcoast' => true,
+  'education' => true,
+  'educational' => true,
+  'egyptian' => true,
+  'eisenbahn' => true,
+  'elburg' => true,
+  'elvendrell' => true,
+  'embroidery' => true,
+  'encyclopedic' => true,
+  'england' => true,
+  'entomology' => true,
+  'environment' => true,
+  'environmentalconservation' => true,
+  'epilepsy' => true,
+  'essex' => true,
+  'estate' => true,
+  'ethnology' => true,
+  'exeter' => true,
+  'exhibition' => true,
+  'family' => true,
+  'farm' => true,
+  'farmequipment' => true,
+  'farmers' => true,
+  'farmstead' => true,
+  'field' => true,
+  'figueres' => true,
+  'filatelia' => true,
+  'film' => true,
+  'fineart' => true,
+  'finearts' => true,
+  'finland' => true,
+  'flanders' => true,
+  'florida' => true,
+  'force' => true,
+  'fortmissoula' => true,
+  'fortworth' => true,
+  'foundation' => true,
+  'francaise' => true,
+  'frankfurt' => true,
+  'franziskaner' => true,
+  'freemasonry' => true,
+  'freiburg' => true,
+  'fribourg' => true,
+  'frog' => true,
+  'fundacio' => true,
+  'furniture' => true,
+  'gallery' => true,
+  'garden' => true,
+  'gateway' => true,
+  'geelvinck' => true,
+  'gemological' => true,
+  'geology' => true,
+  'georgia' => true,
+  'giessen' => true,
+  'glas' => true,
+  'glass' => true,
+  'gorge' => true,
+  'grandrapids' => true,
+  'graz' => true,
+  'guernsey' => true,
+  'halloffame' => true,
+  'hamburg' => true,
+  'handson' => true,
+  'harvestcelebration' => true,
+  'hawaii' => true,
+  'health' => true,
+  'heimatunduhren' => true,
+  'hellas' => true,
+  'helsinki' => true,
+  'hembygdsforbund' => true,
+  'heritage' => true,
+  'histoire' => true,
+  'historical' => true,
+  'historicalsociety' => true,
+  'historichouses' => true,
+  'historisch' => true,
+  'historisches' => true,
+  'history' => true,
+  'historyofscience' => true,
+  'horology' => true,
+  'house' => true,
+  'humanities' => true,
+  'illustration' => true,
+  'imageandsound' => true,
+  'indian' => true,
+  'indiana' => true,
+  'indianapolis' => true,
+  'indianmarket' => true,
+  'intelligence' => true,
+  'interactive' => true,
+  'iraq' => true,
+  'iron' => true,
+  'isleofman' => true,
+  'jamison' => true,
+  'jefferson' => true,
+  'jerusalem' => true,
+  'jewelry' => true,
+  'jewish' => true,
+  'jewishart' => true,
+  'jfk' => true,
+  'journalism' => true,
+  'judaica' => true,
+  'judygarland' => true,
+  'juedisches' => true,
+  'juif' => true,
+  'karate' => true,
+  'karikatur' => true,
+  'kids' => true,
+  'koebenhavn' => true,
+  'koeln' => true,
+  'kunst' => true,
+  'kunstsammlung' => true,
+  'kunstunddesign' => true,
+  'labor' => true,
+  'labour' => true,
+  'lajolla' => true,
+  'lancashire' => true,
+  'landes' => true,
+  'lans' => true,
+  'läns' => true,
+  'larsson' => true,
+  'lewismiller' => true,
+  'lincoln' => true,
+  'linz' => true,
+  'living' => true,
+  'livinghistory' => true,
+  'localhistory' => true,
+  'london' => true,
+  'losangeles' => true,
+  'louvre' => true,
+  'loyalist' => true,
+  'lucerne' => true,
+  'luxembourg' => true,
+  'luzern' => true,
+  'mad' => true,
+  'madrid' => true,
+  'mallorca' => true,
+  'manchester' => true,
+  'mansion' => true,
+  'mansions' => true,
+  'manx' => true,
+  'marburg' => true,
+  'maritime' => true,
+  'maritimo' => true,
+  'maryland' => true,
+  'marylhurst' => true,
+  'media' => true,
+  'medical' => true,
+  'medizinhistorisches' => true,
+  'meeres' => true,
+  'memorial' => true,
+  'mesaverde' => true,
+  'michigan' => true,
+  'midatlantic' => true,
+  'military' => true,
+  'mill' => true,
+  'miners' => true,
+  'mining' => true,
+  'minnesota' => true,
+  'missile' => true,
+  'missoula' => true,
+  'modern' => true,
+  'moma' => true,
+  'money' => true,
+  'monmouth' => true,
+  'monticello' => true,
+  'montreal' => true,
+  'moscow' => true,
+  'motorcycle' => true,
+  'muenchen' => true,
+  'muenster' => true,
+  'mulhouse' => true,
+  'muncie' => true,
+  'museet' => true,
+  'museumcenter' => true,
+  'museumvereniging' => true,
+  'music' => true,
+  'national' => true,
+  'nationalfirearms' => true,
+  'nationalheritage' => true,
+  'nativeamerican' => true,
+  'naturalhistory' => true,
+  'naturalhistorymuseum' => true,
+  'naturalsciences' => true,
+  'nature' => true,
+  'naturhistorisches' => true,
+  'natuurwetenschappen' => true,
+  'naumburg' => true,
+  'naval' => true,
+  'nebraska' => true,
+  'neues' => true,
+  'newhampshire' => true,
+  'newjersey' => true,
+  'newmexico' => true,
+  'newport' => true,
+  'newspaper' => true,
+  'newyork' => true,
+  'niepce' => true,
+  'norfolk' => true,
+  'north' => true,
+  'nrw' => true,
+  'nuernberg' => true,
+  'nuremberg' => true,
+  'nyc' => true,
+  'nyny' => true,
+  'oceanographic' => true,
+  'oceanographique' => true,
+  'omaha' => true,
+  'online' => true,
+  'ontario' => true,
+  'openair' => true,
+  'oregon' => true,
+  'oregontrail' => true,
+  'otago' => true,
+  'oxford' => true,
+  'pacific' => true,
+  'paderborn' => true,
+  'palace' => true,
+  'paleo' => true,
+  'palmsprings' => true,
+  'panama' => true,
+  'paris' => true,
+  'pasadena' => true,
+  'pharmacy' => true,
+  'philadelphia' => true,
+  'philadelphiaarea' => true,
+  'philately' => true,
+  'phoenix' => true,
+  'photography' => true,
+  'pilots' => true,
+  'pittsburgh' => true,
+  'planetarium' => true,
+  'plantation' => true,
+  'plants' => true,
+  'plaza' => true,
+  'portal' => true,
+  'portland' => true,
+  'portlligat' => true,
+  'posts-and-telecommunications' => true,
+  'preservation' => true,
+  'presidio' => true,
+  'press' => true,
+  'project' => true,
+  'public' => true,
+  'pubol' => true,
+  'quebec' => true,
+  'railroad' => true,
+  'railway' => true,
+  'research' => true,
+  'resistance' => true,
+  'riodejaneiro' => true,
+  'rochester' => true,
+  'rockart' => true,
+  'roma' => true,
+  'russia' => true,
+  'saintlouis' => true,
+  'salem' => true,
+  'salvadordali' => true,
+  'salzburg' => true,
+  'sandiego' => true,
+  'sanfrancisco' => true,
+  'santabarbara' => true,
+  'santacruz' => true,
+  'santafe' => true,
+  'saskatchewan' => true,
+  'satx' => true,
+  'savannahga' => true,
+  'schlesisches' => true,
+  'schoenbrunn' => true,
+  'schokoladen' => true,
+  'school' => true,
+  'schweiz' => true,
+  'science' => true,
+  'scienceandhistory' => true,
+  'scienceandindustry' => true,
+  'sciencecenter' => true,
+  'sciencecenters' => true,
+  'science-fiction' => true,
+  'sciencehistory' => true,
+  'sciences' => true,
+  'sciencesnaturelles' => true,
+  'scotland' => true,
+  'seaport' => true,
+  'settlement' => true,
+  'settlers' => true,
+  'shell' => true,
+  'sherbrooke' => true,
+  'sibenik' => true,
+  'silk' => true,
+  'ski' => true,
+  'skole' => true,
+  'society' => true,
+  'sologne' => true,
+  'soundandvision' => true,
+  'southcarolina' => true,
+  'southwest' => true,
+  'space' => true,
+  'spy' => true,
+  'square' => true,
+  'stadt' => true,
+  'stalbans' => true,
+  'starnberg' => true,
+  'state' => true,
+  'stateofdelaware' => true,
+  'station' => true,
+  'steam' => true,
+  'steiermark' => true,
+  'stjohn' => true,
+  'stockholm' => true,
+  'stpetersburg' => true,
+  'stuttgart' => true,
+  'suisse' => true,
+  'surgeonshall' => true,
+  'surrey' => true,
+  'svizzera' => true,
+  'sweden' => true,
+  'sydney' => true,
+  'tank' => true,
+  'tcm' => true,
+  'technology' => true,
+  'telekommunikation' => true,
+  'television' => true,
+  'texas' => true,
+  'textile' => true,
+  'theater' => true,
+  'time' => true,
+  'timekeeping' => true,
+  'topology' => true,
+  'torino' => true,
+  'touch' => true,
+  'town' => true,
+  'transport' => true,
+  'tree' => true,
+  'trolley' => true,
+  'trust' => true,
+  'trustee' => true,
+  'uhren' => true,
+  'ulm' => true,
+  'undersea' => true,
+  'university' => true,
+  'usa' => true,
+  'usantiques' => true,
+  'usarts' => true,
+  'uscountryestate' => true,
+  'usculture' => true,
+  'usdecorativearts' => true,
+  'usgarden' => true,
+  'ushistory' => true,
+  'ushuaia' => true,
+  'uslivinghistory' => true,
+  'utah' => true,
+  'uvic' => true,
+  'valley' => true,
+  'vantaa' => true,
+  'versailles' => true,
+  'viking' => true,
+  'village' => true,
+  'virginia' => true,
+  'virtual' => true,
+  'virtuel' => true,
+  'vlaanderen' => true,
+  'volkenkunde' => true,
+  'wales' => true,
+  'wallonie' => true,
+  'war' => true,
+  'washingtondc' => true,
+  'watchandclock' => true,
+  'watch-and-clock' => true,
+  'western' => true,
+  'westfalen' => true,
+  'whaling' => true,
+  'wildlife' => true,
+  'williamsburg' => true,
+  'windmill' => true,
+  'workshop' => true,
+  'york' => true,
+  'yorkshire' => true,
+  'yosemite' => true,
+  'youth' => true,
+  'zoological' => true,
+  'zoology' => true,
+  'ירושלים' => true,
+  'иком' => true
+ ),
+ 'mv' => array(
+  'aero' => true,
+  'biz' => true,
+  'com' => true,
+  'coop' => true,
+  'edu' => true,
+  'gov' => true,
+  'info' => true,
+  'int' => true,
+  'mil' => true,
+  'museum' => true,
+  'name' => true,
+  'net' => true,
+  'org' => true,
+  'pro' => true
+ ),
+ 'mw' => array(
+  'ac' => true,
+  'biz' => true,
+  'co' => true,
+  'com' => true,
+  'coop' => true,
+  'edu' => true,
+  'gov' => true,
+  'int' => true,
+  'museum' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'mx' => array(
+  'com' => true,
+  'org' => true,
+  'gob' => true,
+  'edu' => true,
+  'net' => true
+ ),
+ 'my' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'edu' => true,
+  'mil' => true,
+  'name' => true
+ ),
+ 'mz' => array(
+  '*' => true
+ ),
+ 'na' => array(
+  'info' => true,
+  'pro' => true,
+  'name' => true,
+  'school' => true,
+  'or' => true,
+  'dr' => true,
+  'us' => true,
+  'mx' => true,
+  'ca' => true,
+  'in' => true,
+  'cc' => true,
+  'tv' => true,
+  'ws' => true,
+  'mobi' => true,
+  'co' => true,
+  'com' => true,
+  'org' => true
+ ),
+ 'name' => true,
+ 'nc' => array(
+  'asso' => true
+ ),
+ 'ne' => true,
+ 'net' => array(
+  'gb' => true,
+  'se' => true,
+  'uk' => true,
+  'za' => true
+ ),
+ 'nf' => array(
+  'com' => true,
+  'net' => true,
+  'per' => true,
+  'rec' => true,
+  'web' => true,
+  'arts' => true,
+  'firm' => true,
+  'info' => true,
+  'other' => true,
+  'store' => true
+ ),
+ 'ng' => array(
+  'ac' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'ni' => array(
+  '*' => true
+ ),
+ 'nl' => array(
+  'bv' => true
+ ),
+ 'no' => array(
+  'fhs' => true,
+  'vgs' => true,
+  'fylkesbibl' => true,
+  'folkebibl' => true,
+  'museum' => true,
+  'idrett' => true,
+  'priv' => true,
+  'mil' => true,
+  'stat' => true,
+  'dep' => true,
+  'kommune' => true,
+  'herad' => true,
+  'aa' => array(
+   'gs' => true
+  ),
+  'ah' => array(
+   'gs' => true
+  ),
+  'bu' => array(
+   'gs' => true
+  ),
+  'fm' => array(
+   'gs' => true
+  ),
+  'hl' => array(
+   'gs' => true
+  ),
+  'hm' => array(
+   'gs' => true
+  ),
+  'jan-mayen' => array(
+   'gs' => true
+  ),
+  'mr' => array(
+   'gs' => true
+  ),
+  'nl' => array(
+   'gs' => true
+  ),
+  'nt' => array(
+   'gs' => true
+  ),
+  'of' => array(
+   'gs' => true
+  ),
+  'ol' => array(
+   'gs' => true
+  ),
+  'oslo' => array(
+   'gs' => true
+  ),
+  'rl' => array(
+   'gs' => true
+  ),
+  'sf' => array(
+   'gs' => true
+  ),
+  'st' => array(
+   'gs' => true
+  ),
+  'svalbard' => array(
+   'gs' => true
+  ),
+  'tm' => array(
+   'gs' => true
+  ),
+  'tr' => array(
+   'gs' => true
+  ),
+  'va' => array(
+   'gs' => true
+  ),
+  'vf' => array(
+   'gs' => true
+  ),
+  'akrehamn' => true,
+  'åkrehamn' => true,
+  'algard' => true,
+  'ålgård' => true,
+  'arna' => true,
+  'brumunddal' => true,
+  'bryne' => true,
+  'bronnoysund' => true,
+  'brønnøysund' => true,
+  'drobak' => true,
+  'drøbak' => true,
+  'egersund' => true,
+  'fetsund' => true,
+  'floro' => true,
+  'florø' => true,
+  'fredrikstad' => true,
+  'hokksund' => true,
+  'honefoss' => true,
+  'hønefoss' => true,
+  'jessheim' => true,
+  'jorpeland' => true,
+  'jørpeland' => true,
+  'kirkenes' => true,
+  'kopervik' => true,
+  'krokstadelva' => true,
+  'langevag' => true,
+  'langevåg' => true,
+  'leirvik' => true,
+  'mjondalen' => true,
+  'mjøndalen' => true,
+  'mo-i-rana' => true,
+  'mosjoen' => true,
+  'mosjøen' => true,
+  'nesoddtangen' => true,
+  'orkanger' => true,
+  'osoyro' => true,
+  'osøyro' => true,
+  'raholt' => true,
+  'råholt' => true,
+  'sandnessjoen' => true,
+  'sandnessjøen' => true,
+  'skedsmokorset' => true,
+  'slattum' => true,
+  'spjelkavik' => true,
+  'stathelle' => true,
+  'stavern' => true,
+  'stjordalshalsen' => true,
+  'stjørdalshalsen' => true,
+  'tananger' => true,
+  'tranby' => true,
+  'vossevangen' => true,
+  'afjord' => true,
+  'åfjord' => true,
+  'agdenes' => true,
+  'al' => true,
+  'ål' => true,
+  'alesund' => true,
+  'ålesund' => true,
+  'alstahaug' => true,
+  'alta' => true,
+  'áltá' => true,
+  'alaheadju' => true,
+  'álaheadju' => true,
+  'alvdal' => true,
+  'amli' => true,
+  'åmli' => true,
+  'amot' => true,
+  'åmot' => true,
+  'andebu' => true,
+  'andoy' => true,
+  'andøy' => true,
+  'andasuolo' => true,
+  'ardal' => true,
+  'årdal' => true,
+  'aremark' => true,
+  'arendal' => true,
+  'ås' => true,
+  'aseral' => true,
+  'åseral' => true,
+  'asker' => true,
+  'askim' => true,
+  'askvoll' => true,
+  'askoy' => true,
+  'askøy' => true,
+  'asnes' => true,
+  'åsnes' => true,
+  'audnedaln' => true,
+  'aukra' => true,
+  'aure' => true,
+  'aurland' => true,
+  'aurskog-holand' => true,
+  'aurskog-høland' => true,
+  'austevoll' => true,
+  'austrheim' => true,
+  'averoy' => true,
+  'averøy' => true,
+  'balestrand' => true,
+  'ballangen' => true,
+  'balat' => true,
+  'bálát' => true,
+  'balsfjord' => true,
+  'bahccavuotna' => true,
+  'báhccavuotna' => true,
+  'bamble' => true,
+  'bardu' => true,
+  'beardu' => true,
+  'beiarn' => true,
+  'bajddar' => true,
+  'bájddar' => true,
+  'baidar' => true,
+  'báidár' => true,
+  'berg' => true,
+  'bergen' => true,
+  'berlevag' => true,
+  'berlevåg' => true,
+  'bearalvahki' => true,
+  'bearalváhki' => true,
+  'bindal' => true,
+  'birkenes' => true,
+  'bjarkoy' => true,
+  'bjarkøy' => true,
+  'bjerkreim' => true,
+  'bjugn' => true,
+  'bodo' => true,
+  'bodø' => true,
+  'badaddja' => true,
+  'bådåddjå' => true,
+  'budejju' => true,
+  'bokn' => true,
+  'bremanger' => true,
+  'bronnoy' => true,
+  'brønnøy' => true,
+  'bygland' => true,
+  'bykle' => true,
+  'barum' => true,
+  'bærum' => true,
+  'telemark' => array(
+   'bo' => true,
+   'bø' => true
+  ),
+  'nordland' => array(
+   'bo' => true,
+   'bø' => true,
+   'heroy' => true,
+   'herøy' => true
+  ),
+  'bievat' => true,
+  'bievát' => true,
+  'bomlo' => true,
+  'bømlo' => true,
+  'batsfjord' => true,
+  'båtsfjord' => true,
+  'bahcavuotna' => true,
+  'báhcavuotna' => true,
+  'dovre' => true,
+  'drammen' => true,
+  'drangedal' => true,
+  'dyroy' => true,
+  'dyrøy' => true,
+  'donna' => true,
+  'dønna' => true,
+  'eid' => true,
+  'eidfjord' => true,
+  'eidsberg' => true,
+  'eidskog' => true,
+  'eidsvoll' => true,
+  'eigersund' => true,
+  'elverum' => true,
+  'enebakk' => true,
+  'engerdal' => true,
+  'etne' => true,
+  'etnedal' => true,
+  'evenes' => true,
+  'evenassi' => true,
+  'evenášši' => true,
+  'evje-og-hornnes' => true,
+  'farsund' => true,
+  'fauske' => true,
+  'fuossko' => true,
+  'fuoisku' => true,
+  'fedje' => true,
+  'fet' => true,
+  'finnoy' => true,
+  'finnøy' => true,
+  'fitjar' => true,
+  'fjaler' => true,
+  'fjell' => true,
+  'flakstad' => true,
+  'flatanger' => true,
+  'flekkefjord' => true,
+  'flesberg' => true,
+  'flora' => true,
+  'fla' => true,
+  'flå' => true,
+  'folldal' => true,
+  'forsand' => true,
+  'fosnes' => true,
+  'frei' => true,
+  'frogn' => true,
+  'froland' => true,
+  'frosta' => true,
+  'frana' => true,
+  'fræna' => true,
+  'froya' => true,
+  'frøya' => true,
+  'fusa' => true,
+  'fyresdal' => true,
+  'forde' => true,
+  'førde' => true,
+  'gamvik' => true,
+  'gangaviika' => true,
+  'gáŋgaviika' => true,
+  'gaular' => true,
+  'gausdal' => true,
+  'gildeskal' => true,
+  'gildeskål' => true,
+  'giske' => true,
+  'gjemnes' => true,
+  'gjerdrum' => true,
+  'gjerstad' => true,
+  'gjesdal' => true,
+  'gjovik' => true,
+  'gjøvik' => true,
+  'gloppen' => true,
+  'gol' => true,
+  'gran' => true,
+  'grane' => true,
+  'granvin' => true,
+  'gratangen' => true,
+  'grimstad' => true,
+  'grong' => true,
+  'kraanghke' => true,
+  'kråanghke' => true,
+  'grue' => true,
+  'gulen' => true,
+  'hadsel' => true,
+  'halden' => true,
+  'halsa' => true,
+  'hamar' => true,
+  'hamaroy' => true,
+  'habmer' => true,
+  'hábmer' => true,
+  'hapmir' => true,
+  'hápmir' => true,
+  'hammerfest' => true,
+  'hammarfeasta' => true,
+  'hámmárfeasta' => true,
+  'haram' => true,
+  'hareid' => true,
+  'harstad' => true,
+  'hasvik' => true,
+  'aknoluokta' => true,
+  'ákŋoluokta' => true,
+  'hattfjelldal' => true,
+  'aarborte' => true,
+  'haugesund' => true,
+  'hemne' => true,
+  'hemnes' => true,
+  'hemsedal' => true,
+  'more-og-romsdal' => array(
+   'heroy' => true,
+   'sande' => true
+  ),
+  'møre-og-romsdal' => array(
+   'herøy' => true,
+   'sande' => true
+  ),
+  'hitra' => true,
+  'hjartdal' => true,
+  'hjelmeland' => true,
+  'hobol' => true,
+  'hobøl' => true,
+  'hof' => true,
+  'hol' => true,
+  'hole' => true,
+  'holmestrand' => true,
+  'holtalen' => true,
+  'holtålen' => true,
+  'hornindal' => true,
+  'horten' => true,
+  'hurdal' => true,
+  'hurum' => true,
+  'hvaler' => true,
+  'hyllestad' => true,
+  'hagebostad' => true,
+  'hægebostad' => true,
+  'hoyanger' => true,
+  'høyanger' => true,
+  'hoylandet' => true,
+  'høylandet' => true,
+  'ha' => true,
+  'hå' => true,
+  'ibestad' => true,
+  'inderoy' => true,
+  'inderøy' => true,
+  'iveland' => true,
+  'jevnaker' => true,
+  'jondal' => true,
+  'jolster' => true,
+  'jølster' => true,
+  'karasjok' => true,
+  'karasjohka' => true,
+  'kárášjohka' => true,
+  'karlsoy' => true,
+  'galsa' => true,
+  'gálsá' => true,
+  'karmoy' => true,
+  'karmøy' => true,
+  'kautokeino' => true,
+  'guovdageaidnu' => true,
+  'klepp' => true,
+  'klabu' => true,
+  'klæbu' => true,
+  'kongsberg' => true,
+  'kongsvinger' => true,
+  'kragero' => true,
+  'kragerø' => true,
+  'kristiansand' => true,
+  'kristiansund' => true,
+  'krodsherad' => true,
+  'krødsherad' => true,
+  'kvalsund' => true,
+  'rahkkeravju' => true,
+  'ráhkkerávju' => true,
+  'kvam' => true,
+  'kvinesdal' => true,
+  'kvinnherad' => true,
+  'kviteseid' => true,
+  'kvitsoy' => true,
+  'kvitsøy' => true,
+  'kvafjord' => true,
+  'kvæfjord' => true,
+  'giehtavuoatna' => true,
+  'kvanangen' => true,
+  'kvænangen' => true,
+  'navuotna' => true,
+  'návuotna' => true,
+  'kafjord' => true,
+  'kåfjord' => true,
+  'gaivuotna' => true,
+  'gáivuotna' => true,
+  'larvik' => true,
+  'lavangen' => true,
+  'lavagis' => true,
+  'loabat' => true,
+  'loabát' => true,
+  'lebesby' => true,
+  'davvesiida' => true,
+  'leikanger' => true,
+  'leirfjord' => true,
+  'leka' => true,
+  'leksvik' => true,
+  'lenvik' => true,
+  'leangaviika' => true,
+  'leaŋgaviika' => true,
+  'lesja' => true,
+  'levanger' => true,
+  'lier' => true,
+  'lierne' => true,
+  'lillehammer' => true,
+  'lillesand' => true,
+  'lindesnes' => true,
+  'lindas' => true,
+  'lindås' => true,
+  'lom' => true,
+  'loppa' => true,
+  'lahppi' => true,
+  'láhppi' => true,
+  'lund' => true,
+  'lunner' => true,
+  'luroy' => true,
+  'lurøy' => true,
+  'luster' => true,
+  'lyngdal' => true,
+  'lyngen' => true,
+  'ivgu' => true,
+  'lardal' => true,
+  'lerdal' => true,
+  'lærdal' => true,
+  'lodingen' => true,
+  'lødingen' => true,
+  'lorenskog' => true,
+  'lørenskog' => true,
+  'loten' => true,
+  'løten' => true,
+  'malvik' => true,
+  'masoy' => true,
+  'måsøy' => true,
+  'muosat' => true,
+  'muosát' => true,
+  'mandal' => true,
+  'marker' => true,
+  'marnardal' => true,
+  'masfjorden' => true,
+  'meland' => true,
+  'meldal' => true,
+  'melhus' => true,
+  'meloy' => true,
+  'meløy' => true,
+  'meraker' => true,
+  'meråker' => true,
+  'moareke' => true,
+  'moåreke' => true,
+  'midsund' => true,
+  'midtre-gauldal' => true,
+  'modalen' => true,
+  'modum' => true,
+  'molde' => true,
+  'moskenes' => true,
+  'moss' => true,
+  'mosvik' => true,
+  'malselv' => true,
+  'målselv' => true,
+  'malatvuopmi' => true,
+  'málatvuopmi' => true,
+  'namdalseid' => true,
+  'aejrie' => true,
+  'namsos' => true,
+  'namsskogan' => true,
+  'naamesjevuemie' => true,
+  'nååmesjevuemie' => true,
+  'laakesvuemie' => true,
+  'nannestad' => true,
+  'narvik' => true,
+  'narviika' => true,
+  'naustdal' => true,
+  'nedre-eiker' => true,
+  'akershus' => array(
+   'nes' => true
+  ),
+  'buskerud' => array(
+   'nes' => true
+  ),
+  'nesna' => true,
+  'nesodden' => true,
+  'nesseby' => true,
+  'unjarga' => true,
+  'unjárga' => true,
+  'nesset' => true,
+  'nissedal' => true,
+  'nittedal' => true,
+  'nord-aurdal' => true,
+  'nord-fron' => true,
+  'nord-odal' => true,
+  'norddal' => true,
+  'nordkapp' => true,
+  'davvenjarga' => true,
+  'davvenjárga' => true,
+  'nordre-land' => true,
+  'nordreisa' => true,
+  'raisa' => true,
+  'ráisa' => true,
+  'nore-og-uvdal' => true,
+  'notodden' => true,
+  'naroy' => true,
+  'nærøy' => true,
+  'notteroy' => true,
+  'nøtterøy' => true,
+  'odda' => true,
+  'oksnes' => true,
+  'øksnes' => true,
+  'oppdal' => true,
+  'oppegard' => true,
+  'oppegård' => true,
+  'orkdal' => true,
+  'orland' => true,
+  'ørland' => true,
+  'orskog' => true,
+  'ørskog' => true,
+  'orsta' => true,
+  'ørsta' => true,
+  'hedmark' => array(
+   'os' => true,
+   'valer' => true,
+   'våler' => true
+  ),
+  'hordaland' => array(
+   'os' => true
+  ),
+  'osen' => true,
+  'osteroy' => true,
+  'osterøy' => true,
+  'ostre-toten' => true,
+  'østre-toten' => true,
+  'overhalla' => true,
+  'ovre-eiker' => true,
+  'øvre-eiker' => true,
+  'oyer' => true,
+  'øyer' => true,
+  'oygarden' => true,
+  'øygarden' => true,
+  'oystre-slidre' => true,
+  'øystre-slidre' => true,
+  'porsanger' => true,
+  'porsangu' => true,
+  'porsáŋgu' => true,
+  'porsgrunn' => true,
+  'radoy' => true,
+  'radøy' => true,
+  'rakkestad' => true,
+  'rana' => true,
+  'ruovat' => true,
+  'randaberg' => true,
+  'rauma' => true,
+  'rendalen' => true,
+  'rennebu' => true,
+  'rennesoy' => true,
+  'rennesøy' => true,
+  'rindal' => true,
+  'ringebu' => true,
+  'ringerike' => true,
+  'ringsaker' => true,
+  'rissa' => true,
+  'risor' => true,
+  'risør' => true,
+  'roan' => true,
+  'rollag' => true,
+  'rygge' => true,
+  'ralingen' => true,
+  'rælingen' => true,
+  'rodoy' => true,
+  'rødøy' => true,
+  'romskog' => true,
+  'rømskog' => true,
+  'roros' => true,
+  'røros' => true,
+  'rost' => true,
+  'røst' => true,
+  'royken' => true,
+  'røyken' => true,
+  'royrvik' => true,
+  'røyrvik' => true,
+  'rade' => true,
+  'råde' => true,
+  'salangen' => true,
+  'siellak' => true,
+  'saltdal' => true,
+  'salat' => true,
+  'sálát' => true,
+  'sálat' => true,
+  'samnanger' => true,
+  'vestfold' => array(
+   'sande' => true
+  ),
+  'sandefjord' => true,
+  'sandnes' => true,
+  'sandoy' => true,
+  'sandøy' => true,
+  'sarpsborg' => true,
+  'sauda' => true,
+  'sauherad' => true,
+  'sel' => true,
+  'selbu' => true,
+  'selje' => true,
+  'seljord' => true,
+  'sigdal' => true,
+  'siljan' => true,
+  'sirdal' => true,
+  'skaun' => true,
+  'skedsmo' => true,
+  'ski' => true,
+  'skien' => true,
+  'skiptvet' => true,
+  'skjervoy' => true,
+  'skjervøy' => true,
+  'skierva' => true,
+  'skiervá' => true,
+  'skjak' => true,
+  'skjåk' => true,
+  'skodje' => true,
+  'skanland' => true,
+  'skånland' => true,
+  'skanit' => true,
+  'skánit' => true,
+  'smola' => true,
+  'smøla' => true,
+  'snillfjord' => true,
+  'snasa' => true,
+  'snåsa' => true,
+  'snoasa' => true,
+  'snaase' => true,
+  'snåase' => true,
+  'sogndal' => true,
+  'sokndal' => true,
+  'sola' => true,
+  'solund' => true,
+  'songdalen' => true,
+  'sortland' => true,
+  'spydeberg' => true,
+  'stange' => true,
+  'stavanger' => true,
+  'steigen' => true,
+  'steinkjer' => true,
+  'stjordal' => true,
+  'stjørdal' => true,
+  'stokke' => true,
+  'stor-elvdal' => true,
+  'stord' => true,
+  'stordal' => true,
+  'storfjord' => true,
+  'omasvuotna' => true,
+  'strand' => true,
+  'stranda' => true,
+  'stryn' => true,
+  'sula' => true,
+  'suldal' => true,
+  'sund' => true,
+  'sunndal' => true,
+  'surnadal' => true,
+  'sveio' => true,
+  'svelvik' => true,
+  'sykkylven' => true,
+  'sogne' => true,
+  'søgne' => true,
+  'somna' => true,
+  'sømna' => true,
+  'sondre-land' => true,
+  'søndre-land' => true,
+  'sor-aurdal' => true,
+  'sør-aurdal' => true,
+  'sor-fron' => true,
+  'sør-fron' => true,
+  'sor-odal' => true,
+  'sør-odal' => true,
+  'sor-varanger' => true,
+  'sør-varanger' => true,
+  'matta-varjjat' => true,
+  'mátta-várjjat' => true,
+  'sorfold' => true,
+  'sørfold' => true,
+  'sorreisa' => true,
+  'sørreisa' => true,
+  'sorum' => true,
+  'sørum' => true,
+  'tana' => true,
+  'deatnu' => true,
+  'time' => true,
+  'tingvoll' => true,
+  'tinn' => true,
+  'tjeldsund' => true,
+  'dielddanuorri' => true,
+  'tjome' => true,
+  'tjøme' => true,
+  'tokke' => true,
+  'tolga' => true,
+  'torsken' => true,
+  'tranoy' => true,
+  'tranøy' => true,
+  'tromso' => true,
+  'tromsø' => true,
+  'tromsa' => true,
+  'romsa' => true,
+  'trondheim' => true,
+  'troandin' => true,
+  'trysil' => true,
+  'trana' => true,
+  'træna' => true,
+  'trogstad' => true,
+  'trøgstad' => true,
+  'tvedestrand' => true,
+  'tydal' => true,
+  'tynset' => true,
+  'tysfjord' => true,
+  'divtasvuodna' => true,
+  'divttasvuotna' => true,
+  'tysnes' => true,
+  'tysvar' => true,
+  'tysvær' => true,
+  'tonsberg' => true,
+  'tønsberg' => true,
+  'ullensaker' => true,
+  'ullensvang' => true,
+  'ulvik' => true,
+  'utsira' => true,
+  'vadso' => true,
+  'vadsø' => true,
+  'cahcesuolo' => true,
+  'čáhcesuolo' => true,
+  'vaksdal' => true,
+  'valle' => true,
+  'vang' => true,
+  'vanylven' => true,
+  'vardo' => true,
+  'vardø' => true,
+  'varggat' => true,
+  'várggát' => true,
+  'vefsn' => true,
+  'vaapste' => true,
+  'vega' => true,
+  'vegarshei' => true,
+  'vegårshei' => true,
+  'vennesla' => true,
+  'verdal' => true,
+  'verran' => true,
+  'vestby' => true,
+  'vestnes' => true,
+  'vestre-slidre' => true,
+  'vestre-toten' => true,
+  'vestvagoy' => true,
+  'vestvågøy' => true,
+  'vevelstad' => true,
+  'vik' => true,
+  'vikna' => true,
+  'vindafjord' => true,
+  'volda' => true,
+  'voss' => true,
+  'varoy' => true,
+  'værøy' => true,
+  'vagan' => true,
+  'vågan' => true,
+  'voagat' => true,
+  'vagsoy' => true,
+  'vågsøy' => true,
+  'vaga' => true,
+  'vågå' => true,
+  'ostfold' => array(
+   'valer' => true
+  ),
+  'østfold' => array(
+   'våler' => true
+  )
+ ),
+ 'np' => array(
+  '*' => true
+ ),
+ 'nr' => array(
+  'biz' => true,
+  'info' => true,
+  'gov' => true,
+  'edu' => true,
+  'org' => true,
+  'net' => true,
+  'com' => true
+ ),
+ 'nu' => true,
+ 'nz' => array(
+  '*' => true
+ ),
+ 'om' => array(
+  '*' => true,
+  '!mediaphone' => true,
+  '!nawrastelecom' => true,
+  '!nawras' => true,
+  '!omanmobile' => true,
+  '!omanpost' => true,
+  '!omantel' => true,
+  '!rakpetroleum' => true,
+  '!siemens' => true,
+  '!songfest' => true,
+  '!statecouncil' => true
+ ),
+ 'org' => array(
+  'ae' => true,
+  'za' => true
+ ),
+ 'pa' => array(
+  'ac' => true,
+  'gob' => true,
+  'com' => true,
+  'org' => true,
+  'sld' => true,
+  'edu' => true,
+  'net' => true,
+  'ing' => true,
+  'abo' => true,
+  'med' => true,
+  'nom' => true
+ ),
+ 'pe' => array(
+  'edu' => true,
+  'gob' => true,
+  'nom' => true,
+  'mil' => true,
+  'org' => true,
+  'com' => true,
+  'net' => true
+ ),
+ 'pf' => array(
+  'com' => true,
+  'org' => true,
+  'edu' => true
+ ),
+ 'pg' => array(
+  '*' => true
+ ),
+ 'ph' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'edu' => true,
+  'ngo' => true,
+  'mil' => true,
+  'i' => true
+ ),
+ 'pk' => array(
+  'com' => true,
+  'net' => true,
+  'edu' => true,
+  'org' => true,
+  'fam' => true,
+  'biz' => true,
+  'web' => true,
+  'gov' => true,
+  'gob' => true,
+  'gok' => true,
+  'gon' => true,
+  'gop' => true,
+  'gos' => true,
+  'info' => true
+ ),
+ 'pl' => array(
+  'aid' => true,
+  'agro' => true,
+  'atm' => true,
+  'auto' => true,
+  'biz' => true,
+  'com' => true,
+  'edu' => true,
+  'gmina' => true,
+  'gsm' => true,
+  'info' => true,
+  'mail' => true,
+  'miasta' => true,
+  'media' => true,
+  'mil' => true,
+  'net' => true,
+  'nieruchomosci' => true,
+  'nom' => true,
+  'org' => true,
+  'pc' => true,
+  'powiat' => true,
+  'priv' => true,
+  'realestate' => true,
+  'rel' => true,
+  'sex' => true,
+  'shop' => true,
+  'sklep' => true,
+  'sos' => true,
+  'szkola' => true,
+  'targi' => true,
+  'tm' => true,
+  'tourism' => true,
+  'travel' => true,
+  'turystyka' => true,
+  '6bone' => true,
+  'art' => true,
+  'mbone' => true,
+  'gov' => array(
+   'uw' => true,
+   'um' => true,
+   'ug' => true,
+   'upow' => true,
+   'starostwo' => true,
+   'so' => true,
+   'sr' => true,
+   'po' => true,
+   'pa' => true
+  ),
+  'ngo' => true,
+  'irc' => true,
+  'usenet' => true,
+  'augustow' => true,
+  'babia-gora' => true,
+  'bedzin' => true,
+  'beskidy' => true,
+  'bialowieza' => true,
+  'bialystok' => true,
+  'bielawa' => true,
+  'bieszczady' => true,
+  'boleslawiec' => true,
+  'bydgoszcz' => true,
+  'bytom' => true,
+  'cieszyn' => true,
+  'czeladz' => true,
+  'czest' => true,
+  'dlugoleka' => true,
+  'elblag' => true,
+  'elk' => true,
+  'glogow' => true,
+  'gniezno' => true,
+  'gorlice' => true,
+  'grajewo' => true,
+  'ilawa' => true,
+  'jaworzno' => true,
+  'jelenia-gora' => true,
+  'jgora' => true,
+  'kalisz' => true,
+  'kazimierz-dolny' => true,
+  'karpacz' => true,
+  'kartuzy' => true,
+  'kaszuby' => true,
+  'katowice' => true,
+  'kepno' => true,
+  'ketrzyn' => true,
+  'klodzko' => true,
+  'kobierzyce' => true,
+  'kolobrzeg' => true,
+  'konin' => true,
+  'konskowola' => true,
+  'kutno' => true,
+  'lapy' => true,
+  'lebork' => true,
+  'legnica' => true,
+  'lezajsk' => true,
+  'limanowa' => true,
+  'lomza' => true,
+  'lowicz' => true,
+  'lubin' => true,
+  'lukow' => true,
+  'malbork' => true,
+  'malopolska' => true,
+  'mazowsze' => true,
+  'mazury' => true,
+  'mielec' => true,
+  'mielno' => true,
+  'mragowo' => true,
+  'naklo' => true,
+  'nowaruda' => true,
+  'nysa' => true,
+  'olawa' => true,
+  'olecko' => true,
+  'olkusz' => true,
+  'olsztyn' => true,
+  'opoczno' => true,
+  'opole' => true,
+  'ostroda' => true,
+  'ostroleka' => true,
+  'ostrowiec' => true,
+  'ostrowwlkp' => true,
+  'pila' => true,
+  'pisz' => true,
+  'podhale' => true,
+  'podlasie' => true,
+  'polkowice' => true,
+  'pomorze' => true,
+  'pomorskie' => true,
+  'prochowice' => true,
+  'pruszkow' => true,
+  'przeworsk' => true,
+  'pulawy' => true,
+  'radom' => true,
+  'rawa-maz' => true,
+  'rybnik' => true,
+  'rzeszow' => true,
+  'sanok' => true,
+  'sejny' => true,
+  'siedlce' => true,
+  'slask' => true,
+  'slupsk' => true,
+  'sosnowiec' => true,
+  'stalowa-wola' => true,
+  'skoczow' => true,
+  'starachowice' => true,
+  'stargard' => true,
+  'suwalki' => true,
+  'swidnica' => true,
+  'swiebodzin' => true,
+  'swinoujscie' => true,
+  'szczecin' => true,
+  'szczytno' => true,
+  'tarnobrzeg' => true,
+  'tgory' => true,
+  'turek' => true,
+  'tychy' => true,
+  'ustka' => true,
+  'walbrzych' => true,
+  'warmia' => true,
+  'warszawa' => true,
+  'waw' => true,
+  'wegrow' => true,
+  'wielun' => true,
+  'wlocl' => true,
+  'wloclawek' => true,
+  'wodzislaw' => true,
+  'wolomin' => true,
+  'wroclaw' => true,
+  'zachpomor' => true,
+  'zagan' => true,
+  'zarow' => true,
+  'zgora' => true,
+  'zgorzelec' => true,
+  'gda' => true,
+  'gdansk' => true,
+  'gdynia' => true,
+  'med' => true,
+  'sopot' => true,
+  'gliwice' => true,
+  'krakow' => true,
+  'poznan' => true,
+  'wroc' => true,
+  'zakopane' => true,
+  'co' => true
+ ),
+ 'pn' => array(
+  'gov' => true,
+  'co' => true,
+  'org' => true,
+  'edu' => true,
+  'net' => true
+ ),
+ 'pr' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'edu' => true,
+  'isla' => true,
+  'pro' => true,
+  'biz' => true,
+  'info' => true,
+  'name' => true,
+  'est' => true,
+  'prof' => true,
+  'ac' => true
+ ),
+ 'pro' => array(
+  'aca' => true,
+  'bar' => true,
+  'cpa' => true,
+  'jur' => true,
+  'law' => true,
+  'med' => true,
+  'eng' => true
+ ),
+ 'ps' => array(
+  'edu' => true,
+  'gov' => true,
+  'sec' => true,
+  'plo' => true,
+  'com' => true,
+  'org' => true,
+  'net' => true
+ ),
+ 'pt' => array(
+  'net' => true,
+  'gov' => true,
+  'org' => true,
+  'edu' => true,
+  'int' => true,
+  'publ' => true,
+  'com' => true,
+  'nome' => true
+ ),
+ 'pw' => array(
+  'co' => true,
+  'ne' => true,
+  'or' => true,
+  'ed' => true,
+  'go' => true,
+  'belau' => true
+ ),
+ 'py' => array(
+  '*' => true
+ ),
+ 'qa' => array(
+  '*' => true
+ ),
+ 're' => array(
+  'com' => true,
+  'asso' => true,
+  'nom' => true
+ ),
+ 'ro' => array(
+  'com' => true,
+  'org' => true,
+  'tm' => true,
+  'nt' => true,
+  'nom' => true,
+  'info' => true,
+  'rec' => true,
+  'arts' => true,
+  'firm' => true,
+  'store' => true,
+  'www' => true
+ ),
+ 'rs' => array(
+  'co' => true,
+  'org' => true,
+  'edu' => true,
+  'ac' => true,
+  'gov' => true,
+  'in' => true
+ ),
+ 'ru' => array(
+  'ac' => true,
+  'com' => true,
+  'edu' => true,
+  'int' => true,
+  'net' => true,
+  'org' => true,
+  'pp' => true,
+  'adygeya' => true,
+  'altai' => true,
+  'amur' => true,
+  'arkhangelsk' => true,
+  'astrakhan' => true,
+  'bashkiria' => true,
+  'belgorod' => true,
+  'bir' => true,
+  'bryansk' => true,
+  'buryatia' => true,
+  'cbg' => true,
+  'chel' => true,
+  'chelyabinsk' => true,
+  'chita' => true,
+  'chukotka' => true,
+  'chuvashia' => true,
+  'dagestan' => true,
+  'dudinka' => true,
+  'e-burg' => true,
+  'grozny' => true,
+  'irkutsk' => true,
+  'ivanovo' => true,
+  'izhevsk' => true,
+  'jar' => true,
+  'joshkar-ola' => true,
+  'kalmykia' => true,
+  'kaluga' => true,
+  'kamchatka' => true,
+  'karelia' => true,
+  'kazan' => true,
+  'kchr' => true,
+  'kemerovo' => true,
+  'khabarovsk' => true,
+  'khakassia' => true,
+  'khv' => true,
+  'kirov' => true,
+  'koenig' => true,
+  'komi' => true,
+  'kostroma' => true,
+  'krasnoyarsk' => true,
+  'kuban' => true,
+  'kurgan' => true,
+  'kursk' => true,
+  'lipetsk' => true,
+  'magadan' => true,
+  'mari' => true,
+  'mari-el' => true,
+  'marine' => true,
+  'mordovia' => true,
+  'mosreg' => true,
+  'msk' => true,
+  'murmansk' => true,
+  'nalchik' => true,
+  'nnov' => true,
+  'nov' => true,
+  'novosibirsk' => true,
+  'nsk' => true,
+  'omsk' => true,
+  'orenburg' => true,
+  'oryol' => true,
+  'palana' => true,
+  'penza' => true,
+  'perm' => true,
+  'pskov' => true,
+  'ptz' => true,
+  'rnd' => true,
+  'ryazan' => true,
+  'sakhalin' => true,
+  'samara' => true,
+  'saratov' => true,
+  'simbirsk' => true,
+  'smolensk' => true,
+  'spb' => true,
+  'stavropol' => true,
+  'stv' => true,
+  'surgut' => true,
+  'tambov' => true,
+  'tatarstan' => true,
+  'tom' => true,
+  'tomsk' => true,
+  'tsaritsyn' => true,
+  'tsk' => true,
+  'tula' => true,
+  'tuva' => true,
+  'tver' => true,
+  'tyumen' => true,
+  'udm' => true,
+  'udmurtia' => true,
+  'ulan-ude' => true,
+  'vladikavkaz' => true,
+  'vladimir' => true,
+  'vladivostok' => true,
+  'volgograd' => true,
+  'vologda' => true,
+  'voronezh' => true,
+  'vrn' => true,
+  'vyatka' => true,
+  'yakutia' => true,
+  'yamal' => true,
+  'yaroslavl' => true,
+  'yekaterinburg' => true,
+  'yuzhno-sakhalinsk' => true,
+  'amursk' => true,
+  'baikal' => true,
+  'cmw' => true,
+  'fareast' => true,
+  'jamal' => true,
+  'kms' => true,
+  'k-uralsk' => true,
+  'kustanai' => true,
+  'kuzbass' => true,
+  'magnitka' => true,
+  'mytis' => true,
+  'nakhodka' => true,
+  'nkz' => true,
+  'norilsk' => true,
+  'oskol' => true,
+  'pyatigorsk' => true,
+  'rubtsovsk' => true,
+  'snz' => true,
+  'syzran' => true,
+  'vdonsk' => true,
+  'zgrad' => true,
+  'gov' => true,
+  'mil' => true,
+  'test' => true
+ ),
+ 'rw' => array(
+  'gov' => true,
+  'net' => true,
+  'edu' => true,
+  'ac' => true,
+  'com' => true,
+  'co' => true,
+  'int' => true,
+  'mil' => true,
+  'gouv' => true
+ ),
+ 'sa' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'med' => true,
+  'pub' => true,
+  'edu' => true,
+  'sch' => true
+ ),
+ 'sb' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'sc' => array(
+  'com' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true
+ ),
+ 'sd' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'med' => true,
+  'gov' => true,
+  'info' => true
+ ),
+ 'se' => array(
+  'a' => true,
+  'ac' => true,
+  'b' => true,
+  'bd' => true,
+  'brand' => true,
+  'c' => true,
+  'd' => true,
+  'e' => true,
+  'f' => true,
+  'fh' => true,
+  'fhsk' => true,
+  'fhv' => true,
+  'g' => true,
+  'h' => true,
+  'i' => true,
+  'k' => true,
+  'komforb' => true,
+  'kommunalforbund' => true,
+  'komvux' => true,
+  'l' => true,
+  'lanbib' => true,
+  'm' => true,
+  'n' => true,
+  'naturbruksgymn' => true,
+  'o' => true,
+  'org' => true,
+  'p' => true,
+  'parti' => true,
+  'pp' => true,
+  'press' => true,
+  'r' => true,
+  's' => true,
+  'sshn' => true,
+  't' => true,
+  'tm' => true,
+  'u' => true,
+  'w' => true,
+  'x' => true,
+  'y' => true,
+  'z' => true
+ ),
+ 'sg' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'edu' => true,
+  'per' => true
+ ),
+ 'sh' => true,
+ 'si' => true,
+ 'sk' => true,
+ 'sl' => array(
+  'com' => true,
+  'net' => true,
+  'edu' => true,
+  'gov' => true,
+  'org' => true
+ ),
+ 'sm' => true,
+ 'sn' => array(
+  'art' => true,
+  'com' => true,
+  'edu' => true,
+  'gouv' => true,
+  'org' => true,
+  'perso' => true,
+  'univ' => true
+ ),
+ 'so' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'sr' => true,
+ 'st' => array(
+  'co' => true,
+  'com' => true,
+  'consulado' => true,
+  'edu' => true,
+  'embaixada' => true,
+  'gov' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true,
+  'principe' => true,
+  'saotome' => true,
+  'store' => true
+ ),
+ 'su' => true,
+ 'sv' => array(
+  '*' => true
+ ),
+ 'sy' => array(
+  'edu' => true,
+  'gov' => true,
+  'net' => true,
+  'mil' => true,
+  'com' => true,
+  'org' => true
+ ),
+ 'sz' => array(
+  'co' => true,
+  'ac' => true,
+  'org' => true
+ ),
+ 'tc' => true,
+ 'td' => true,
+ 'tel' => true,
+ 'tf' => true,
+ 'tg' => true,
+ 'th' => array(
+  'ac' => true,
+  'co' => true,
+  'go' => true,
+  'in' => true,
+  'mi' => true,
+  'net' => true,
+  'or' => true
+ ),
+ 'tj' => array(
+  'ac' => true,
+  'biz' => true,
+  'co' => true,
+  'com' => true,
+  'edu' => true,
+  'go' => true,
+  'gov' => true,
+  'int' => true,
+  'mil' => true,
+  'name' => true,
+  'net' => true,
+  'nic' => true,
+  'org' => true,
+  'test' => true,
+  'web' => true
+ ),
+ 'tk' => true,
+ 'tl' => array(
+  'gov' => true
+ ),
+ 'tm' => true,
+ 'tn' => array(
+  'com' => true,
+  'ens' => true,
+  'fin' => true,
+  'gov' => true,
+  'ind' => true,
+  'intl' => true,
+  'nat' => true,
+  'net' => true,
+  'org' => true,
+  'info' => true,
+  'perso' => true,
+  'tourism' => true,
+  'edunet' => true,
+  'rnrt' => true,
+  'rns' => true,
+  'rnu' => true,
+  'mincom' => true,
+  'agrinet' => true,
+  'defense' => true,
+  'turen' => true
+ ),
+ 'to' => array(
+  'com' => true,
+  'gov' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'mil' => true
+ ),
+ 'tr' => array(
+  '*' => true,
+  '!nic' => true,
+  '!tsk' => true,
+  'nc' => array(
+   'gov' => true
+  )
+ ),
+ 'travel' => true,
+ 'tt' => array(
+  'co' => true,
+  'com' => true,
+  'org' => true,
+  'net' => true,
+  'biz' => true,
+  'info' => true,
+  'pro' => true,
+  'int' => true,
+  'coop' => true,
+  'jobs' => true,
+  'mobi' => true,
+  'travel' => true,
+  'museum' => true,
+  'aero' => true,
+  'name' => true,
+  'gov' => true,
+  'edu' => true
+ ),
+ 'tv' => true,
+ 'tw' => array(
+  'edu' => true,
+  'gov' => true,
+  'mil' => true,
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'idv' => true,
+  'game' => true,
+  'ebiz' => true,
+  'club' => true,
+  '網路' => true,
+  '組織' => true,
+  '商業' => true
+ ),
+ 'tz' => array(
+  'ac' => true,
+  'co' => true,
+  'go' => true,
+  'mil' => true,
+  'ne' => true,
+  'or' => true,
+  'sc' => true
+ ),
+ 'ua' => array(
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'in' => true,
+  'net' => true,
+  'org' => true,
+  'cherkassy' => true,
+  'chernigov' => true,
+  'chernovtsy' => true,
+  'ck' => true,
+  'cn' => true,
+  'crimea' => true,
+  'cv' => true,
+  'dn' => true,
+  'dnepropetrovsk' => true,
+  'donetsk' => true,
+  'dp' => true,
+  'if' => true,
+  'ivano-frankivsk' => true,
+  'kh' => true,
+  'kharkov' => true,
+  'kherson' => true,
+  'khmelnitskiy' => true,
+  'kiev' => true,
+  'kirovograd' => true,
+  'km' => true,
+  'kr' => true,
+  'ks' => true,
+  'kv' => true,
+  'lg' => true,
+  'lugansk' => true,
+  'lutsk' => true,
+  'lviv' => true,
+  'mk' => true,
+  'nikolaev' => true,
+  'od' => true,
+  'odessa' => true,
+  'pl' => true,
+  'poltava' => true,
+  'rovno' => true,
+  'rv' => true,
+  'sebastopol' => true,
+  'sumy' => true,
+  'te' => true,
+  'ternopil' => true,
+  'uzhgorod' => true,
+  'vinnica' => true,
+  'vn' => true,
+  'zaporizhzhe' => true,
+  'zp' => true,
+  'zhitomir' => true,
+  'zt' => true
+ ),
+ 'ug' => array(
+  'co' => true,
+  'ac' => true,
+  'sc' => true,
+  'go' => true,
+  'ne' => true,
+  'or' => true
+ ),
+ 'uk' => array(
+  '*' => true,
+  'sch' => array(
+   '*' => true
+  ),
+  '!bl' => true,
+  '!british-library' => true,
+  '!icnet' => true,
+  '!jet' => true,
+  '!nel' => true,
+  '!nhs' => true,
+  '!nls' => true,
+  '!national-library-scotland' => true,
+  '!parliament' => true
+ ),
+ 'us' => array(
+  'dni' => true,
+  'fed' => true,
+  'isa' => true,
+  'kids' => true,
+  'nsn' => true,
+  'ak' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'al' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ar' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'as' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'az' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ca' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'co' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ct' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'dc' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'de' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'fl' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ga' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'gu' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'hi' => array(
+   'cc' => true,
+   'lib' => true
+  ),
+  'ia' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'id' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'il' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'in' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ks' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ky' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'la' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ma' => array(
+   'k12' => array(
+    'pvt' => true,
+    'chtr' => true,
+    'paroch' => true
+   ),
+   'cc' => true,
+   'lib' => true
+  ),
+  'md' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'me' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'mi' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'mn' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'mo' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ms' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'mt' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'nc' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'nd' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ne' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'nh' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'nj' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'nm' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'nv' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ny' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'oh' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ok' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'or' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'pa' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'pr' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ri' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'sc' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'sd' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'tn' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'tx' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'ut' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'vi' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'vt' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'va' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'wa' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'wi' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'wv' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  ),
+  'wy' => array(
+   'k12' => true,
+   'cc' => true,
+   'lib' => true
+  )
+ ),
+ 'uy' => array(
+  '*' => true
+ ),
+ 'uz' => array(
+  'com' => true,
+  'co' => true
+ ),
+ 'va' => true,
+ 'vc' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'mil' => true,
+  'edu' => true
+ ),
+ 've' => array(
+  '*' => true
+ ),
+ 'vg' => true,
+ 'vi' => array(
+  'co' => true,
+  'com' => true,
+  'k12' => true,
+  'net' => true,
+  'org' => true
+ ),
+ 'vn' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'edu' => true,
+  'gov' => true,
+  'int' => true,
+  'ac' => true,
+  'biz' => true,
+  'info' => true,
+  'name' => true,
+  'pro' => true,
+  'health' => true
+ ),
+ 'vu' => true,
+ 'ws' => array(
+  'com' => true,
+  'net' => true,
+  'org' => true,
+  'gov' => true,
+  'edu' => true
+ ),
+ 'امارات' => true,
+ '中国' => true,
+ '中國' => true,
+ 'مصر' => true,
+ '香港' => true,
+ 'الاردن' => true,
+ 'ලංකා' => true,
+ 'இலங்கை' => true,
+ 'فلسطين' => true,
+ 'рф' => true,
+ 'قطر' => true,
+ 'السعودية' => true,
+ '新加坡' => true,
+ 'சிங்கப்பூர்' => true,
+ 'ไทย' => true,
+ 'تونس' => true,
+ '台灣' => true,
+ '台湾' => true,
+ 'ye' => array(
+  '*' => true
+ ),
+ 'yu' => array(
+  '*' => true
+ ),
+ 'za' => array(
+  '*' => true
+ ),
+ 'zm' => array(
+  '*' => true
+ ),
+ 'zw' => array(
+  '*' => true
+ )
+);
+?>
\ No newline at end of file
diff --git a/lib/docs/HTTP_Request2/HTTP/examples/upload-rapidshare.php b/lib/docs/HTTP_Request2/HTTP/examples/upload-rapidshare.php
new file mode 100644
index 0000000..9773a94
--- /dev/null
+++ b/lib/docs/HTTP_Request2/HTTP/examples/upload-rapidshare.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Usage example for HTTP_Request2 package: uploading a file to rapidshare.com
+ *
+ * Inspired by Perl usage example: http://images.rapidshare.com/software/rsapi.pl
+ * Rapidshare API description: http://rapidshare.com/dev.html
+ *
+ * $Id: upload-rapidshare.php 287307 2009-08-14 15:40:22Z avb $
+ */
+
+require_once 'HTTP/Request2.php';
+
+// You'll probably want to change this
+$filename = '/etc/passwd';
+
+try {
+    // First step: get an available upload server
+    $request = new HTTP_Request2(
+        'http://rapidshare.com/cgi-bin/rsapi.cgi?sub=nextuploadserver_v1'
+    );
+    $server  = $request->send()->getBody();
+    if (!preg_match('/^(\\d+)$/', $server)) {
+        throw new Exception("Invalid upload server: {$server}");
+    }
+
+    // Calculate file hash, we'll use it later to check upload
+    if (false === ($hash = @md5_file($filename))) {
+        throw new Exception("Cannot calculate MD5 hash of '{$filename}'");
+    }
+
+    // Second step: upload a file to the available server
+    $uploader = new HTTP_Request2(
+        "http://rs{$server}l3.rapidshare.com/cgi-bin/upload.cgi",
+        HTTP_Request2::METHOD_POST
+    );
+    // Adding the file
+    $uploader->addUpload('filecontent', $filename);
+    // This will tell server to return program-friendly output
+    $uploader->addPostParameter('rsapi_v1', '1');
+
+    $response = $uploader->send()->getBody();
+    if (!preg_match_all('/^(File[^=]+)=(.+)$/m', $response, $m, PREG_SET_ORDER)) {
+        throw new Exception("Invalid response: {$response}");
+    }
+    $rspAry = array();
+    foreach ($m as $item) {
+        $rspAry[$item[1]] = $item[2];
+    }
+    // Check that uploaded file has the same hash
+    if (empty($rspAry['File1.4'])) {
+        throw new Exception("MD5 hash data not found in response");
+    } elseif ($hash != strtolower($rspAry['File1.4'])) {
+        throw new Exception("Upload failed, local MD5 is {$hash}, uploaded MD5 is {$rspAry['File1.4']}");
+    }
+    echo "Upload succeeded\nDownload link: {$rspAry['File1.1']}\nDelete link: {$rspAry['File1.2']}\n";
+
+} catch (Exception $e) {
+    echo "Error: " . $e->getMessage();
+}
+?>
diff --git a/lib/docs/Net_URL2/Net/docs/6470.php b/lib/docs/Net_URL2/Net/docs/6470.php
new file mode 100644
index 0000000..104de89
--- /dev/null
+++ b/lib/docs/Net_URL2/Net/docs/6470.php
@@ -0,0 +1,75 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Copyright (c) 2002-2003, Richard Heyes                                     |
+// | All rights reserved.                                                  |
+// |                                                                       |
+// | Redistribution and use in source and binary forms, with or without    |
+// | modification, are permitted provided that the following conditions    |
+// | are met:                                                              |
+// |                                                                       |
+// | o Redistributions of source code must retain the above copyright      |
+// |   notice, this list of conditions and the following disclaimer.       |
+// | o 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.|
+// | o The names of the authors may not 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.  |
+// |                                                                       |
+// +-----------------------------------------------------------------------+
+// | Author: Richard Heyes <richard at php net>                            |
+// +-----------------------------------------------------------------------+
+// $Id: 6470.php 235190 2007-05-08 00:04:54Z davidc $
+/**
+* This example will decode the url given and display its
+* constituent parts.
+*/
+    error_reporting(E_ALL | E_STRICT);
+
+    require_once 'Net/URL2.php';
+
+    //$url = &new Net_URL2('https://www.example.com/foo/bar/index.php?foo=bar');
+    Net_URL2::setOption('encode_query_keys', true);
+    $url = new Net_URL2;
+    
+?>
+<html>
+<body>
+
+<pre>
+Protocol...: <?php echo $url->protocol; ?>
+
+Username...: <?php echo $url->user; ?>
+
+Password...: <?php echo $url->pass; ?>
+
+Server.....: <?php echo $url->host; ?>
+
+Port.......: <?php $url->port; ?>
+
+File/path..: <?php $url->path; ?>
+
+Querystring: <?php print_r($url->querystring); ?>
+
+Anchor.....: <?php echo $url->anchor;?>
+
+Full URL...: <?php echo $url->getUrl(); ?>
+
+
+Resolve path (/.././/foo/bar/joe/./././../jabba): <b><?php Net_URL2::resolvePath('/.././/foo/bar/joe/./././../jabba'); ?></b>
+</pre>
+
+</body>
+</html>
diff --git a/lib/docs/Net_URL2/Net/docs/example.php b/lib/docs/Net_URL2/Net/docs/example.php
new file mode 100644
index 0000000..d2725ba
--- /dev/null
+++ b/lib/docs/Net_URL2/Net/docs/example.php
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Copyright (c) 2002-2003, Richard Heyes                                     |
+// | All rights reserved.                                                  |
+// |                                                                       |
+// | Redistribution and use in source and binary forms, with or without    |
+// | modification, are permitted provided that the following conditions    |
+// | are met:                                                              |
+// |                                                                       |
+// | o Redistributions of source code must retain the above copyright      |
+// |   notice, this list of conditions and the following disclaimer.       |
+// | o 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.|
+// | o The names of the authors may not 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.  |
+// |                                                                       |
+// +-----------------------------------------------------------------------+
+// | Author: Richard Heyes <richard at php net>                            |
+// +-----------------------------------------------------------------------+
+// $Id: example.php 235190 2007-05-08 00:04:54Z davidc $
+/**
+* This example will decode the url given and display its
+* constituent parts.
+*/
+    error_reporting(E_ALL | E_STRICT);
+
+    //include('../URL2.php');
+    include('Net/URL2.php');
+
+    //$url = &new Net_URL2('https://www.example.com/foo/bar/index.php?foo=bar');
+    $url = new Net_URL2('https://example.com/pls/portal30/PORTAL30.wwpob_page.changetabs?p_back_url=http%3A%2F%2Fexample.com%2Fservlet%2Fpage%3F_pageid%3D360%2C366%2C368%2C382%26_dad%3Dportal30%26_schema%3DPORTAL30&foo=bar');
+?>
+<html>
+<body>
+
+<pre>
+Protocol...: <?php echo $url->protocol; ?>
+
+Username...: <?php echo $url->user; ?>
+
+Password...: <?php echo $url->pass; ?>
+
+Server.....: <?php echo $url->host; ?>
+
+Port.......: <?php $url->port; ?>
+
+File/path..: <?php $url->path; ?>
+
+Querystring: <?php print_r($url->querystring); ?>
+
+Anchor.....: <?php echo $url->anchor;?>
+
+Full URL...: <?php echo $url->getUrl(); ?>
+
+
+Resolve path (/.././/foo/bar/joe/./././../jabba): <b><?php Net_URL2::resolvePath('/.././/foo/bar/joe/./././../jabba'); ?></b>
+</pre>
+
+</body>
+</html>
diff --git a/lib/docs/SimpleCAS/docs/examples/Zend_Auth_Adapter_SimpleCAS.php b/lib/docs/SimpleCAS/docs/examples/Zend_Auth_Adapter_SimpleCAS.php
new file mode 100644
index 0000000..921d1a0
--- /dev/null
+++ b/lib/docs/SimpleCAS/docs/examples/Zend_Auth_Adapter_SimpleCAS.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * This is a Zend_Auth adapter library for CAS.
+ * It uses SimpleCAS.
+ *
+ * <code>
+ * public function casAction()
+ * {
+ *     $auth = Zend_Auth::getInstance();
+ *     $authAdapter = new UNL_CasZendAuthAdapter(
+ *         Zend_Registry::get('config')->auth->cas
+ *     );
+ * 
+ *     # User has not been identified, and there's a ticket in the URL
+ *     if (!$auth->hasIdentity() && isset($_GET['ticket'])) {
+ *         $authAdapter->setTicket($_GET['ticket']);
+ *         $result = $auth->authenticate($authAdapter);
+ * 
+ *         if ($result->isValid()) {
+ *             Zend_Session::regenerateId();
+ *         }
+ *     }
+ * 
+ *     # No ticket or ticket was invalid. Redirect to CAS.
+ *     if (!$auth->hasIdentity()) {
+ *         $this->_redirect($authAdapter->getLoginURL());
+ *     }
+ * }
+ * </code>
+ */
+
+
+/**
+ * @see Zend_Auth_Adapter_Interface
+ */
+require_once 'Zend/Auth/Adapter/Interface.php';
+
+require_once('SimpleCAS/Server/Version2.php');
+
+class Zend_Auth_Adapter_SimpleCAS implements Zend_Auth_Adapter_Interface
+{
+    /**
+     * CAS client
+     */
+    private $_protocol;
+
+    /**
+     * Service ticket
+     */
+    private $_ticket;
+
+    /**
+     * Constructor
+     *
+     * @param string $server_hostname
+     * @param string $server_port
+     * @param string $server_uri
+     * @return void
+     */ 
+    public function __construct($options)
+    {
+        $this->_protocol = new SimpleCAS_Protocol_Version2($options);
+    }
+
+    public function setTicket($ticket)
+    {
+        $this->_ticket = $ticket;
+        return $this;
+    }
+
+    /**
+     * Authenticates ticket
+     *
+     * The ticket is provided with setTicket
+     *
+     * @param return boolean
+     */ 
+    public function authenticate()
+    {
+        if ($id = $this->_protocol->validateTicket($this->_ticket, self::getURL())) {
+            return new Zend_Auth_Result(
+                Zend_Auth_Result::SUCCESS,
+                $id,
+                array("Authentication successful"));
+        } else {
+            return new Zend_Auth_Result(
+                Zend_Auth_Result::FAILURE,
+                null,
+                array("Authentication failed"));
+        }
+    }
+    
+    /**
+     * Returns the current URL without CAS affecting parameters.
+     * Copied directly from SimpleCAS.php 0.1.0
+     * 
+     * @return string url
+     */
+    static public function getURL()
+    {
+        if (isset($_SERVER['HTTPS'])
+            && !empty($_SERVER['HTTPS'])
+            && $_SERVER['HTTPS'] == 'on') {
+            $protocol = 'https';
+        } else {
+            $protocol = 'http';
+        }
+    
+        $url = $protocol.'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
+        
+        $replacements = array('/\?logout/'        => '',
+                              '/&ticket=[^&]*/'   => '',
+                              '/\?ticket=[^&;]*/' => '?',
+                              '/\?%26/'           => '?',
+                              '/\?&/'             => '?',
+                              '/\?$/'             => '');
+        
+        $url = preg_replace(array_keys($replacements),
+                            array_values($replacements), $url);
+        
+        return $url;
+    }
+
+    /**
+     * Returns the URL to login form on the CAS server.
+     *
+     * @return string
+     */
+    public function getLoginURL()
+    {
+        return $this->_protocol->getLoginURL(self::getURL());
+    }
+ 
+}
diff --git a/lib/docs/SimpleCAS/docs/examples/simple.php b/lib/docs/SimpleCAS/docs/examples/simple.php
new file mode 100644
index 0000000..02f768b
--- /dev/null
+++ b/lib/docs/SimpleCAS/docs/examples/simple.php
@@ -0,0 +1,27 @@
+<?php
+ini_set('display_errors', true);
+chdir(dirname(dirname(dirname(__FILE__))));
+
+require_once 'SimpleCAS/Autoload.php';
+require_once 'HTTP/Request2.php';
+
+$options = array('hostname' =>'login.unl.edu',
+                 'port'     => 443,
+                 'uri'      => 'cas');
+$protocol = new SimpleCAS_Protocol_Version2($options);
+
+$protocol->getRequest()->setConfig('ssl_verify_peer', false);
+
+$client = SimpleCAS::client($protocol);
+$client->forceAuthentication();
+
+if (isset($_GET['logout'])) {
+	$client->logout();
+}
+
+if ($client->isAuthenticated()) {
+    echo '<h1>Authentication Successful!</h1>';
+    echo '<p>The user\'s login is '.$client->getUsername().'</p>';
+}
+?>
+<a href="?logout">Logout</a>
\ No newline at end of file
diff --git a/lib/docs/UNL_Auth/docs/examples/CASPEARAuth_example.php b/lib/docs/UNL_Auth/docs/examples/CASPEARAuth_example.php
new file mode 100644
index 0000000..8b24427
--- /dev/null
+++ b/lib/docs/UNL_Auth/docs/examples/CASPEARAuth_example.php
@@ -0,0 +1,26 @@
+<?php
+ini_set('display_errors', true);
+error_reporting(E_ALL);
+chdir(dirname(__FILE__).'/../../');
+require_once 'UNL/Auth.php';
+
+//$auth = UNL_Auth::PEARFactory('CAS', $options=null, $loginfunction=null, false);
+$auth = UNL_Auth::PEARFactory('CAS');
+$auth->start();
+
+if (isset($_GET['logout']) && $auth->checkAuth()) {
+    $auth->logout();
+    $auth->start();
+}
+
+if ($auth->checkAuth()) {
+    /*
+     * The output of your site goes here.
+     */
+    echo 'You are authenticated, '.$auth->getUsername().'<br />';
+    echo '<a href="?logout">Logout</a>';
+} else {
+    echo 'You need to log in bro!';
+}
+
+?>
\ No newline at end of file
diff --git a/lib/docs/UNL_Auth/docs/examples/CAS_example.php b/lib/docs/UNL_Auth/docs/examples/CAS_example.php
new file mode 100644
index 0000000..42acfc6
--- /dev/null
+++ b/lib/docs/UNL_Auth/docs/examples/CAS_example.php
@@ -0,0 +1,22 @@
+<?php
+ini_set('display_errors', true);
+error_reporting(E_ALL);
+chdir(dirname(__FILE__).'/../../');
+require_once 'UNL/Auth.php';
+
+$auth = UNL_Auth::factory('CAS');
+
+if (isset($_GET['login'])) {
+	$auth->login();
+} elseif (isset($_GET['logout'])) {
+	$auth->logout();
+}
+
+if (!$auth->isLoggedIn()) {
+    // Could call $auth->login() here to get the party started.
+	echo "You are not logged in.\n<br />\n";
+	echo '<a href="?login=true">Click here to log in!</a>';
+} else {
+	echo "You are logged in as {$auth->getUser()}<br />";
+	echo "<a href='?logout'>logout</a>";
+}
diff --git a/lib/docs/UNL_Auth/docs/examples/SimpleCAS_example.php b/lib/docs/UNL_Auth/docs/examples/SimpleCAS_example.php
new file mode 100644
index 0000000..d514e53
--- /dev/null
+++ b/lib/docs/UNL_Auth/docs/examples/SimpleCAS_example.php
@@ -0,0 +1,22 @@
+<?php
+ini_set('display_errors', true);
+error_reporting(E_ALL);
+chdir(dirname(__FILE__).'/../../');
+require_once 'UNL/Auth.php';
+
+$auth = UNL_Auth::factory('SimpleCAS');
+
+if (isset($_GET['login'])) {
+    $auth->login();
+} elseif (isset($_GET['logout'])) {
+    $auth->logout();
+}
+
+if (!$auth->isLoggedIn()) {
+    // Could call $auth->login() here to get the party started.
+    echo "You are not logged in.\n<br />\n";
+    echo '<a href="?login=true">Click here to log in!</a>';
+} else {
+    echo "You are logged in as {$auth->getUser()}<br />";
+    echo "<a href='?logout'>logout</a>";
+}
\ No newline at end of file
diff --git a/lib/docs/UNL_Auth/docs/examples/Zend_SimpleCAS_example.php b/lib/docs/UNL_Auth/docs/examples/Zend_SimpleCAS_example.php
new file mode 100644
index 0000000..adac078
--- /dev/null
+++ b/lib/docs/UNL_Auth/docs/examples/Zend_SimpleCAS_example.php
@@ -0,0 +1,26 @@
+<?php
+ini_set('display_errors', true);
+error_reporting(E_ALL);
+chdir(dirname(__FILE__).'/../../');
+require_once 'UNL/Auth.php';
+require_once 'Zend/Auth.php';
+
+$auth = Zend_Auth::getInstance();
+$authAdapter = UNL_Auth::ZendFactory('SimpleCAS');
+if (!$auth->hasIdentity()) {
+    $result = $auth->authenticate($authAdapter);
+    if (!$result->isValid()) {
+        // Authentication failed; print the reasons why
+        foreach ($result->getMessages() as $message) {
+            echo "$message\n";
+        }
+    } else {
+        // Authentication succeeded; the identity ($username) is stored
+        // in the session
+        // $result->getIdentity() === $auth->getIdentity()
+        echo 'Hello '.$result->getIdentity();
+    }
+} else {
+    echo 'Hello@';
+}
+
diff --git a/lib/downloads/HTTP_Request2-2.0.0beta3.tgz b/lib/downloads/HTTP_Request2-2.0.0beta3.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..790e40fe830bbdada2733edba199d2d0a53c55b0
GIT binary patch
literal 95266
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
V3=9km|Nk>H2s}BI!Jxy=0090Up-TV&

literal 0
HcmV?d00001

diff --git a/lib/downloads/Net_URL2-0.3.1.tgz b/lib/downloads/Net_URL2-0.3.1.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..a0abb1f560641c79d54f17fa9dcf7273be1b329d
GIT binary patch
literal 8488
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

literal 0
HcmV?d00001

diff --git a/lib/downloads/SimpleCAS-0.5.0.tgz b/lib/downloads/SimpleCAS-0.5.0.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..fef74eda21e32fe1e04758b9e59425a9e467992c
GIT binary patch
literal 7565
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

literal 0
HcmV?d00001

diff --git a/lib/downloads/UNL_Auth-0.4.0.tgz b/lib/downloads/UNL_Auth-0.4.0.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..006d5ec47141da50dad49eeaf0492e0393d7feae
GIT binary patch
literal 5633
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
T$iVRbKQluT_gXH78U_XcD%BIP

literal 0
HcmV?d00001

diff --git a/lib/php/HTTP/Request2.php b/lib/php/HTTP/Request2.php
new file mode 100644
index 0000000..97903f7
--- /dev/null
+++ b/lib/php/HTTP/Request2.php
@@ -0,0 +1,1015 @@
+<?php
+/**
+ * Class representing a HTTP request message
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Request2.php 308735 2011-02-27 20:31:28Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * A class representing an URL as per RFC 3986.
+ */
+require_once 'Net/URL2.php';
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * Class representing a HTTP request message
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @version    Release: 2.0.0beta3
+ * @link       http://tools.ietf.org/html/rfc2616#section-5
+ */
+class HTTP_Request2 implements SplSubject
+{
+   /**#@+
+    * Constants for HTTP request methods
+    *
+    * @link http://tools.ietf.org/html/rfc2616#section-5.1.1
+    */
+    const METHOD_OPTIONS = 'OPTIONS';
+    const METHOD_GET     = 'GET';
+    const METHOD_HEAD    = 'HEAD';
+    const METHOD_POST    = 'POST';
+    const METHOD_PUT     = 'PUT';
+    const METHOD_DELETE  = 'DELETE';
+    const METHOD_TRACE   = 'TRACE';
+    const METHOD_CONNECT = 'CONNECT';
+   /**#@-*/
+
+   /**#@+
+    * Constants for HTTP authentication schemes
+    *
+    * @link http://tools.ietf.org/html/rfc2617
+    */
+    const AUTH_BASIC  = 'basic';
+    const AUTH_DIGEST = 'digest';
+   /**#@-*/
+
+   /**
+    * Regular expression used to check for invalid symbols in RFC 2616 tokens
+    * @link http://pear.php.net/bugs/bug.php?id=15630
+    */
+    const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!';
+
+   /**
+    * Regular expression used to check for invalid symbols in cookie strings
+    * @link http://pear.php.net/bugs/bug.php?id=15630
+    * @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
+    */
+    const REGEXP_INVALID_COOKIE = '/[\s,;]/';
+
+   /**
+    * Fileinfo magic database resource
+    * @var  resource
+    * @see  detectMimeType()
+    */
+    private static $_fileinfoDb;
+
+   /**
+    * Observers attached to the request (instances of SplObserver)
+    * @var  array
+    */
+    protected $observers = array();
+
+   /**
+    * Request URL
+    * @var  Net_URL2
+    */
+    protected $url;
+
+   /**
+    * Request method
+    * @var  string
+    */
+    protected $method = self::METHOD_GET;
+
+   /**
+    * Authentication data
+    * @var  array
+    * @see  getAuth()
+    */
+    protected $auth;
+
+   /**
+    * Request headers
+    * @var  array
+    */
+    protected $headers = array();
+
+   /**
+    * Configuration parameters
+    * @var  array
+    * @see  setConfig()
+    */
+    protected $config = array(
+        'adapter'           => 'HTTP_Request2_Adapter_Socket',
+        'connect_timeout'   => 10,
+        'timeout'           => 0,
+        'use_brackets'      => true,
+        'protocol_version'  => '1.1',
+        'buffer_size'       => 16384,
+        'store_body'        => true,
+
+        'proxy_host'        => '',
+        'proxy_port'        => '',
+        'proxy_user'        => '',
+        'proxy_password'    => '',
+        'proxy_auth_scheme' => self::AUTH_BASIC,
+
+        'ssl_verify_peer'   => true,
+        'ssl_verify_host'   => true,
+        'ssl_cafile'        => null,
+        'ssl_capath'        => null,
+        'ssl_local_cert'    => null,
+        'ssl_passphrase'    => null,
+
+        'digest_compat_ie'  => false,
+
+        'follow_redirects'  => false,
+        'max_redirects'     => 5,
+        'strict_redirects'  => false
+    );
+
+   /**
+    * Last event in request / response handling, intended for observers
+    * @var  array
+    * @see  getLastEvent()
+    */
+    protected $lastEvent = array(
+        'name' => 'start',
+        'data' => null
+    );
+
+   /**
+    * Request body
+    * @var  string|resource
+    * @see  setBody()
+    */
+    protected $body = '';
+
+   /**
+    * Array of POST parameters
+    * @var  array
+    */
+    protected $postParams = array();
+
+   /**
+    * Array of file uploads (for multipart/form-data POST requests)
+    * @var  array
+    */
+    protected $uploads = array();
+
+   /**
+    * Adapter used to perform actual HTTP request
+    * @var  HTTP_Request2_Adapter
+    */
+    protected $adapter;
+
+   /**
+    * Cookie jar to persist cookies between requests
+    * @var HTTP_Request2_CookieJar
+    */
+    protected $cookieJar = null;
+
+   /**
+    * Constructor. Can set request URL, method and configuration array.
+    *
+    * Also sets a default value for User-Agent header.
+    *
+    * @param    string|Net_Url2     Request URL
+    * @param    string              Request method
+    * @param    array               Configuration for this Request instance
+    */
+    public function __construct($url = null, $method = self::METHOD_GET, array $config = array())
+    {
+        $this->setConfig($config);
+        if (!empty($url)) {
+            $this->setUrl($url);
+        }
+        if (!empty($method)) {
+            $this->setMethod($method);
+        }
+        $this->setHeader('user-agent', 'HTTP_Request2/2.0.0beta3 ' .
+                         '(http://pear.php.net/package/http_request2) ' .
+                         'PHP/' . phpversion());
+    }
+
+   /**
+    * Sets the URL for this request
+    *
+    * If the URL has userinfo part (username & password) these will be removed
+    * and converted to auth data. If the URL does not have a path component,
+    * that will be set to '/'.
+    *
+    * @param    string|Net_URL2 Request URL
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException
+    */
+    public function setUrl($url)
+    {
+        if (is_string($url)) {
+            $url = new Net_URL2(
+                $url, array(Net_URL2::OPTION_USE_BRACKETS => $this->config['use_brackets'])
+            );
+        }
+        if (!$url instanceof Net_URL2) {
+            throw new HTTP_Request2_LogicException(
+                'Parameter is not a valid HTTP URL',
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        // URL contains username / password?
+        if ($url->getUserinfo()) {
+            $username = $url->getUser();
+            $password = $url->getPassword();
+            $this->setAuth(rawurldecode($username), $password? rawurldecode($password): '');
+            $url->setUserinfo('');
+        }
+        if ('' == $url->getPath()) {
+            $url->setPath('/');
+        }
+        $this->url = $url;
+
+        return $this;
+    }
+
+   /**
+    * Returns the request URL
+    *
+    * @return   Net_URL2
+    */
+    public function getUrl()
+    {
+        return $this->url;
+    }
+
+   /**
+    * Sets the request method
+    *
+    * @param    string
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException if the method name is invalid
+    */
+    public function setMethod($method)
+    {
+        // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1
+        if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) {
+            throw new HTTP_Request2_LogicException(
+                "Invalid request method '{$method}'",
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        $this->method = $method;
+
+        return $this;
+    }
+
+   /**
+    * Returns the request method
+    *
+    * @return   string
+    */
+    public function getMethod()
+    {
+        return $this->method;
+    }
+
+   /**
+    * Sets the configuration parameter(s)
+    *
+    * The following parameters are available:
+    * <ul>
+    *   <li> 'adapter'           - adapter to use (string)</li>
+    *   <li> 'connect_timeout'   - Connection timeout in seconds (integer)</li>
+    *   <li> 'timeout'           - Total number of seconds a request can take.
+    *                              Use 0 for no limit, should be greater than
+    *                              'connect_timeout' if set (integer)</li>
+    *   <li> 'use_brackets'      - Whether to append [] to array variable names (bool)</li>
+    *   <li> 'protocol_version'  - HTTP Version to use, '1.0' or '1.1' (string)</li>
+    *   <li> 'buffer_size'       - Buffer size to use for reading and writing (int)</li>
+    *   <li> 'store_body'        - Whether to store response body in response object.
+    *                              Set to false if receiving a huge response and
+    *                              using an Observer to save it (boolean)</li>
+    *   <li> 'proxy_host'        - Proxy server host (string)</li>
+    *   <li> 'proxy_port'        - Proxy server port (integer)</li>
+    *   <li> 'proxy_user'        - Proxy auth username (string)</li>
+    *   <li> 'proxy_password'    - Proxy auth password (string)</li>
+    *   <li> 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)</li>
+    *   <li> 'ssl_verify_peer'   - Whether to verify peer's SSL certificate (bool)</li>
+    *   <li> 'ssl_verify_host'   - Whether to check that Common Name in SSL
+    *                              certificate matches host name (bool)</li>
+    *   <li> 'ssl_cafile'        - Cerificate Authority file to verify the peer
+    *                              with (use with 'ssl_verify_peer') (string)</li>
+    *   <li> 'ssl_capath'        - Directory holding multiple Certificate
+    *                              Authority files (string)</li>
+    *   <li> 'ssl_local_cert'    - Name of a file containing local cerificate (string)</li>
+    *   <li> 'ssl_passphrase'    - Passphrase with which local certificate
+    *                              was encoded (string)</li>
+    *   <li> 'digest_compat_ie'  - Whether to imitate behaviour of MSIE 5 and 6
+    *                              in using URL without query string in digest
+    *                              authentication (boolean)</li>
+    *   <li> 'follow_redirects'  - Whether to automatically follow HTTP Redirects (boolean)</li>
+    *   <li> 'max_redirects'     - Maximum number of redirects to follow (integer)</li>
+    *   <li> 'strict_redirects'  - Whether to keep request method on redirects via status 301 and
+    *                              302 (true, needed for compatibility with RFC 2616)
+    *                              or switch to GET (false, needed for compatibility with most
+    *                              browsers) (boolean)</li>
+    * </ul>
+    *
+    * @param    string|array    configuration parameter name or array
+    *                           ('parameter name' => 'parameter value')
+    * @param    mixed           parameter value if $nameOrConfig is not an array
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException If the parameter is unknown
+    */
+    public function setConfig($nameOrConfig, $value = null)
+    {
+        if (is_array($nameOrConfig)) {
+            foreach ($nameOrConfig as $name => $value) {
+                $this->setConfig($name, $value);
+            }
+
+        } else {
+            if (!array_key_exists($nameOrConfig, $this->config)) {
+                throw new HTTP_Request2_LogicException(
+                    "Unknown configuration parameter '{$nameOrConfig}'",
+                    HTTP_Request2_Exception::INVALID_ARGUMENT
+                );
+            }
+            $this->config[$nameOrConfig] = $value;
+        }
+
+        return $this;
+    }
+
+   /**
+    * Returns the value(s) of the configuration parameter(s)
+    *
+    * @param    string  parameter name
+    * @return   mixed   value of $name parameter, array of all configuration
+    *                   parameters if $name is not given
+    * @throws   HTTP_Request2_LogicException If the parameter is unknown
+    */
+    public function getConfig($name = null)
+    {
+        if (null === $name) {
+            return $this->config;
+        } elseif (!array_key_exists($name, $this->config)) {
+            throw new HTTP_Request2_LogicException(
+                "Unknown configuration parameter '{$name}'",
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        return $this->config[$name];
+    }
+
+   /**
+    * Sets the autentification data
+    *
+    * @param    string  user name
+    * @param    string  password
+    * @param    string  authentication scheme
+    * @return   HTTP_Request2
+    */
+    public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC)
+    {
+        if (empty($user)) {
+            $this->auth = null;
+        } else {
+            $this->auth = array(
+                'user'     => (string)$user,
+                'password' => (string)$password,
+                'scheme'   => $scheme
+            );
+        }
+
+        return $this;
+    }
+
+   /**
+    * Returns the authentication data
+    *
+    * The array has the keys 'user', 'password' and 'scheme', where 'scheme'
+    * is one of the HTTP_Request2::AUTH_* constants.
+    *
+    * @return   array
+    */
+    public function getAuth()
+    {
+        return $this->auth;
+    }
+
+   /**
+    * Sets request header(s)
+    *
+    * The first parameter may be either a full header string 'header: value' or
+    * header name. In the former case $value parameter is ignored, in the latter
+    * the header's value will either be set to $value or the header will be
+    * removed if $value is null. The first parameter can also be an array of
+    * headers, in that case method will be called recursively.
+    *
+    * Note that headers are treated case insensitively as per RFC 2616.
+    *
+    * <code>
+    * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar'
+    * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz'
+    * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux'
+    * $req->setHeader('FOO'); // removes 'Foo' header from request
+    * </code>
+    *
+    * @param    string|array    header name, header string ('Header: value')
+    *                           or an array of headers
+    * @param    string|array|null header value if $name is not an array,
+    *                           header will be removed if value is null
+    * @param    bool            whether to replace previous header with the
+    *                           same name or append to its value
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException
+    */
+    public function setHeader($name, $value = null, $replace = true)
+    {
+        if (is_array($name)) {
+            foreach ($name as $k => $v) {
+                if (is_string($k)) {
+                    $this->setHeader($k, $v, $replace);
+                } else {
+                    $this->setHeader($v, null, $replace);
+                }
+            }
+        } else {
+            if (null === $value && strpos($name, ':')) {
+                list($name, $value) = array_map('trim', explode(':', $name, 2));
+            }
+            // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2
+            if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) {
+                throw new HTTP_Request2_LogicException(
+                    "Invalid header name '{$name}'",
+                    HTTP_Request2_Exception::INVALID_ARGUMENT
+                );
+            }
+            // Header names are case insensitive anyway
+            $name = strtolower($name);
+            if (null === $value) {
+                unset($this->headers[$name]);
+
+            } else {
+                if (is_array($value)) {
+                    $value = implode(', ', array_map('trim', $value));
+                } elseif (is_string($value)) {
+                    $value = trim($value);
+                }
+                if (!isset($this->headers[$name]) || $replace) {
+                    $this->headers[$name] = $value;
+                } else {
+                    $this->headers[$name] .= ', ' . $value;
+                }
+            }
+        }
+
+        return $this;
+    }
+
+   /**
+    * Returns the request headers
+    *
+    * The array is of the form ('header name' => 'header value'), header names
+    * are lowercased
+    *
+    * @return   array
+    */
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+
+   /**
+    * Adds a cookie to the request
+    *
+    * If the request does not have a CookieJar object set, this method simply
+    * appends a cookie to "Cookie:" header.
+    *
+    * If a CookieJar object is available, the cookie is stored in that object.
+    * Data from request URL will be used for setting its 'domain' and 'path'
+    * parameters, 'expires' and 'secure' will be set to null and false,
+    * respectively. If you need further control, use CookieJar's methods.
+    *
+    * @param    string  cookie name
+    * @param    string  cookie value
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException
+    * @see      setCookieJar()
+    */
+    public function addCookie($name, $value)
+    {
+        if (!empty($this->cookieJar)) {
+            $this->cookieJar->store(array('name' => $name, 'value' => $value),
+                                    $this->url);
+
+        } else {
+            $cookie = $name . '=' . $value;
+            if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
+                throw new HTTP_Request2_LogicException(
+                    "Invalid cookie: '{$cookie}'",
+                    HTTP_Request2_Exception::INVALID_ARGUMENT
+                );
+            }
+            $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
+            $this->setHeader('cookie', $cookies . $cookie);
+        }
+
+        return $this;
+    }
+
+   /**
+    * Sets the request body
+    *
+    * If you provide file pointer rather than file name, it should support
+    * fstat() and rewind() operations.
+    *
+    * @param    string|resource|HTTP_Request2_MultipartBody  Either a string
+    *               with the body or filename containing body or pointer to
+    *               an open file or object with multipart body data
+    * @param    bool    Whether first parameter is a filename
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException
+    */
+    public function setBody($body, $isFilename = false)
+    {
+        if (!$isFilename && !is_resource($body)) {
+            if (!$body instanceof HTTP_Request2_MultipartBody) {
+                $this->body = (string)$body;
+            } else {
+                $this->body = $body;
+            }
+        } else {
+            $fileData = $this->fopenWrapper($body, empty($this->headers['content-type']));
+            $this->body = $fileData['fp'];
+            if (empty($this->headers['content-type'])) {
+                $this->setHeader('content-type', $fileData['type']);
+            }
+        }
+        $this->postParams = $this->uploads = array();
+
+        return $this;
+    }
+
+   /**
+    * Returns the request body
+    *
+    * @return   string|resource|HTTP_Request2_MultipartBody
+    */
+    public function getBody()
+    {
+        if (self::METHOD_POST == $this->method &&
+            (!empty($this->postParams) || !empty($this->uploads))
+        ) {
+            if (0 === strpos($this->headers['content-type'], 'application/x-www-form-urlencoded')) {
+                $body = http_build_query($this->postParams, '', '&');
+                if (!$this->getConfig('use_brackets')) {
+                    $body = preg_replace('/%5B\d+%5D=/', '=', $body);
+                }
+                // support RFC 3986 by not encoding '~' symbol (request #15368)
+                return str_replace('%7E', '~', $body);
+
+            } elseif (0 === strpos($this->headers['content-type'], 'multipart/form-data')) {
+                require_once 'HTTP/Request2/MultipartBody.php';
+                return new HTTP_Request2_MultipartBody(
+                    $this->postParams, $this->uploads, $this->getConfig('use_brackets')
+                );
+            }
+        }
+        return $this->body;
+    }
+
+   /**
+    * Adds a file to form-based file upload
+    *
+    * Used to emulate file upload via a HTML form. The method also sets
+    * Content-Type of HTTP request to 'multipart/form-data'.
+    *
+    * If you just want to send the contents of a file as the body of HTTP
+    * request you should use setBody() method.
+    *
+    * If you provide file pointers rather than file names, they should support
+    * fstat() and rewind() operations.
+    *
+    * @param    string  name of file-upload field
+    * @param    string|resource|array   full name of local file, pointer to
+    *               open file or an array of files
+    * @param    string  filename to send in the request
+    * @param    string  content-type of file being uploaded
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException
+    */
+    public function addUpload($fieldName, $filename, $sendFilename = null,
+                              $contentType = null)
+    {
+        if (!is_array($filename)) {
+            $fileData = $this->fopenWrapper($filename, empty($contentType));
+            $this->uploads[$fieldName] = array(
+                'fp'        => $fileData['fp'],
+                'filename'  => !empty($sendFilename)? $sendFilename
+                                :(is_string($filename)? basename($filename): 'anonymous.blob') ,
+                'size'      => $fileData['size'],
+                'type'      => empty($contentType)? $fileData['type']: $contentType
+            );
+        } else {
+            $fps = $names = $sizes = $types = array();
+            foreach ($filename as $f) {
+                if (!is_array($f)) {
+                    $f = array($f);
+                }
+                $fileData = $this->fopenWrapper($f[0], empty($f[2]));
+                $fps[]   = $fileData['fp'];
+                $names[] = !empty($f[1])? $f[1]
+                            :(is_string($f[0])? basename($f[0]): 'anonymous.blob');
+                $sizes[] = $fileData['size'];
+                $types[] = empty($f[2])? $fileData['type']: $f[2];
+            }
+            $this->uploads[$fieldName] = array(
+                'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types
+            );
+        }
+        if (empty($this->headers['content-type']) ||
+            'application/x-www-form-urlencoded' == $this->headers['content-type']
+        ) {
+            $this->setHeader('content-type', 'multipart/form-data');
+        }
+
+        return $this;
+    }
+
+   /**
+    * Adds POST parameter(s) to the request.
+    *
+    * @param    string|array    parameter name or array ('name' => 'value')
+    * @param    mixed           parameter value (can be an array)
+    * @return   HTTP_Request2
+    */
+    public function addPostParameter($name, $value = null)
+    {
+        if (!is_array($name)) {
+            $this->postParams[$name] = $value;
+        } else {
+            foreach ($name as $k => $v) {
+                $this->addPostParameter($k, $v);
+            }
+        }
+        if (empty($this->headers['content-type'])) {
+            $this->setHeader('content-type', 'application/x-www-form-urlencoded');
+        }
+
+        return $this;
+    }
+
+   /**
+    * Attaches a new observer
+    *
+    * @param    SplObserver
+    */
+    public function attach(SplObserver $observer)
+    {
+        foreach ($this->observers as $attached) {
+            if ($attached === $observer) {
+                return;
+            }
+        }
+        $this->observers[] = $observer;
+    }
+
+   /**
+    * Detaches an existing observer
+    *
+    * @param    SplObserver
+    */
+    public function detach(SplObserver $observer)
+    {
+        foreach ($this->observers as $key => $attached) {
+            if ($attached === $observer) {
+                unset($this->observers[$key]);
+                return;
+            }
+        }
+    }
+
+   /**
+    * Notifies all observers
+    */
+    public function notify()
+    {
+        foreach ($this->observers as $observer) {
+            $observer->update($this);
+        }
+    }
+
+   /**
+    * Sets the last event
+    *
+    * Adapters should use this method to set the current state of the request
+    * and notify the observers.
+    *
+    * @param    string  event name
+    * @param    mixed   event data
+    */
+    public function setLastEvent($name, $data = null)
+    {
+        $this->lastEvent = array(
+            'name' => $name,
+            'data' => $data
+        );
+        $this->notify();
+    }
+
+   /**
+    * Returns the last event
+    *
+    * Observers should use this method to access the last change in request.
+    * The following event names are possible:
+    * <ul>
+    *   <li>'connect'                 - after connection to remote server,
+    *                                   data is the destination (string)</li>
+    *   <li>'disconnect'              - after disconnection from server</li>
+    *   <li>'sentHeaders'             - after sending the request headers,
+    *                                   data is the headers sent (string)</li>
+    *   <li>'sentBodyPart'            - after sending a part of the request body,
+    *                                   data is the length of that part (int)</li>
+    *   <li>'sentBody'                - after sending the whole request body,
+    *                                   data is request body length (int)</li>
+    *   <li>'receivedHeaders'         - after receiving the response headers,
+    *                                   data is HTTP_Request2_Response object</li>
+    *   <li>'receivedBodyPart'        - after receiving a part of the response
+    *                                   body, data is that part (string)</li>
+    *   <li>'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still
+    *                                   encoded by Content-Encoding</li>
+    *   <li>'receivedBody'            - after receiving the complete response
+    *                                   body, data is HTTP_Request2_Response object</li>
+    * </ul>
+    * Different adapters may not send all the event types. Mock adapter does
+    * not send any events to the observers.
+    *
+    * @return   array   The array has two keys: 'name' and 'data'
+    */
+    public function getLastEvent()
+    {
+        return $this->lastEvent;
+    }
+
+   /**
+    * Sets the adapter used to actually perform the request
+    *
+    * You can pass either an instance of a class implementing HTTP_Request2_Adapter
+    * or a class name. The method will only try to include a file if the class
+    * name starts with HTTP_Request2_Adapter_, it will also try to prepend this
+    * prefix to the class name if it doesn't contain any underscores, so that
+    * <code>
+    * $request->setAdapter('curl');
+    * </code>
+    * will work.
+    *
+    * @param    string|HTTP_Request2_Adapter
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_LogicException
+    */
+    public function setAdapter($adapter)
+    {
+        if (is_string($adapter)) {
+            if (!class_exists($adapter, false)) {
+                if (false === strpos($adapter, '_')) {
+                    $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter);
+                }
+                if (preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter)) {
+                    include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php';
+                }
+                if (!class_exists($adapter, false)) {
+                    throw new HTTP_Request2_LogicException(
+                        "Class {$adapter} not found",
+                        HTTP_Request2_Exception::MISSING_VALUE
+                    );
+                }
+            }
+            $adapter = new $adapter;
+        }
+        if (!$adapter instanceof HTTP_Request2_Adapter) {
+            throw new HTTP_Request2_LogicException(
+                'Parameter is not a HTTP request adapter',
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        $this->adapter = $adapter;
+
+        return $this;
+    }
+
+   /**
+    * Sets the cookie jar
+    *
+    * A cookie jar is used to maintain cookies across HTTP requests and
+    * responses. Cookies from jar will be automatically added to the request
+    * headers based on request URL.
+    *
+    * @param HTTP_Request2_CookieJar|bool   Existing CookieJar object, true to
+    *                                       create a new one, false to remove
+    */
+    public function setCookieJar($jar = true)
+    {
+        if (!class_exists('HTTP_Request2_CookieJar', false)) {
+            require_once 'HTTP/Request2/CookieJar.php';
+        }
+
+        if ($jar instanceof HTTP_Request2_CookieJar) {
+            $this->cookieJar = $jar;
+        } elseif (true === $jar) {
+            $this->cookieJar = new HTTP_Request2_CookieJar();
+        } elseif (!$jar) {
+            $this->cookieJar = null;
+        } else {
+            throw new HTTP_Request2_LogicException(
+                'Invalid parameter passed to setCookieJar()',
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+
+        return $this;
+    }
+
+   /**
+    * Returns current CookieJar object or null if none
+    *
+    * @return HTTP_Request2_CookieJar|null
+    */
+    public function getCookieJar()
+    {
+        return $this->cookieJar;
+    }
+
+   /**
+    * Sends the request and returns the response
+    *
+    * @throws   HTTP_Request2_Exception
+    * @return   HTTP_Request2_Response
+    */
+    public function send()
+    {
+        // Sanity check for URL
+        if (!$this->url instanceof Net_URL2
+            || !$this->url->isAbsolute()
+            || !in_array(strtolower($this->url->getScheme()), array('https', 'http'))
+        ) {
+            throw new HTTP_Request2_LogicException(
+                'HTTP_Request2 needs an absolute HTTP(S) request URL, '
+                . ($this->url instanceof Net_URL2
+                   ? 'none' : "'" . $this->url->__toString() . "'")
+                . ' given',
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        if (empty($this->adapter)) {
+            $this->setAdapter($this->getConfig('adapter'));
+        }
+        // magic_quotes_runtime may break file uploads and chunked response
+        // processing; see bug #4543. Don't use ini_get() here; see bug #16440.
+        if ($magicQuotes = get_magic_quotes_runtime()) {
+            set_magic_quotes_runtime(false);
+        }
+        // force using single byte encoding if mbstring extension overloads
+        // strlen() and substr(); see bug #1781, bug #10605
+        if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
+            $oldEncoding = mb_internal_encoding();
+            mb_internal_encoding('iso-8859-1');
+        }
+
+        try {
+            $response = $this->adapter->sendRequest($this);
+        } catch (Exception $e) {
+        }
+        // cleanup in either case (poor man's "finally" clause)
+        if ($magicQuotes) {
+            set_magic_quotes_runtime(true);
+        }
+        if (!empty($oldEncoding)) {
+            mb_internal_encoding($oldEncoding);
+        }
+        // rethrow the exception
+        if (!empty($e)) {
+            throw $e;
+        }
+        return $response;
+    }
+
+   /**
+    * Wrapper around fopen()/fstat() used by setBody() and addUpload()
+    *
+    * @param  string|resource file name or pointer to open file
+    * @param  bool            whether to try autodetecting MIME type of file,
+    *                         will only work if $file is a filename, not pointer
+    * @return array array('fp' => file pointer, 'size' => file size, 'type' => MIME type)
+    * @throws HTTP_Request2_LogicException
+    */
+    protected function fopenWrapper($file, $detectType = false)
+    {
+        if (!is_string($file) && !is_resource($file)) {
+            throw new HTTP_Request2_LogicException(
+                "Filename or file pointer resource expected",
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        $fileData = array(
+            'fp'   => is_string($file)? null: $file,
+            'type' => 'application/octet-stream',
+            'size' => 0
+        );
+        if (is_string($file)) {
+            $track = @ini_set('track_errors', 1);
+            if (!($fileData['fp'] = @fopen($file, 'rb'))) {
+                $e = new HTTP_Request2_LogicException(
+                    $php_errormsg, HTTP_Request2_Exception::READ_ERROR
+                );
+            }
+            @ini_set('track_errors', $track);
+            if (isset($e)) {
+                throw $e;
+            }
+            if ($detectType) {
+                $fileData['type'] = self::detectMimeType($file);
+            }
+        }
+        if (!($stat = fstat($fileData['fp']))) {
+            throw new HTTP_Request2_LogicException(
+                "fstat() call failed", HTTP_Request2_Exception::READ_ERROR
+            );
+        }
+        $fileData['size'] = $stat['size'];
+
+        return $fileData;
+    }
+
+   /**
+    * Tries to detect MIME type of a file
+    *
+    * The method will try to use fileinfo extension if it is available,
+    * deprecated mime_content_type() function in the other case. If neither
+    * works, default 'application/octet-stream' MIME type is returned
+    *
+    * @param    string  filename
+    * @return   string  file MIME type
+    */
+    protected static function detectMimeType($filename)
+    {
+        // finfo extension from PECL available
+        if (function_exists('finfo_open')) {
+            if (!isset(self::$_fileinfoDb)) {
+                self::$_fileinfoDb = @finfo_open(FILEINFO_MIME);
+            }
+            if (self::$_fileinfoDb) {
+                $info = finfo_file(self::$_fileinfoDb, $filename);
+            }
+        }
+        // (deprecated) mime_content_type function available
+        if (empty($info) && function_exists('mime_content_type')) {
+            return mime_content_type($filename);
+        }
+        return empty($info)? 'application/octet-stream': $info;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/HTTP/Request2/Adapter.php b/lib/php/HTTP/Request2/Adapter.php
new file mode 100644
index 0000000..ca25abf
--- /dev/null
+++ b/lib/php/HTTP/Request2/Adapter.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Base class for HTTP_Request2 adapters
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Adapter.php 308322 2011-02-14 13:58:03Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP response
+ */
+require_once 'HTTP/Request2/Response.php';
+
+/**
+ * Base class for HTTP_Request2 adapters
+ *
+ * HTTP_Request2 class itself only defines methods for aggregating the request
+ * data, all actual work of sending the request to the remote server and
+ * receiving its response is performed by adapters.
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @version    Release: 2.0.0beta3
+ */
+abstract class HTTP_Request2_Adapter
+{
+   /**
+    * A list of methods that MUST NOT have a request body, per RFC 2616
+    * @var  array
+    */
+    protected static $bodyDisallowed = array('TRACE');
+
+   /**
+    * Methods having defined semantics for request body
+    *
+    * Content-Length header (indicating that the body follows, section 4.3 of
+    * RFC 2616) will be sent for these methods even if no body was added
+    *
+    * @var  array
+    * @link http://pear.php.net/bugs/bug.php?id=12900
+    * @link http://pear.php.net/bugs/bug.php?id=14740
+    */
+    protected static $bodyRequired = array('POST', 'PUT');
+
+   /**
+    * Request being sent
+    * @var  HTTP_Request2
+    */
+    protected $request;
+
+   /**
+    * Request body
+    * @var  string|resource|HTTP_Request2_MultipartBody
+    * @see  HTTP_Request2::getBody()
+    */
+    protected $requestBody;
+
+   /**
+    * Length of the request body
+    * @var  integer
+    */
+    protected $contentLength;
+
+   /**
+    * Sends request to the remote server and returns its response
+    *
+    * @param    HTTP_Request2
+    * @return   HTTP_Request2_Response
+    * @throws   HTTP_Request2_Exception
+    */
+    abstract public function sendRequest(HTTP_Request2 $request);
+
+   /**
+    * Calculates length of the request body, adds proper headers
+    *
+    * @param    array   associative array of request headers, this method will
+    *                   add proper 'Content-Length' and 'Content-Type' headers
+    *                   to this array (or remove them if not needed)
+    */
+    protected function calculateRequestLength(&$headers)
+    {
+        $this->requestBody = $this->request->getBody();
+
+        if (is_string($this->requestBody)) {
+            $this->contentLength = strlen($this->requestBody);
+        } elseif (is_resource($this->requestBody)) {
+            $stat = fstat($this->requestBody);
+            $this->contentLength = $stat['size'];
+            rewind($this->requestBody);
+        } else {
+            $this->contentLength = $this->requestBody->getLength();
+            $headers['content-type'] = 'multipart/form-data; boundary=' .
+                                       $this->requestBody->getBoundary();
+            $this->requestBody->rewind();
+        }
+
+        if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+            0 == $this->contentLength
+        ) {
+            // No body: send a Content-Length header nonetheless (request #12900),
+            // but do that only for methods that require a body (bug #14740)
+            if (in_array($this->request->getMethod(), self::$bodyRequired)) {
+                $headers['content-length'] = 0;
+            } else {
+                unset($headers['content-length']);
+                // if the method doesn't require a body and doesn't have a
+                // body, don't send a Content-Type header. (request #16799)
+                unset($headers['content-type']);
+            }
+        } else {
+            if (empty($headers['content-type'])) {
+                $headers['content-type'] = 'application/x-www-form-urlencoded';
+            }
+            $headers['content-length'] = $this->contentLength;
+        }
+    }
+}
+?>
diff --git a/lib/php/HTTP/Request2/Adapter/Curl.php b/lib/php/HTTP/Request2/Adapter/Curl.php
new file mode 100644
index 0000000..eeec8cb
--- /dev/null
+++ b/lib/php/HTTP/Request2/Adapter/Curl.php
@@ -0,0 +1,562 @@
+<?php
+/**
+ * Adapter for HTTP_Request2 wrapping around cURL extension
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Curl.php 309921 2011-04-03 16:43:02Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Adapter for HTTP_Request2 wrapping around cURL extension
+ *
+ * @category    HTTP
+ * @package     HTTP_Request2
+ * @author      Alexey Borzov <avb@php.net>
+ * @version     Release: 2.0.0beta3
+ */
+class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
+{
+   /**
+    * Mapping of header names to cURL options
+    * @var  array
+    */
+    protected static $headerMap = array(
+        'accept-encoding' => CURLOPT_ENCODING,
+        'cookie'          => CURLOPT_COOKIE,
+        'referer'         => CURLOPT_REFERER,
+        'user-agent'      => CURLOPT_USERAGENT
+    );
+
+   /**
+    * Mapping of SSL context options to cURL options
+    * @var  array
+    */
+    protected static $sslContextMap = array(
+        'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
+        'ssl_cafile'      => CURLOPT_CAINFO,
+        'ssl_capath'      => CURLOPT_CAPATH,
+        'ssl_local_cert'  => CURLOPT_SSLCERT,
+        'ssl_passphrase'  => CURLOPT_SSLCERTPASSWD
+   );
+
+   /**
+    * Mapping of CURLE_* constants to Exception subclasses and error codes
+    * @var  array
+    */
+    protected static $errorMap = array(
+        CURLE_UNSUPPORTED_PROTOCOL  => array('HTTP_Request2_MessageException',
+                                             HTTP_Request2_Exception::NON_HTTP_REDIRECT),
+        CURLE_COULDNT_RESOLVE_PROXY => array('HTTP_Request2_ConnectionException'),
+        CURLE_COULDNT_RESOLVE_HOST  => array('HTTP_Request2_ConnectionException'),
+        CURLE_COULDNT_CONNECT       => array('HTTP_Request2_ConnectionException'),
+        // error returned from write callback
+        CURLE_WRITE_ERROR           => array('HTTP_Request2_MessageException',
+                                             HTTP_Request2_Exception::NON_HTTP_REDIRECT),
+        CURLE_OPERATION_TIMEOUTED   => array('HTTP_Request2_MessageException',
+                                             HTTP_Request2_Exception::TIMEOUT),
+        CURLE_HTTP_RANGE_ERROR      => array('HTTP_Request2_MessageException'),
+        CURLE_SSL_CONNECT_ERROR     => array('HTTP_Request2_ConnectionException'),
+        CURLE_LIBRARY_NOT_FOUND     => array('HTTP_Request2_LogicException',
+                                             HTTP_Request2_Exception::MISCONFIGURATION),
+        CURLE_FUNCTION_NOT_FOUND    => array('HTTP_Request2_LogicException',
+                                             HTTP_Request2_Exception::MISCONFIGURATION),
+        CURLE_ABORTED_BY_CALLBACK   => array('HTTP_Request2_MessageException',
+                                             HTTP_Request2_Exception::NON_HTTP_REDIRECT),
+        CURLE_TOO_MANY_REDIRECTS    => array('HTTP_Request2_MessageException',
+                                             HTTP_Request2_Exception::TOO_MANY_REDIRECTS),
+        CURLE_SSL_PEER_CERTIFICATE  => array('HTTP_Request2_ConnectionException'),
+        CURLE_GOT_NOTHING           => array('HTTP_Request2_MessageException'),
+        CURLE_SSL_ENGINE_NOTFOUND   => array('HTTP_Request2_LogicException',
+                                             HTTP_Request2_Exception::MISCONFIGURATION),
+        CURLE_SSL_ENGINE_SETFAILED  => array('HTTP_Request2_LogicException',
+                                             HTTP_Request2_Exception::MISCONFIGURATION),
+        CURLE_SEND_ERROR            => array('HTTP_Request2_MessageException'),
+        CURLE_RECV_ERROR            => array('HTTP_Request2_MessageException'),
+        CURLE_SSL_CERTPROBLEM       => array('HTTP_Request2_LogicException',
+                                             HTTP_Request2_Exception::INVALID_ARGUMENT),
+        CURLE_SSL_CIPHER            => array('HTTP_Request2_ConnectionException'),
+        CURLE_SSL_CACERT            => array('HTTP_Request2_ConnectionException'),
+        CURLE_BAD_CONTENT_ENCODING  => array('HTTP_Request2_MessageException'),
+    );
+
+   /**
+    * Response being received
+    * @var  HTTP_Request2_Response
+    */
+    protected $response;
+
+   /**
+    * Whether 'sentHeaders' event was sent to observers
+    * @var  boolean
+    */
+    protected $eventSentHeaders = false;
+
+   /**
+    * Whether 'receivedHeaders' event was sent to observers
+    * @var boolean
+    */
+    protected $eventReceivedHeaders = false;
+
+   /**
+    * Position within request body
+    * @var  integer
+    * @see  callbackReadBody()
+    */
+    protected $position = 0;
+
+   /**
+    * Information about last transfer, as returned by curl_getinfo()
+    * @var  array
+    */
+    protected $lastInfo;
+
+   /**
+    * Creates a subclass of HTTP_Request2_Exception from curl error data
+    *
+    * @param resource curl handle
+    * @return HTTP_Request2_Exception
+    */
+    protected static function wrapCurlError($ch)
+    {
+        $nativeCode = curl_errno($ch);
+        $message    = 'Curl error: ' . curl_error($ch);
+        if (!isset(self::$errorMap[$nativeCode])) {
+            return new HTTP_Request2_Exception($message, 0, $nativeCode);
+        } else {
+            $class = self::$errorMap[$nativeCode][0];
+            $code  = empty(self::$errorMap[$nativeCode][1])
+                     ? 0 : self::$errorMap[$nativeCode][1];
+            return new $class($message, $code, $nativeCode);
+        }
+    }
+
+   /**
+    * Sends request to the remote server and returns its response
+    *
+    * @param    HTTP_Request2
+    * @return   HTTP_Request2_Response
+    * @throws   HTTP_Request2_Exception
+    */
+    public function sendRequest(HTTP_Request2 $request)
+    {
+        if (!extension_loaded('curl')) {
+            throw new HTTP_Request2_LogicException(
+                'cURL extension not available', HTTP_Request2_Exception::MISCONFIGURATION
+            );
+        }
+
+        $this->request              = $request;
+        $this->response             = null;
+        $this->position             = 0;
+        $this->eventSentHeaders     = false;
+        $this->eventReceivedHeaders = false;
+
+        try {
+            if (false === curl_exec($ch = $this->createCurlHandle())) {
+                $e = self::wrapCurlError($ch);
+            }
+        } catch (Exception $e) {
+        }
+        if (isset($ch)) {
+            $this->lastInfo = curl_getinfo($ch);
+            curl_close($ch);
+        }
+
+        $response = $this->response;
+        unset($this->request, $this->requestBody, $this->response);
+
+        if (!empty($e)) {
+            throw $e;
+        }
+
+        if ($jar = $request->getCookieJar()) {
+            $jar->addCookiesFromResponse($response, $request->getUrl());
+        }
+
+        if (0 < $this->lastInfo['size_download']) {
+            $request->setLastEvent('receivedBody', $response);
+        }
+        return $response;
+    }
+
+   /**
+    * Returns information about last transfer
+    *
+    * @return   array   associative array as returned by curl_getinfo()
+    */
+    public function getInfo()
+    {
+        return $this->lastInfo;
+    }
+
+   /**
+    * Creates a new cURL handle and populates it with data from the request
+    *
+    * @return   resource    a cURL handle, as created by curl_init()
+    * @throws   HTTP_Request2_LogicException
+    */
+    protected function createCurlHandle()
+    {
+        $ch = curl_init();
+
+        curl_setopt_array($ch, array(
+            // setup write callbacks
+            CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
+            CURLOPT_WRITEFUNCTION  => array($this, 'callbackWriteBody'),
+            // buffer size
+            CURLOPT_BUFFERSIZE     => $this->request->getConfig('buffer_size'),
+            // connection timeout
+            CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
+            // save full outgoing headers, in case someone is interested
+            CURLINFO_HEADER_OUT    => true,
+            // request url
+            CURLOPT_URL            => $this->request->getUrl()->getUrl()
+        ));
+
+        // set up redirects
+        if (!$this->request->getConfig('follow_redirects')) {
+            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
+        } else {
+            if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)) {
+                throw new HTTP_Request2_LogicException(
+                    'Redirect support in curl is unavailable due to open_basedir or safe_mode setting',
+                    HTTP_Request2_Exception::MISCONFIGURATION
+                );
+            }
+            curl_setopt($ch, CURLOPT_MAXREDIRS, $this->request->getConfig('max_redirects'));
+            // limit redirects to http(s), works in 5.2.10+
+            if (defined('CURLOPT_REDIR_PROTOCOLS')) {
+                curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+            }
+            // works in 5.3.2+, http://bugs.php.net/bug.php?id=49571
+            if ($this->request->getConfig('strict_redirects') && defined('CURLOPT_POSTREDIR')) {
+                curl_setopt($ch, CURLOPT_POSTREDIR, 3);
+            }
+        }
+
+        // request timeout
+        if ($timeout = $this->request->getConfig('timeout')) {
+            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+        }
+
+        // set HTTP version
+        switch ($this->request->getConfig('protocol_version')) {
+            case '1.0':
+                curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+                break;
+            case '1.1':
+                curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+        }
+
+        // set request method
+        switch ($this->request->getMethod()) {
+            case HTTP_Request2::METHOD_GET:
+                curl_setopt($ch, CURLOPT_HTTPGET, true);
+                break;
+            case HTTP_Request2::METHOD_POST:
+                curl_setopt($ch, CURLOPT_POST, true);
+                break;
+            case HTTP_Request2::METHOD_HEAD:
+                curl_setopt($ch, CURLOPT_NOBODY, true);
+                break;
+            case HTTP_Request2::METHOD_PUT:
+                curl_setopt($ch, CURLOPT_UPLOAD, true);
+                break;
+            default:
+                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
+        }
+
+        // set proxy, if needed
+        if ($host = $this->request->getConfig('proxy_host')) {
+            if (!($port = $this->request->getConfig('proxy_port'))) {
+                throw new HTTP_Request2_LogicException(
+                    'Proxy port not provided', HTTP_Request2_Exception::MISSING_VALUE
+                );
+            }
+            curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
+            if ($user = $this->request->getConfig('proxy_user')) {
+                curl_setopt($ch, CURLOPT_PROXYUSERPWD, $user . ':' .
+                            $this->request->getConfig('proxy_password'));
+                switch ($this->request->getConfig('proxy_auth_scheme')) {
+                    case HTTP_Request2::AUTH_BASIC:
+                        curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+                        break;
+                    case HTTP_Request2::AUTH_DIGEST:
+                        curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
+                }
+            }
+        }
+
+        // set authentication data
+        if ($auth = $this->request->getAuth()) {
+            curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
+            switch ($auth['scheme']) {
+                case HTTP_Request2::AUTH_BASIC:
+                    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+                    break;
+                case HTTP_Request2::AUTH_DIGEST:
+                    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+            }
+        }
+
+        // set SSL options
+        if (0 == strcasecmp($this->request->getUrl()->getScheme(), 'https')) {
+            foreach ($this->request->getConfig() as $name => $value) {
+                if ('ssl_verify_host' == $name && null !== $value) {
+                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
+                } elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
+                    curl_setopt($ch, self::$sslContextMap[$name], $value);
+                }
+            }
+        }
+
+        $headers = $this->request->getHeaders();
+        // make cURL automagically send proper header
+        if (!isset($headers['accept-encoding'])) {
+            $headers['accept-encoding'] = '';
+        }
+
+        if (($jar = $this->request->getCookieJar())
+            && ($cookies = $jar->getMatching($this->request->getUrl(), true))
+        ) {
+            $headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies;
+        }
+
+        // set headers having special cURL keys
+        foreach (self::$headerMap as $name => $option) {
+            if (isset($headers[$name])) {
+                curl_setopt($ch, $option, $headers[$name]);
+                unset($headers[$name]);
+            }
+        }
+
+        $this->calculateRequestLength($headers);
+        if (isset($headers['content-length'])) {
+            $this->workaroundPhpBug47204($ch, $headers);
+        }
+
+        // set headers not having special keys
+        $headersFmt = array();
+        foreach ($headers as $name => $value) {
+            $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+            $headersFmt[]  = $canonicalName . ': ' . $value;
+        }
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
+
+        return $ch;
+    }
+
+   /**
+    * Workaround for PHP bug #47204 that prevents rewinding request body
+    *
+    * The workaround consists of reading the entire request body into memory
+    * and setting it as CURLOPT_POSTFIELDS, so it isn't recommended for large
+    * file uploads, use Socket adapter instead.
+    *
+    * @param    resource    cURL handle
+    * @param    array       Request headers
+    */
+    protected function workaroundPhpBug47204($ch, &$headers)
+    {
+        // no redirects, no digest auth -> probably no rewind needed
+        if (!$this->request->getConfig('follow_redirects')
+            && (!($auth = $this->request->getAuth())
+                || HTTP_Request2::AUTH_DIGEST != $auth['scheme'])
+        ) {
+            curl_setopt($ch, CURLOPT_READFUNCTION, array($this, 'callbackReadBody'));
+
+        // rewind may be needed, read the whole body into memory
+        } else {
+            if ($this->requestBody instanceof HTTP_Request2_MultipartBody) {
+                $this->requestBody = $this->requestBody->__toString();
+
+            } elseif (is_resource($this->requestBody)) {
+                $fp = $this->requestBody;
+                $this->requestBody = '';
+                while (!feof($fp)) {
+                    $this->requestBody .= fread($fp, 16384);
+                }
+            }
+            // curl hangs up if content-length is present
+            unset($headers['content-length']);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
+        }
+    }
+
+   /**
+    * Callback function called by cURL for reading the request body
+    *
+    * @param    resource    cURL handle
+    * @param    resource    file descriptor (not used)
+    * @param    integer     maximum length of data to return
+    * @return   string      part of the request body, up to $length bytes
+    */
+    protected function callbackReadBody($ch, $fd, $length)
+    {
+        if (!$this->eventSentHeaders) {
+            $this->request->setLastEvent(
+                'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
+            );
+            $this->eventSentHeaders = true;
+        }
+        if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+            0 == $this->contentLength || $this->position >= $this->contentLength
+        ) {
+            return '';
+        }
+        if (is_string($this->requestBody)) {
+            $string = substr($this->requestBody, $this->position, $length);
+        } elseif (is_resource($this->requestBody)) {
+            $string = fread($this->requestBody, $length);
+        } else {
+            $string = $this->requestBody->read($length);
+        }
+        $this->request->setLastEvent('sentBodyPart', strlen($string));
+        $this->position += strlen($string);
+        return $string;
+    }
+
+   /**
+    * Callback function called by cURL for saving the response headers
+    *
+    * @param    resource    cURL handle
+    * @param    string      response header (with trailing CRLF)
+    * @return   integer     number of bytes saved
+    * @see      HTTP_Request2_Response::parseHeaderLine()
+    */
+    protected function callbackWriteHeader($ch, $string)
+    {
+        // we may receive a second set of headers if doing e.g. digest auth
+        if ($this->eventReceivedHeaders || !$this->eventSentHeaders) {
+            // don't bother with 100-Continue responses (bug #15785)
+            if (!$this->eventSentHeaders ||
+                $this->response->getStatus() >= 200
+            ) {
+                $this->request->setLastEvent(
+                    'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
+                );
+            }
+            $upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD);
+            // if body wasn't read by a callback, send event with total body size
+            if ($upload > $this->position) {
+                $this->request->setLastEvent(
+                    'sentBodyPart', $upload - $this->position
+                );
+                $this->position = $upload;
+            }
+            if ($upload && (!$this->eventSentHeaders
+                            || $this->response->getStatus() >= 200)
+            ) {
+                $this->request->setLastEvent('sentBody', $upload);
+            }
+            $this->eventSentHeaders = true;
+            // we'll need a new response object
+            if ($this->eventReceivedHeaders) {
+                $this->eventReceivedHeaders = false;
+                $this->response             = null;
+            }
+        }
+        if (empty($this->response)) {
+            $this->response = new HTTP_Request2_Response(
+                $string, false, curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)
+            );
+        } else {
+            $this->response->parseHeaderLine($string);
+            if ('' == trim($string)) {
+                // don't bother with 100-Continue responses (bug #15785)
+                if (200 <= $this->response->getStatus()) {
+                    $this->request->setLastEvent('receivedHeaders', $this->response);
+                }
+
+                if ($this->request->getConfig('follow_redirects') && $this->response->isRedirect()) {
+                    $redirectUrl = new Net_URL2($this->response->getHeader('location'));
+
+                    // for versions lower than 5.2.10, check the redirection URL protocol
+                    if (!defined('CURLOPT_REDIR_PROTOCOLS') && $redirectUrl->isAbsolute()
+                        && !in_array($redirectUrl->getScheme(), array('http', 'https'))
+                    ) {
+                        return -1;
+                    }
+
+                    if ($jar = $this->request->getCookieJar()) {
+                        $jar->addCookiesFromResponse($this->response, $this->request->getUrl());
+                        if (!$redirectUrl->isAbsolute()) {
+                            $redirectUrl = $this->request->getUrl()->resolve($redirectUrl);
+                        }
+                        if ($cookies = $jar->getMatching($redirectUrl, true)) {
+                            curl_setopt($ch, CURLOPT_COOKIE, $cookies);
+                        }
+                    }
+                }
+                $this->eventReceivedHeaders = true;
+            }
+        }
+        return strlen($string);
+    }
+
+   /**
+    * Callback function called by cURL for saving the response body
+    *
+    * @param    resource    cURL handle (not used)
+    * @param    string      part of the response body
+    * @return   integer     number of bytes saved
+    * @see      HTTP_Request2_Response::appendBody()
+    */
+    protected function callbackWriteBody($ch, $string)
+    {
+        // cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
+        // response doesn't start with proper HTTP status line (see bug #15716)
+        if (empty($this->response)) {
+            throw new HTTP_Request2_MessageException(
+                "Malformed response: {$string}",
+                HTTP_Request2_Exception::MALFORMED_RESPONSE
+            );
+        }
+        if ($this->request->getConfig('store_body')) {
+            $this->response->appendBody($string);
+        }
+        $this->request->setLastEvent('receivedBodyPart', $string);
+        return strlen($string);
+    }
+}
+?>
diff --git a/lib/php/HTTP/Request2/Adapter/Mock.php b/lib/php/HTTP/Request2/Adapter/Mock.php
new file mode 100644
index 0000000..8e761c8
--- /dev/null
+++ b/lib/php/HTTP/Request2/Adapter/Mock.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Mock adapter intended for testing
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Mock.php 308322 2011-02-14 13:58:03Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Mock adapter intended for testing
+ *
+ * Can be used to test applications depending on HTTP_Request2 package without
+ * actually performing any HTTP requests. This adapter will return responses
+ * previously added via addResponse()
+ * <code>
+ * $mock = new HTTP_Request2_Adapter_Mock();
+ * $mock->addResponse("HTTP/1.1 ... ");
+ *
+ * $request = new HTTP_Request2();
+ * $request->setAdapter($mock);
+ *
+ * // This will return the response set above
+ * $response = $req->send();
+ * </code>
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @version    Release: 2.0.0beta3
+ */
+class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
+{
+   /**
+    * A queue of responses to be returned by sendRequest()
+    * @var  array
+    */
+    protected $responses = array();
+
+   /**
+    * Returns the next response from the queue built by addResponse()
+    *
+    * If the queue is empty it will return default empty response with status 400,
+    * if an Exception object was added to the queue it will be thrown.
+    *
+    * @param    HTTP_Request2
+    * @return   HTTP_Request2_Response
+    * @throws   Exception
+    */
+    public function sendRequest(HTTP_Request2 $request)
+    {
+        if (count($this->responses) > 0) {
+            $response = array_shift($this->responses);
+            if ($response instanceof HTTP_Request2_Response) {
+                return $response;
+            } else {
+                // rethrow the exception
+                $class   = get_class($response);
+                $message = $response->getMessage();
+                $code    = $response->getCode();
+                throw new $class($message, $code);
+            }
+        } else {
+            return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
+        }
+    }
+
+   /**
+    * Adds response to the queue
+    *
+    * @param    mixed   either a string, a pointer to an open file,
+    *                   an instance of HTTP_Request2_Response or Exception
+    * @throws   HTTP_Request2_Exception
+    */
+    public function addResponse($response)
+    {
+        if (is_string($response)) {
+            $response = self::createResponseFromString($response);
+        } elseif (is_resource($response)) {
+            $response = self::createResponseFromFile($response);
+        } elseif (!$response instanceof HTTP_Request2_Response &&
+                  !$response instanceof Exception
+        ) {
+            throw new HTTP_Request2_Exception('Parameter is not a valid response');
+        }
+        $this->responses[] = $response;
+    }
+
+   /**
+    * Creates a new HTTP_Request2_Response object from a string
+    *
+    * @param    string
+    * @return   HTTP_Request2_Response
+    * @throws   HTTP_Request2_Exception
+    */
+    public static function createResponseFromString($str)
+    {
+        $parts       = preg_split('!(\r?\n){2}!m', $str, 2);
+        $headerLines = explode("\n", $parts[0]);
+        $response    = new HTTP_Request2_Response(array_shift($headerLines));
+        foreach ($headerLines as $headerLine) {
+            $response->parseHeaderLine($headerLine);
+        }
+        $response->parseHeaderLine('');
+        if (isset($parts[1])) {
+            $response->appendBody($parts[1]);
+        }
+        return $response;
+    }
+
+   /**
+    * Creates a new HTTP_Request2_Response object from a file
+    *
+    * @param    resource    file pointer returned by fopen()
+    * @return   HTTP_Request2_Response
+    * @throws   HTTP_Request2_Exception
+    */
+    public static function createResponseFromFile($fp)
+    {
+        $response = new HTTP_Request2_Response(fgets($fp));
+        do {
+            $headerLine = fgets($fp);
+            $response->parseHeaderLine($headerLine);
+        } while ('' != trim($headerLine));
+
+        while (!feof($fp)) {
+            $response->appendBody(fread($fp, 8192));
+        }
+        return $response;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/HTTP/Request2/Adapter/Socket.php b/lib/php/HTTP/Request2/Adapter/Socket.php
new file mode 100644
index 0000000..5b4dc54
--- /dev/null
+++ b/lib/php/HTTP/Request2/Adapter/Socket.php
@@ -0,0 +1,1084 @@
+<?php
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Socket.php 309921 2011-04-03 16:43:02Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for HTTP_Request2 adapters
+ */
+require_once 'HTTP/Request2/Adapter.php';
+
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * This adapter uses only PHP sockets and will work on almost any PHP
+ * environment. Code is based on original HTTP_Request PEAR package.
+ *
+ * @category    HTTP
+ * @package     HTTP_Request2
+ * @author      Alexey Borzov <avb@php.net>
+ * @version     Release: 2.0.0beta3
+ */
+class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
+{
+   /**
+    * Regular expression for 'token' rule from RFC 2616
+    */
+    const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
+
+   /**
+    * Regular expression for 'quoted-string' rule from RFC 2616
+    */
+    const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
+
+   /**
+    * Connected sockets, needed for Keep-Alive support
+    * @var  array
+    * @see  connect()
+    */
+    protected static $sockets = array();
+
+   /**
+    * Data for digest authentication scheme
+    *
+    * The keys for the array are URL prefixes.
+    *
+    * The values are associative arrays with data (realm, nonce, nonce-count,
+    * opaque...) needed for digest authentication. Stored here to prevent making
+    * duplicate requests to digest-protected resources after we have already
+    * received the challenge.
+    *
+    * @var  array
+    */
+    protected static $challenges = array();
+
+   /**
+    * Connected socket
+    * @var  resource
+    * @see  connect()
+    */
+    protected $socket;
+
+   /**
+    * Challenge used for server digest authentication
+    * @var  array
+    */
+    protected $serverChallenge;
+
+   /**
+    * Challenge used for proxy digest authentication
+    * @var  array
+    */
+    protected $proxyChallenge;
+
+   /**
+    * Sum of start time and global timeout, exception will be thrown if request continues past this time
+    * @var  integer
+    */
+    protected $deadline = null;
+
+   /**
+    * Remaining length of the current chunk, when reading chunked response
+    * @var  integer
+    * @see  readChunked()
+    */
+    protected $chunkLength = 0;
+
+   /**
+    * Remaining amount of redirections to follow
+    *
+    * Starts at 'max_redirects' configuration parameter and is reduced on each
+    * subsequent redirect. An Exception will be thrown once it reaches zero.
+    *
+    * @var  integer
+    */
+    protected $redirectCountdown = null;
+
+   /**
+    * Sends request to the remote server and returns its response
+    *
+    * @param    HTTP_Request2
+    * @return   HTTP_Request2_Response
+    * @throws   HTTP_Request2_Exception
+    */
+    public function sendRequest(HTTP_Request2 $request)
+    {
+        $this->request = $request;
+
+        // Use global request timeout if given, see feature requests #5735, #8964
+        if ($timeout = $request->getConfig('timeout')) {
+            $this->deadline = time() + $timeout;
+        } else {
+            $this->deadline = null;
+        }
+
+        try {
+            $keepAlive = $this->connect();
+            $headers   = $this->prepareHeaders();
+            if (false === @fwrite($this->socket, $headers, strlen($headers))) {
+                throw new HTTP_Request2_MessageException('Error writing request');
+            }
+            // provide request headers to the observer, see request #7633
+            $this->request->setLastEvent('sentHeaders', $headers);
+            $this->writeBody();
+
+            if ($this->deadline && time() > $this->deadline) {
+                throw new HTTP_Request2_MessageException(
+                    'Request timed out after ' .
+                    $request->getConfig('timeout') . ' second(s)',
+                    HTTP_Request2_Exception::TIMEOUT
+                );
+            }
+
+            $response = $this->readResponse();
+
+            if ($jar = $request->getCookieJar()) {
+                $jar->addCookiesFromResponse($response, $request->getUrl());
+            }
+
+            if (!$this->canKeepAlive($keepAlive, $response)) {
+                $this->disconnect();
+            }
+
+            if ($this->shouldUseProxyDigestAuth($response)) {
+                return $this->sendRequest($request);
+            }
+            if ($this->shouldUseServerDigestAuth($response)) {
+                return $this->sendRequest($request);
+            }
+            if ($authInfo = $response->getHeader('authentication-info')) {
+                $this->updateChallenge($this->serverChallenge, $authInfo);
+            }
+            if ($proxyInfo = $response->getHeader('proxy-authentication-info')) {
+                $this->updateChallenge($this->proxyChallenge, $proxyInfo);
+            }
+
+        } catch (Exception $e) {
+            $this->disconnect();
+        }
+
+        unset($this->request, $this->requestBody);
+
+        if (!empty($e)) {
+            $this->redirectCountdown = null;
+            throw $e;
+        }
+
+        if (!$request->getConfig('follow_redirects') || !$response->isRedirect()) {
+            $this->redirectCountdown = null;
+            return $response;
+        } else {
+            return $this->handleRedirect($request, $response);
+        }
+    }
+
+   /**
+    * Connects to the remote server
+    *
+    * @return   bool    whether the connection can be persistent
+    * @throws   HTTP_Request2_Exception
+    */
+    protected function connect()
+    {
+        $secure  = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');
+        $tunnel  = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+        $headers = $this->request->getHeaders();
+        $reqHost = $this->request->getUrl()->getHost();
+        if (!($reqPort = $this->request->getUrl()->getPort())) {
+            $reqPort = $secure? 443: 80;
+        }
+
+        if ($host = $this->request->getConfig('proxy_host')) {
+            if (!($port = $this->request->getConfig('proxy_port'))) {
+                throw new HTTP_Request2_LogicException(
+                    'Proxy port not provided',
+                    HTTP_Request2_Exception::MISSING_VALUE
+                );
+            }
+            $proxy = true;
+        } else {
+            $host  = $reqHost;
+            $port  = $reqPort;
+            $proxy = false;
+        }
+
+        if ($tunnel && !$proxy) {
+            throw new HTTP_Request2_LogicException(
+                "Trying to perform CONNECT request without proxy",
+                HTTP_Request2_Exception::MISSING_VALUE
+            );
+        }
+        if ($secure && !in_array('ssl', stream_get_transports())) {
+            throw new HTTP_Request2_LogicException(
+                'Need OpenSSL support for https:// requests',
+                HTTP_Request2_Exception::MISCONFIGURATION
+            );
+        }
+
+        // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+        // connection token to a proxy server...
+        if ($proxy && !$secure &&
+            !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']
+        ) {
+            $this->request->setHeader('connection');
+        }
+
+        $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') &&
+                      empty($headers['connection'])) ||
+                     (!empty($headers['connection']) &&
+                      'Keep-Alive' == $headers['connection']);
+        $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;
+
+        $options = array();
+        if ($secure || $tunnel) {
+            foreach ($this->request->getConfig() as $name => $value) {
+                if ('ssl_' == substr($name, 0, 4) && null !== $value) {
+                    if ('ssl_verify_host' == $name) {
+                        if ($value) {
+                            $options['CN_match'] = $reqHost;
+                        }
+                    } else {
+                        $options[substr($name, 4)] = $value;
+                    }
+                }
+            }
+            ksort($options);
+        }
+
+        // Changing SSL context options after connection is established does *not*
+        // work, we need a new connection if options change
+        $remote    = $host . ':' . $port;
+        $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .
+                     (empty($options)? '': ':' . serialize($options));
+        unset($this->socket);
+
+        // We use persistent connections and have a connected socket?
+        // Ensure that the socket is still connected, see bug #16149
+        if ($keepAlive && !empty(self::$sockets[$socketKey]) &&
+            !feof(self::$sockets[$socketKey])
+        ) {
+            $this->socket =& self::$sockets[$socketKey];
+
+        } elseif ($secure && $proxy && !$tunnel) {
+            $this->establishTunnel();
+            $this->request->setLastEvent(
+                'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"
+            );
+            self::$sockets[$socketKey] =& $this->socket;
+
+        } else {
+            // Set SSL context options if doing HTTPS request or creating a tunnel
+            $context = stream_context_create();
+            foreach ($options as $name => $value) {
+                if (!stream_context_set_option($context, 'ssl', $name, $value)) {
+                    throw new HTTP_Request2_LogicException(
+                        "Error setting SSL context option '{$name}'"
+                    );
+                }
+            }
+            $track = @ini_set('track_errors', 1);
+            $this->socket = @stream_socket_client(
+                $remote, $errno, $errstr,
+                $this->request->getConfig('connect_timeout'),
+                STREAM_CLIENT_CONNECT, $context
+            );
+            if (!$this->socket) {
+                $e = new HTTP_Request2_ConnectionException(
+                    "Unable to connect to {$remote}. Error: "
+                     . (empty($errstr)? $php_errormsg: $errstr), 0, $errno
+                );
+            }
+            @ini_set('track_errors', $track);
+            if (isset($e)) {
+                throw $e;
+            }
+            $this->request->setLastEvent('connect', $remote);
+            self::$sockets[$socketKey] =& $this->socket;
+        }
+        return $keepAlive;
+    }
+
+   /**
+    * Establishes a tunnel to a secure remote server via HTTP CONNECT request
+    *
+    * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP
+    * sees that we are connected to a proxy server (duh!) rather than the server
+    * that presents its certificate.
+    *
+    * @link     http://tools.ietf.org/html/rfc2817#section-5.2
+    * @throws   HTTP_Request2_Exception
+    */
+    protected function establishTunnel()
+    {
+        $donor   = new self;
+        $connect = new HTTP_Request2(
+            $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,
+            array_merge($this->request->getConfig(),
+                        array('adapter' => $donor))
+        );
+        $response = $connect->send();
+        // Need any successful (2XX) response
+        if (200 > $response->getStatus() || 300 <= $response->getStatus()) {
+            throw new HTTP_Request2_ConnectionException(
+                'Failed to connect via HTTPS proxy. Proxy response: ' .
+                $response->getStatus() . ' ' . $response->getReasonPhrase()
+            );
+        }
+        $this->socket = $donor->socket;
+
+        $modes = array(
+            STREAM_CRYPTO_METHOD_TLS_CLIENT,
+            STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+            STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+            STREAM_CRYPTO_METHOD_SSLv2_CLIENT
+        );
+
+        foreach ($modes as $mode) {
+            if (stream_socket_enable_crypto($this->socket, true, $mode)) {
+                return;
+            }
+        }
+        throw new HTTP_Request2_ConnectionException(
+            'Failed to enable secure connection when connecting through proxy'
+        );
+    }
+
+   /**
+    * Checks whether current connection may be reused or should be closed
+    *
+    * @param    boolean                 whether connection could be persistent
+    *                                   in the first place
+    * @param    HTTP_Request2_Response  response object to check
+    * @return   boolean
+    */
+    protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)
+    {
+        // Do not close socket on successful CONNECT request
+        if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+            200 <= $response->getStatus() && 300 > $response->getStatus()
+        ) {
+            return true;
+        }
+
+        $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding'))
+                       || null !== $response->getHeader('content-length')
+                       // no body possible for such responses, see also request #17031
+                       || HTTP_Request2::METHOD_HEAD == $this->request->getMethod()
+                       || in_array($response->getStatus(), array(204, 304));
+        $persistent  = 'keep-alive' == strtolower($response->getHeader('connection')) ||
+                       (null === $response->getHeader('connection') &&
+                        '1.1' == $response->getVersion());
+        return $requestKeepAlive && $lengthKnown && $persistent;
+    }
+
+   /**
+    * Disconnects from the remote server
+    */
+    protected function disconnect()
+    {
+        if (is_resource($this->socket)) {
+            fclose($this->socket);
+            $this->socket = null;
+            $this->request->setLastEvent('disconnect');
+        }
+    }
+
+   /**
+    * Handles HTTP redirection
+    *
+    * This method will throw an Exception if redirect to a non-HTTP(S) location
+    * is attempted, also if number of redirects performed already is equal to
+    * 'max_redirects' configuration parameter.
+    *
+    * @param    HTTP_Request2               Original request
+    * @param    HTTP_Request2_Response      Response containing redirect
+    * @return   HTTP_Request2_Response      Response from a new location
+    * @throws   HTTP_Request2_Exception
+    */
+    protected function handleRedirect(HTTP_Request2 $request,
+                                      HTTP_Request2_Response $response)
+    {
+        if (is_null($this->redirectCountdown)) {
+            $this->redirectCountdown = $request->getConfig('max_redirects');
+        }
+        if (0 == $this->redirectCountdown) {
+            $this->redirectCountdown = null;
+            // Copying cURL behaviour
+            throw new HTTP_Request2_MessageException (
+                'Maximum (' . $request->getConfig('max_redirects') . ') redirects followed',
+                HTTP_Request2_Exception::TOO_MANY_REDIRECTS
+            );
+        }
+        $redirectUrl = new Net_URL2(
+            $response->getHeader('location'),
+            array(Net_URL2::OPTION_USE_BRACKETS => $request->getConfig('use_brackets'))
+        );
+        // refuse non-HTTP redirect
+        if ($redirectUrl->isAbsolute()
+            && !in_array($redirectUrl->getScheme(), array('http', 'https'))
+        ) {
+            $this->redirectCountdown = null;
+            throw new HTTP_Request2_MessageException(
+                'Refusing to redirect to a non-HTTP URL ' . $redirectUrl->__toString(),
+                HTTP_Request2_Exception::NON_HTTP_REDIRECT
+            );
+        }
+        // Theoretically URL should be absolute (see http://tools.ietf.org/html/rfc2616#section-14.30),
+        // but in practice it is often not
+        if (!$redirectUrl->isAbsolute()) {
+            $redirectUrl = $request->getUrl()->resolve($redirectUrl);
+        }
+        $redirect = clone $request;
+        $redirect->setUrl($redirectUrl);
+        if (303 == $response->getStatus() || (!$request->getConfig('strict_redirects')
+             && in_array($response->getStatus(), array(301, 302)))
+        ) {
+            $redirect->setMethod(HTTP_Request2::METHOD_GET);
+            $redirect->setBody('');
+        }
+
+        if (0 < $this->redirectCountdown) {
+            $this->redirectCountdown--;
+        }
+        return $this->sendRequest($redirect);
+    }
+
+   /**
+    * Checks whether another request should be performed with server digest auth
+    *
+    * Several conditions should be satisfied for it to return true:
+    *   - response status should be 401
+    *   - auth credentials should be set in the request object
+    *   - response should contain WWW-Authenticate header with digest challenge
+    *   - there is either no challenge stored for this URL or new challenge
+    *     contains stale=true parameter (in other case we probably just failed
+    *     due to invalid username / password)
+    *
+    * The method stores challenge values in $challenges static property
+    *
+    * @param    HTTP_Request2_Response  response to check
+    * @return   boolean whether another request should be performed
+    * @throws   HTTP_Request2_Exception in case of unsupported challenge parameters
+    */
+    protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
+    {
+        // no sense repeating a request if we don't have credentials
+        if (401 != $response->getStatus() || !$this->request->getAuth()) {
+            return false;
+        }
+        if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) {
+            return false;
+        }
+
+        $url    = $this->request->getUrl();
+        $scheme = $url->getScheme();
+        $host   = $scheme . '://' . $url->getHost();
+        if ($port = $url->getPort()) {
+            if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||
+                (0 == strcasecmp($scheme, 'https') && 443 != $port)
+            ) {
+                $host .= ':' . $port;
+            }
+        }
+
+        if (!empty($challenge['domain'])) {
+            $prefixes = array();
+            foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
+                // don't bother with different servers
+                if ('/' == substr($prefix, 0, 1)) {
+                    $prefixes[] = $host . $prefix;
+                }
+            }
+        }
+        if (empty($prefixes)) {
+            $prefixes = array($host . '/');
+        }
+
+        $ret = true;
+        foreach ($prefixes as $prefix) {
+            if (!empty(self::$challenges[$prefix]) &&
+                (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+            ) {
+                // probably credentials are invalid
+                $ret = false;
+            }
+            self::$challenges[$prefix] =& $challenge;
+        }
+        return $ret;
+    }
+
+   /**
+    * Checks whether another request should be performed with proxy digest auth
+    *
+    * Several conditions should be satisfied for it to return true:
+    *   - response status should be 407
+    *   - proxy auth credentials should be set in the request object
+    *   - response should contain Proxy-Authenticate header with digest challenge
+    *   - there is either no challenge stored for this proxy or new challenge
+    *     contains stale=true parameter (in other case we probably just failed
+    *     due to invalid username / password)
+    *
+    * The method stores challenge values in $challenges static property
+    *
+    * @param    HTTP_Request2_Response  response to check
+    * @return   boolean whether another request should be performed
+    * @throws   HTTP_Request2_Exception in case of unsupported challenge parameters
+    */
+    protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)
+    {
+        if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {
+            return false;
+        }
+        if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) {
+            return false;
+        }
+
+        $key = 'proxy://' . $this->request->getConfig('proxy_host') .
+               ':' . $this->request->getConfig('proxy_port');
+
+        if (!empty(self::$challenges[$key]) &&
+            (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))
+        ) {
+            $ret = false;
+        } else {
+            $ret = true;
+        }
+        self::$challenges[$key] = $challenge;
+        return $ret;
+    }
+
+   /**
+    * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value
+    *
+    * There is a problem with implementation of RFC 2617: several of the parameters
+    * are defined as quoted-string there and thus may contain backslash escaped
+    * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as
+    * just value of quoted-string X without surrounding quotes, it doesn't speak
+    * about removing backslash escaping.
+    *
+    * Now realm parameter is user-defined and human-readable, strange things
+    * happen when it contains quotes:
+    *   - Apache allows quotes in realm, but apparently uses realm value without
+    *     backslashes for digest computation
+    *   - Squid allows (manually escaped) quotes there, but it is impossible to
+    *     authorize with either escaped or unescaped quotes used in digest,
+    *     probably it can't parse the response (?)
+    *   - Both IE and Firefox display realm value with backslashes in
+    *     the password popup and apparently use the same value for digest
+    *
+    * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in
+    * quoted-string handling, unfortunately that means failure to authorize
+    * sometimes
+    *
+    * @param    string  value of WWW-Authenticate or Proxy-Authenticate header
+    * @return   mixed   associative array with challenge parameters, false if
+    *                   no challenge is present in header value
+    * @throws   HTTP_Request2_NotImplementedException in case of unsupported challenge parameters
+    */
+    protected function parseDigestChallenge($headerValue)
+    {
+        $authParam   = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+                       self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')';
+        $challenge   = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!";
+        if (!preg_match($challenge, $headerValue, $matches)) {
+            return false;
+        }
+
+        preg_match_all('!' . $authParam . '!', $matches[0], $params);
+        $paramsAry   = array();
+        $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale',
+                             'algorithm', 'qop');
+        for ($i = 0; $i < count($params[0]); $i++) {
+            // section 3.2.1: Any unrecognized directive MUST be ignored.
+            if (in_array($params[1][$i], $knownParams)) {
+                if ('"' == substr($params[2][$i], 0, 1)) {
+                    $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+                } else {
+                    $paramsAry[$params[1][$i]] = $params[2][$i];
+                }
+            }
+        }
+        // we only support qop=auth
+        if (!empty($paramsAry['qop']) &&
+            !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))
+        ) {
+            throw new HTTP_Request2_NotImplementedException(
+                "Only 'auth' qop is currently supported in digest authentication, " .
+                "server requested '{$paramsAry['qop']}'"
+            );
+        }
+        // we only support algorithm=MD5
+        if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) {
+            throw new HTTP_Request2_NotImplementedException(
+                "Only 'MD5' algorithm is currently supported in digest authentication, " .
+                "server requested '{$paramsAry['algorithm']}'"
+            );
+        }
+
+        return $paramsAry;
+    }
+
+   /**
+    * Parses [Proxy-]Authentication-Info header value and updates challenge
+    *
+    * @param    array   challenge to update
+    * @param    string  value of [Proxy-]Authentication-Info header
+    * @todo     validate server rspauth response
+    */
+    protected function updateChallenge(&$challenge, $headerValue)
+    {
+        $authParam   = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .
+                       self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!';
+        $paramsAry   = array();
+
+        preg_match_all($authParam, $headerValue, $params);
+        for ($i = 0; $i < count($params[0]); $i++) {
+            if ('"' == substr($params[2][$i], 0, 1)) {
+                $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1);
+            } else {
+                $paramsAry[$params[1][$i]] = $params[2][$i];
+            }
+        }
+        // for now, just update the nonce value
+        if (!empty($paramsAry['nextnonce'])) {
+            $challenge['nonce'] = $paramsAry['nextnonce'];
+            $challenge['nc']    = 1;
+        }
+    }
+
+   /**
+    * Creates a value for [Proxy-]Authorization header when using digest authentication
+    *
+    * @param    string  user name
+    * @param    string  password
+    * @param    string  request URL
+    * @param    array   digest challenge parameters
+    * @return   string  value of [Proxy-]Authorization request header
+    * @link     http://tools.ietf.org/html/rfc2617#section-3.2.2
+    */
+    protected function createDigestResponse($user, $password, $url, &$challenge)
+    {
+        if (false !== ($q = strpos($url, '?')) &&
+            $this->request->getConfig('digest_compat_ie')
+        ) {
+            $url = substr($url, 0, $q);
+        }
+
+        $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
+        $a2 = md5($this->request->getMethod() . ':' . $url);
+
+        if (empty($challenge['qop'])) {
+            $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2);
+        } else {
+            $challenge['cnonce'] = 'Req2.' . rand();
+            if (empty($challenge['nc'])) {
+                $challenge['nc'] = 1;
+            }
+            $nc     = sprintf('%08x', $challenge['nc']++);
+            $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
+                          $challenge['cnonce'] . ':auth:' . $a2);
+        }
+        return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .
+               'realm="' . $challenge['realm'] . '", ' .
+               'nonce="' . $challenge['nonce'] . '", ' .
+               'uri="' . $url . '", ' .
+               'response="' . $digest . '"' .
+               (!empty($challenge['opaque'])?
+                ', opaque="' . $challenge['opaque'] . '"':
+                '') .
+               (!empty($challenge['qop'])?
+                ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"':
+                '');
+    }
+
+   /**
+    * Adds 'Authorization' header (if needed) to request headers array
+    *
+    * @param    array   request headers
+    * @param    string  request host (needed for digest authentication)
+    * @param    string  request URL (needed for digest authentication)
+    * @throws   HTTP_Request2_NotImplementedException
+    */
+    protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
+    {
+        if (!($auth = $this->request->getAuth())) {
+            return;
+        }
+        switch ($auth['scheme']) {
+            case HTTP_Request2::AUTH_BASIC:
+                $headers['authorization'] =
+                    'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);
+                break;
+
+            case HTTP_Request2::AUTH_DIGEST:
+                unset($this->serverChallenge);
+                $fullUrl = ('/' == $requestUrl[0])?
+                           $this->request->getUrl()->getScheme() . '://' .
+                            $requestHost . $requestUrl:
+                           $requestUrl;
+                foreach (array_keys(self::$challenges) as $key) {
+                    if ($key == substr($fullUrl, 0, strlen($key))) {
+                        $headers['authorization'] = $this->createDigestResponse(
+                            $auth['user'], $auth['password'],
+                            $requestUrl, self::$challenges[$key]
+                        );
+                        $this->serverChallenge =& self::$challenges[$key];
+                        break;
+                    }
+                }
+                break;
+
+            default:
+                throw new HTTP_Request2_NotImplementedException(
+                    "Unknown HTTP authentication scheme '{$auth['scheme']}'"
+                );
+        }
+    }
+
+   /**
+    * Adds 'Proxy-Authorization' header (if needed) to request headers array
+    *
+    * @param    array   request headers
+    * @param    string  request URL (needed for digest authentication)
+    * @throws   HTTP_Request2_NotImplementedException
+    */
+    protected function addProxyAuthorizationHeader(&$headers, $requestUrl)
+    {
+        if (!$this->request->getConfig('proxy_host') ||
+            !($user = $this->request->getConfig('proxy_user')) ||
+            (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&
+             HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())
+        ) {
+            return;
+        }
+
+        $password = $this->request->getConfig('proxy_password');
+        switch ($this->request->getConfig('proxy_auth_scheme')) {
+            case HTTP_Request2::AUTH_BASIC:
+                $headers['proxy-authorization'] =
+                    'Basic ' . base64_encode($user . ':' . $password);
+                break;
+
+            case HTTP_Request2::AUTH_DIGEST:
+                unset($this->proxyChallenge);
+                $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .
+                            ':' . $this->request->getConfig('proxy_port');
+                if (!empty(self::$challenges[$proxyUrl])) {
+                    $headers['proxy-authorization'] = $this->createDigestResponse(
+                        $user, $password,
+                        $requestUrl, self::$challenges[$proxyUrl]
+                    );
+                    $this->proxyChallenge =& self::$challenges[$proxyUrl];
+                }
+                break;
+
+            default:
+                throw new HTTP_Request2_NotImplementedException(
+                    "Unknown HTTP authentication scheme '" .
+                    $this->request->getConfig('proxy_auth_scheme') . "'"
+                );
+        }
+    }
+
+
+   /**
+    * Creates the string with the Request-Line and request headers
+    *
+    * @return   string
+    * @throws   HTTP_Request2_Exception
+    */
+    protected function prepareHeaders()
+    {
+        $headers = $this->request->getHeaders();
+        $url     = $this->request->getUrl();
+        $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
+        $host    = $url->getHost();
+
+        $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80;
+        if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
+            $host .= ':' . (empty($port)? $defaultPort: $port);
+        }
+        // Do not overwrite explicitly set 'Host' header, see bug #16146
+        if (!isset($headers['host'])) {
+            $headers['host'] = $host;
+        }
+
+        if ($connect) {
+            $requestUrl = $host;
+
+        } else {
+            if (!$this->request->getConfig('proxy_host') ||
+                0 == strcasecmp($url->getScheme(), 'https')
+            ) {
+                $requestUrl = '';
+            } else {
+                $requestUrl = $url->getScheme() . '://' . $host;
+            }
+            $path        = $url->getPath();
+            $query       = $url->getQuery();
+            $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
+        }
+
+        if ('1.1' == $this->request->getConfig('protocol_version') &&
+            extension_loaded('zlib') && !isset($headers['accept-encoding'])
+        ) {
+            $headers['accept-encoding'] = 'gzip, deflate';
+        }
+        if (($jar = $this->request->getCookieJar())
+            && ($cookies = $jar->getMatching($this->request->getUrl(), true))
+        ) {
+            $headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies;
+        }
+
+        $this->addAuthorizationHeader($headers, $host, $requestUrl);
+        $this->addProxyAuthorizationHeader($headers, $requestUrl);
+        $this->calculateRequestLength($headers);
+
+        $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
+                      $this->request->getConfig('protocol_version') . "\r\n";
+        foreach ($headers as $name => $value) {
+            $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+            $headersStr   .= $canonicalName . ': ' . $value . "\r\n";
+        }
+        return $headersStr . "\r\n";
+    }
+
+   /**
+    * Sends the request body
+    *
+    * @throws   HTTP_Request2_MessageException
+    */
+    protected function writeBody()
+    {
+        if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
+            0 == $this->contentLength
+        ) {
+            return;
+        }
+
+        $position   = 0;
+        $bufferSize = $this->request->getConfig('buffer_size');
+        while ($position < $this->contentLength) {
+            if (is_string($this->requestBody)) {
+                $str = substr($this->requestBody, $position, $bufferSize);
+            } elseif (is_resource($this->requestBody)) {
+                $str = fread($this->requestBody, $bufferSize);
+            } else {
+                $str = $this->requestBody->read($bufferSize);
+            }
+            if (false === @fwrite($this->socket, $str, strlen($str))) {
+                throw new HTTP_Request2_MessageException('Error writing request');
+            }
+            // Provide the length of written string to the observer, request #7630
+            $this->request->setLastEvent('sentBodyPart', strlen($str));
+            $position += strlen($str);
+        }
+        $this->request->setLastEvent('sentBody', $this->contentLength);
+    }
+
+   /**
+    * Reads the remote server's response
+    *
+    * @return   HTTP_Request2_Response
+    * @throws   HTTP_Request2_Exception
+    */
+    protected function readResponse()
+    {
+        $bufferSize = $this->request->getConfig('buffer_size');
+
+        do {
+            $response = new HTTP_Request2_Response(
+                $this->readLine($bufferSize), true, $this->request->getUrl()
+            );
+            do {
+                $headerLine = $this->readLine($bufferSize);
+                $response->parseHeaderLine($headerLine);
+            } while ('' != $headerLine);
+        } while (in_array($response->getStatus(), array(100, 101)));
+
+        $this->request->setLastEvent('receivedHeaders', $response);
+
+        // No body possible in such responses
+        if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||
+            (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&
+             200 <= $response->getStatus() && 300 > $response->getStatus()) ||
+            in_array($response->getStatus(), array(204, 304))
+        ) {
+            return $response;
+        }
+
+        $chunked = 'chunked' == $response->getHeader('transfer-encoding');
+        $length  = $response->getHeader('content-length');
+        $hasBody = false;
+        if ($chunked || null === $length || 0 < intval($length)) {
+            // RFC 2616, section 4.4:
+            // 3. ... If a message is received with both a
+            // Transfer-Encoding header field and a Content-Length header field,
+            // the latter MUST be ignored.
+            $toRead = ($chunked || null === $length)? null: $length;
+            $this->chunkLength = 0;
+
+            while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {
+                if ($chunked) {
+                    $data = $this->readChunked($bufferSize);
+                } elseif (is_null($toRead)) {
+                    $data = $this->fread($bufferSize);
+                } else {
+                    $data    = $this->fread(min($toRead, $bufferSize));
+                    $toRead -= strlen($data);
+                }
+                if ('' == $data && (!$this->chunkLength || feof($this->socket))) {
+                    break;
+                }
+
+                $hasBody = true;
+                if ($this->request->getConfig('store_body')) {
+                    $response->appendBody($data);
+                }
+                if (!in_array($response->getHeader('content-encoding'), array('identity', null))) {
+                    $this->request->setLastEvent('receivedEncodedBodyPart', $data);
+                } else {
+                    $this->request->setLastEvent('receivedBodyPart', $data);
+                }
+            }
+        }
+
+        if ($hasBody) {
+            $this->request->setLastEvent('receivedBody', $response);
+        }
+        return $response;
+    }
+
+   /**
+    * Reads until either the end of the socket or a newline, whichever comes first
+    *
+    * Strips the trailing newline from the returned data, handles global
+    * request timeout. Method idea borrowed from Net_Socket PEAR package.
+    *
+    * @param    int     buffer size to use for reading
+    * @return   Available data up to the newline (not including newline)
+    * @throws   HTTP_Request2_MessageException     In case of timeout
+    */
+    protected function readLine($bufferSize)
+    {
+        $line = '';
+        while (!feof($this->socket)) {
+            if ($this->deadline) {
+                stream_set_timeout($this->socket, max($this->deadline - time(), 1));
+            }
+            $line .= @fgets($this->socket, $bufferSize);
+            $info  = stream_get_meta_data($this->socket);
+            if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {
+                $reason = $this->deadline
+                          ? 'after ' . $this->request->getConfig('timeout') . ' second(s)'
+                          : 'due to default_socket_timeout php.ini setting';
+                throw new HTTP_Request2_MessageException(
+                    "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT
+                );
+            }
+            if (substr($line, -1) == "\n") {
+                return rtrim($line, "\r\n");
+            }
+        }
+        return $line;
+    }
+
+   /**
+    * Wrapper around fread(), handles global request timeout
+    *
+    * @param    int     Reads up to this number of bytes
+    * @return   Data read from socket
+    * @throws   HTTP_Request2_MessageException     In case of timeout
+    */
+    protected function fread($length)
+    {
+        if ($this->deadline) {
+            stream_set_timeout($this->socket, max($this->deadline - time(), 1));
+        }
+        $data = fread($this->socket, $length);
+        $info = stream_get_meta_data($this->socket);
+        if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {
+            $reason = $this->deadline
+                      ? 'after ' . $this->request->getConfig('timeout') . ' second(s)'
+                      : 'due to default_socket_timeout php.ini setting';
+            throw new HTTP_Request2_MessageException(
+                "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT
+            );
+        }
+        return $data;
+    }
+
+   /**
+    * Reads a part of response body encoded with chunked Transfer-Encoding
+    *
+    * @param    int     buffer size to use for reading
+    * @return   string
+    * @throws   HTTP_Request2_MessageException
+    */
+    protected function readChunked($bufferSize)
+    {
+        // at start of the next chunk?
+        if (0 == $this->chunkLength) {
+            $line = $this->readLine($bufferSize);
+            if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
+                throw new HTTP_Request2_MessageException(
+                    "Cannot decode chunked response, invalid chunk length '{$line}'",
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            } else {
+                $this->chunkLength = hexdec($matches[1]);
+                // Chunk with zero length indicates the end
+                if (0 == $this->chunkLength) {
+                    $this->readLine($bufferSize);
+                    return '';
+                }
+            }
+        }
+        $data = $this->fread(min($this->chunkLength, $bufferSize));
+        $this->chunkLength -= strlen($data);
+        if (0 == $this->chunkLength) {
+            $this->readLine($bufferSize); // Trailing CRLF
+        }
+        return $data;
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/HTTP/Request2/CookieJar.php b/lib/php/HTTP/Request2/CookieJar.php
new file mode 100644
index 0000000..3d5cf97
--- /dev/null
+++ b/lib/php/HTTP/Request2/CookieJar.php
@@ -0,0 +1,499 @@
+<?php
+/**
+ * Stores cookies and passes them between HTTP requests
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: CookieJar.php 308629 2011-02-24 17:34:24Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Class representing a HTTP request message */
+require_once 'HTTP/Request2.php';
+
+/**
+ * Stores cookies and passes them between HTTP requests
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @version    Release: 2.0.0beta3
+ */
+class HTTP_Request2_CookieJar implements Serializable
+{
+   /**
+    * Array of stored cookies
+    *
+    * The array is indexed by domain, path and cookie name
+    *   .example.com
+    *     /
+    *       some_cookie => cookie data
+    *     /subdir
+    *       other_cookie => cookie data
+    *   .example.org
+    *     ...
+    *
+    * @var array
+    */
+    protected $cookies = array();
+
+   /**
+    * Whether session cookies should be serialized when serializing the jar
+    * @var bool
+    */
+    protected $serializeSession = false;
+
+   /**
+    * Whether Public Suffix List should be used for domain matching
+    * @var bool
+    */
+    protected $useList = true;
+
+   /**
+    * Array with Public Suffix List data
+    * @var  array
+    * @link http://publicsuffix.org/
+    */
+    protected static $psl = array();
+
+   /**
+    * Class constructor, sets various options
+    *
+    * @param bool Controls serializing session cookies, see {@link serializeSessionCookies()}
+    * @param bool Controls using Public Suffix List, see {@link usePublicSuffixList()}
+    */
+    public function __construct($serializeSessionCookies = false, $usePublicSuffixList = true)
+    {
+        $this->serializeSessionCookies($serializeSessionCookies);
+        $this->usePublicSuffixList($usePublicSuffixList);
+    }
+
+   /**
+    * Returns current time formatted in ISO-8601 at UTC timezone
+    *
+    * @return string
+    */
+    protected function now()
+    {
+        $dt = new DateTime();
+        $dt->setTimezone(new DateTimeZone('UTC'));
+        return $dt->format(DateTime::ISO8601);
+    }
+
+   /**
+    * Checks cookie array for correctness, possibly updating its 'domain', 'path' and 'expires' fields
+    *
+    * The checks are as follows:
+    *   - cookie array should contain 'name' and 'value' fields;
+    *   - name and value should not contain disallowed symbols;
+    *   - 'expires' should be either empty parseable by DateTime;
+    *   - 'domain' and 'path' should be either not empty or an URL where
+    *     cookie was set should be provided.
+    *   - if $setter is provided, then document at that URL should be allowed
+    *     to set a cookie for that 'domain'. If $setter is not provided,
+    *     then no domain checks will be made.
+    *
+    * 'expires' field will be converted to ISO8601 format from COOKIE format,
+    * 'domain' and 'path' will be set from setter URL if empty.
+    *
+    * @param    array    cookie data, as returned by {@link HTTP_Request2_Response::getCookies()}
+    * @param    Net_URL2 URL of the document that sent Set-Cookie header
+    * @return   array    Updated cookie array
+    * @throws   HTTP_Request2_LogicException
+    * @throws   HTTP_Request2_MessageException
+    */
+    protected function checkAndUpdateFields(array $cookie, Net_URL2 $setter = null)
+    {
+        if ($missing = array_diff(array('name', 'value'), array_keys($cookie))) {
+            throw new HTTP_Request2_LogicException(
+                "Cookie array should contain 'name' and 'value' fields",
+                HTTP_Request2_Exception::MISSING_VALUE
+            );
+        }
+        if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['name'])) {
+            throw new HTTP_Request2_LogicException(
+                "Invalid cookie name: '{$cookie['name']}'",
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['value'])) {
+            throw new HTTP_Request2_LogicException(
+                "Invalid cookie value: '{$cookie['value']}'",
+                HTTP_Request2_Exception::INVALID_ARGUMENT
+            );
+        }
+        $cookie += array('domain' => '', 'path' => '', 'expires' => null, 'secure' => false);
+
+        // Need ISO-8601 date @ UTC timezone
+        if (!empty($cookie['expires'])
+            && !preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+0000$/', $cookie['expires'])
+        ) {
+            try {
+                $dt = new DateTime($cookie['expires']);
+                $dt->setTimezone(new DateTimeZone('UTC'));
+                $cookie['expires'] = $dt->format(DateTime::ISO8601);
+            } catch (Exception $e) {
+                throw new HTTP_Request2_LogicException($e->getMessage());
+            }
+        }
+
+        if (empty($cookie['domain']) || empty($cookie['path'])) {
+            if (!$setter) {
+                throw new HTTP_Request2_LogicException(
+                    'Cookie misses domain and/or path component, cookie setter URL needed',
+                    HTTP_Request2_Exception::MISSING_VALUE
+                );
+            }
+            if (empty($cookie['domain'])) {
+                if ($host = $setter->getHost()) {
+                    $cookie['domain'] = $host;
+                } else {
+                    throw new HTTP_Request2_LogicException(
+                        'Setter URL does not contain host part, can\'t set cookie domain',
+                        HTTP_Request2_Exception::MISSING_VALUE
+                    );
+                }
+            }
+            if (empty($cookie['path'])) {
+                $path = $setter->getPath();
+                $cookie['path'] = empty($path)? '/': substr($path, 0, strrpos($path, '/') + 1);
+            }
+        }
+
+        if ($setter && !$this->domainMatch($setter->getHost(), $cookie['domain'])) {
+            throw new HTTP_Request2_MessageException(
+                "Domain " . $setter->getHost() . " cannot set cookies for "
+                . $cookie['domain']
+            );
+        }
+
+        return $cookie;
+    }
+
+   /**
+    * Stores a cookie in the jar
+    *
+    * @param    array    cookie data, as returned by {@link HTTP_Request2_Response::getCookies()}
+    * @param    Net_URL2 URL of the document that sent Set-Cookie header
+    * @throws   HTTP_Request2_Exception
+    */
+    public function store(array $cookie, Net_URL2 $setter = null)
+    {
+        $cookie = $this->checkAndUpdateFields($cookie, $setter);
+
+        if (strlen($cookie['value'])
+            && (is_null($cookie['expires']) || $cookie['expires'] > $this->now())
+        ) {
+            if (!isset($this->cookies[$cookie['domain']])) {
+                $this->cookies[$cookie['domain']] = array();
+            }
+            if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) {
+                $this->cookies[$cookie['domain']][$cookie['path']] = array();
+            }
+            $this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie;
+
+        } elseif (isset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']])) {
+            unset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']]);
+        }
+    }
+
+   /**
+    * Adds cookies set in HTTP response to the jar
+    *
+    * @param HTTP_Request2_Response response
+    * @param Net_URL2               original request URL, needed for setting
+    *                               default domain/path
+    */
+    public function addCookiesFromResponse(HTTP_Request2_Response $response, Net_URL2 $setter)
+    {
+        foreach ($response->getCookies() as $cookie) {
+            $this->store($cookie, $setter);
+        }
+    }
+
+   /**
+    * Returns all cookies matching a given request URL
+    *
+    * The following checks are made:
+    *   - cookie domain should match request host
+    *   - cookie path should be a prefix for request path
+    *   - 'secure' cookies will only be sent for HTTPS requests
+    *
+    * @param  Net_URL2
+    * @param  bool      Whether to return cookies as string for "Cookie: " header
+    * @return array
+    */
+    public function getMatching(Net_URL2 $url, $asString = false)
+    {
+        $host   = $url->getHost();
+        $path   = $url->getPath();
+        $secure = 0 == strcasecmp($url->getScheme(), 'https');
+
+        $matched = $ret = array();
+        foreach (array_keys($this->cookies) as $domain) {
+            if ($this->domainMatch($host, $domain)) {
+                foreach (array_keys($this->cookies[$domain]) as $cPath) {
+                    if (0 === strpos($path, $cPath)) {
+                        foreach ($this->cookies[$domain][$cPath] as $name => $cookie) {
+                            if (!$cookie['secure'] || $secure) {
+                                $matched[$name][strlen($cookie['path'])] = $cookie;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        foreach ($matched as $cookies) {
+            krsort($cookies);
+            $ret = array_merge($ret, $cookies);
+        }
+        if (!$asString) {
+            return $ret;
+        } else {
+            $str = '';
+            foreach ($ret as $c) {
+                $str .= (empty($str)? '': '; ') . $c['name'] . '=' . $c['value'];
+            }
+            return $str;
+        }
+    }
+
+   /**
+    * Returns all cookies stored in a jar
+    *
+    * @return array
+    */
+    public function getAll()
+    {
+        $cookies = array();
+        foreach (array_keys($this->cookies) as $domain) {
+            foreach (array_keys($this->cookies[$domain]) as $path) {
+                foreach ($this->cookies[$domain][$path] as $name => $cookie) {
+                    $cookies[] = $cookie;
+                }
+            }
+        }
+        return $cookies;
+    }
+
+   /**
+    * Sets whether session cookies should be serialized when serializing the jar
+    *
+    * @param    boolean
+    */
+    public function serializeSessionCookies($serialize)
+    {
+        $this->serializeSession = (bool)$serialize;
+    }
+
+   /**
+    * Sets whether Public Suffix List should be used for restricting cookie-setting
+    *
+    * Without PSL {@link domainMatch()} will only prevent setting cookies for
+    * top-level domains like '.com' or '.org'. However, it will not prevent
+    * setting a cookie for '.co.uk' even though only third-level registrations
+    * are possible in .uk domain.
+    *
+    * With the List it is possible to find the highest level at which a domain
+    * may be registered for a particular top-level domain and consequently
+    * prevent cookies set for '.co.uk' or '.msk.ru'. The same list is used by
+    * Firefox, Chrome and Opera browsers to restrict cookie setting.
+    *
+    * Note that PSL is licensed differently to HTTP_Request2 package (refer to
+    * the license information in public-suffix-list.php), so you can disable
+    * its use if this is an issue for you.
+    *
+    * @param    boolean
+    * @link     http://publicsuffix.org/learn/
+    */
+    public function usePublicSuffixList($useList)
+    {
+        $this->useList = (bool)$useList;
+    }
+
+   /**
+    * Returns string representation of object
+    *
+    * @return string
+    * @see    Serializable::serialize()
+    */
+    public function serialize()
+    {
+        $cookies = $this->getAll();
+        if (!$this->serializeSession) {
+            for ($i = count($cookies) - 1; $i >= 0; $i--) {
+                if (empty($cookies[$i]['expires'])) {
+                    unset($cookies[$i]);
+                }
+            }
+        }
+        return serialize(array(
+            'cookies'          => $cookies,
+            'serializeSession' => $this->serializeSession,
+            'useList'          => $this->useList
+        ));
+    }
+
+   /**
+    * Constructs the object from serialized string
+    *
+    * @param string  string representation
+    * @see   Serializable::unserialize()
+    */
+    public function unserialize($serialized)
+    {
+        $data = unserialize($serialized);
+        $now  = $this->now();
+        $this->serializeSessionCookies($data['serializeSession']);
+        $this->usePublicSuffixList($data['useList']);
+        foreach ($data['cookies'] as $cookie) {
+            if (!empty($cookie['expires']) && $cookie['expires'] <= $now) {
+                continue;
+            }
+            if (!isset($this->cookies[$cookie['domain']])) {
+                $this->cookies[$cookie['domain']] = array();
+            }
+            if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) {
+                $this->cookies[$cookie['domain']][$cookie['path']] = array();
+            }
+            $this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie;
+        }
+    }
+
+   /**
+    * Checks whether a cookie domain matches a request host.
+    *
+    * The method is used by {@link store()} to check for whether a document
+    * at given URL can set a cookie with a given domain attribute and by
+    * {@link getMatching()} to find cookies matching the request URL.
+    *
+    * @param    string  request host
+    * @param    string  cookie domain
+    * @return   bool    match success
+    */
+    public function domainMatch($requestHost, $cookieDomain)
+    {
+        if ($requestHost == $cookieDomain) {
+            return true;
+        }
+        // IP address, we require exact match
+        if (preg_match('/^(?:\d{1,3}\.){3}\d{1,3}$/', $requestHost)) {
+            return false;
+        }
+        if ('.' != $cookieDomain[0]) {
+            $cookieDomain = '.' . $cookieDomain;
+        }
+        // prevents setting cookies for '.com' and similar domains
+        if (!$this->useList && substr_count($cookieDomain, '.') < 2
+            || $this->useList && !self::getRegisteredDomain($cookieDomain)
+        ) {
+            return false;
+        }
+        return substr('.' . $requestHost, -strlen($cookieDomain)) == $cookieDomain;
+    }
+
+   /**
+    * Removes subdomains to get the registered domain (the first after top-level)
+    *
+    * The method will check Public Suffix List to find out where top-level
+    * domain ends and registered domain starts. It will remove domain parts
+    * to the left of registered one.
+    *
+    * @param  string        domain name
+    * @return string|bool   registered domain, will return false if $domain is
+    *                       either invalid or a TLD itself
+    */
+    public static function getRegisteredDomain($domain)
+    {
+        $domainParts = explode('.', ltrim($domain, '.'));
+
+        // load the list if needed
+        if (empty(self::$psl)) {
+            $path = '/Library/WebServer/Documents/workspace/UCOMM_Webforms/lib/data' . DIRECTORY_SEPARATOR . 'HTTP_Request2';
+            if (0 === strpos($path, '@' . 'data_dir@')) {
+                $path = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'
+                                 . DIRECTORY_SEPARATOR . 'data');
+            }
+            self::$psl = include_once $path . DIRECTORY_SEPARATOR . 'public-suffix-list.php';
+        }
+
+        if (!($result = self::checkDomainsList($domainParts, self::$psl))) {
+            // known TLD, invalid domain name
+            return false;
+        }
+
+        // unknown TLD
+        if (!strpos($result, '.')) {
+            // fallback to checking that domain "has at least two dots"
+            if (2 > ($count = count($domainParts))) {
+                return false;
+            }
+            return $domainParts[$count - 2] . '.' . $domainParts[$count - 1];
+        }
+        return $result;
+    }
+
+   /**
+    * Recursive helper method for {@link getRegisteredDomain()}
+    *
+    * @param  array         remaining domain parts
+    * @param  mixed         node in {@link HTTP_Request2_CookieJar::$psl} to check
+    * @return string|null   concatenated domain parts, null in case of error
+    */
+    protected static function checkDomainsList(array $domainParts, $listNode)
+    {
+        $sub    = array_pop($domainParts);
+        $result = null;
+
+        if (!is_array($listNode) || is_null($sub)
+            || array_key_exists('!' . $sub, $listNode)
+         ) {
+            return $sub;
+
+        } elseif (array_key_exists($sub, $listNode)) {
+            $result = self::checkDomainsList($domainParts, $listNode[$sub]);
+
+        } elseif (array_key_exists('*', $listNode)) {
+            $result = self::checkDomainsList($domainParts, $listNode['*']);
+
+        } else {
+            return $sub;
+        }
+
+        return (strlen($result) > 0) ? ($result . '.' . $sub) : null;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/HTTP/Request2/Exception.php b/lib/php/HTTP/Request2/Exception.php
new file mode 100644
index 0000000..1bae2f1
--- /dev/null
+++ b/lib/php/HTTP/Request2/Exception.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Exception classes for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Exception.php 308629 2011-02-24 17:34:24Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for exceptions in PEAR
+ */
+require_once 'PEAR/Exception.php';
+
+/**
+ * Base exception class for HTTP_Request2 package
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @version    Release: 2.0.0beta3
+ * @link       http://pear.php.net/pepr/pepr-proposal-show.php?id=132
+ */
+class HTTP_Request2_Exception extends PEAR_Exception
+{
+    /** An invalid argument was passed to a method */
+    const INVALID_ARGUMENT   = 1;
+    /** Some required value was not available */
+    const MISSING_VALUE      = 2;
+    /** Request cannot be processed due to errors in PHP configuration */
+    const MISCONFIGURATION   = 3;
+    /** Error reading the local file */
+    const READ_ERROR         = 4;
+
+    /** Server returned a response that does not conform to HTTP protocol */
+    const MALFORMED_RESPONSE = 10;
+    /** Failure decoding Content-Encoding or Transfer-Encoding of response */
+    const DECODE_ERROR       = 20;
+    /** Operation timed out */
+    const TIMEOUT            = 30;
+    /** Number of redirects exceeded 'max_redirects' configuration parameter */
+    const TOO_MANY_REDIRECTS = 40;
+    /** Redirect to a protocol other than http(s):// */
+    const NON_HTTP_REDIRECT  = 50;
+
+   /**
+    * Native error code
+    * @var int
+    */
+    private $_nativeCode;
+
+   /**
+    * Constructor, can set package error code and native error code
+    *
+    * @param string exception message
+    * @param int    package error code, one of class constants
+    * @param int    error code from underlying PHP extension
+    */
+    public function __construct($message = null, $code = null, $nativeCode = null)
+    {
+        parent::__construct($message, $code);
+        $this->_nativeCode = $nativeCode;
+    }
+
+   /**
+    * Returns error code produced by underlying PHP extension
+    *
+    * For Socket Adapter this may contain error number returned by
+    * stream_socket_client(), for Curl Adapter this will contain error number
+    * returned by curl_errno()
+    *
+    * @return integer
+    */
+    public function getNativeCode()
+    {
+        return $this->_nativeCode;
+    }
+}
+
+/**
+ * Exception thrown in case of missing features
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @version    Release: 2.0.0beta3
+ */
+class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception {}
+
+/**
+ * Exception that represents error in the program logic
+ *
+ * This exception usually implies a programmer's error, like passing invalid
+ * data to methods or trying to use PHP extensions that weren't installed or
+ * enabled. Usually exceptions of this kind will be thrown before request even
+ * starts.
+ *
+ * The exception will usually contain a package error code.
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @version    Release: 2.0.0beta3
+ */
+class HTTP_Request2_LogicException extends HTTP_Request2_Exception {}
+
+/**
+ * Exception thrown when connection to a web or proxy server fails
+ *
+ * The exception will not contain a package error code, but will contain
+ * native error code, as returned by stream_socket_client() or curl_errno().
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @version    Release: 2.0.0beta3
+ */
+class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception {}
+
+/**
+ * Exception thrown when sending or receiving HTTP message fails
+ *
+ * The exception may contain both package error code and native error code.
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @version    Release: 2.0.0beta3
+ */
+class HTTP_Request2_MessageException extends HTTP_Request2_Exception {}
+?>
\ No newline at end of file
diff --git a/lib/php/HTTP/Request2/MultipartBody.php b/lib/php/HTTP/Request2/MultipartBody.php
new file mode 100644
index 0000000..57bc5d6
--- /dev/null
+++ b/lib/php/HTTP/Request2/MultipartBody.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * Helper class for building multipart/form-data request body
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: MultipartBody.php 308322 2011-02-14 13:58:03Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class for building multipart/form-data request body
+ *
+ * The class helps to reduce memory consumption by streaming large file uploads
+ * from disk, it also allows monitoring of upload progress (see request #7630)
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @version    Release: 2.0.0beta3
+ * @link       http://tools.ietf.org/html/rfc1867
+ */
+class HTTP_Request2_MultipartBody
+{
+   /**
+    * MIME boundary
+    * @var  string
+    */
+    private $_boundary;
+
+   /**
+    * Form parameters added via {@link HTTP_Request2::addPostParameter()}
+    * @var  array
+    */
+    private $_params = array();
+
+   /**
+    * File uploads added via {@link HTTP_Request2::addUpload()}
+    * @var  array
+    */
+    private $_uploads = array();
+
+   /**
+    * Header for parts with parameters
+    * @var  string
+    */
+    private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
+
+   /**
+    * Header for parts with uploads
+    * @var  string
+    */
+    private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
+
+   /**
+    * Current position in parameter and upload arrays
+    *
+    * First number is index of "current" part, second number is position within
+    * "current" part
+    *
+    * @var  array
+    */
+    private $_pos = array(0, 0);
+
+
+   /**
+    * Constructor. Sets the arrays with POST data.
+    *
+    * @param    array   values of form fields set via {@link HTTP_Request2::addPostParameter()}
+    * @param    array   file uploads set via {@link HTTP_Request2::addUpload()}
+    * @param    bool    whether to append brackets to array variable names
+    */
+    public function __construct(array $params, array $uploads, $useBrackets = true)
+    {
+        $this->_params = self::_flattenArray('', $params, $useBrackets);
+        foreach ($uploads as $fieldName => $f) {
+            if (!is_array($f['fp'])) {
+                $this->_uploads[] = $f + array('name' => $fieldName);
+            } else {
+                for ($i = 0; $i < count($f['fp']); $i++) {
+                    $upload = array(
+                        'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
+                    );
+                    foreach (array('fp', 'filename', 'size', 'type') as $key) {
+                        $upload[$key] = $f[$key][$i];
+                    }
+                    $this->_uploads[] = $upload;
+                }
+            }
+        }
+    }
+
+   /**
+    * Returns the length of the body to use in Content-Length header
+    *
+    * @return   integer
+    */
+    public function getLength()
+    {
+        $boundaryLength     = strlen($this->getBoundary());
+        $headerParamLength  = strlen($this->_headerParam) - 4 + $boundaryLength;
+        $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
+        $length             = $boundaryLength + 6;
+        foreach ($this->_params as $p) {
+            $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
+        }
+        foreach ($this->_uploads as $u) {
+            $length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
+                       strlen($u['filename']) + $u['size'] + 2;
+        }
+        return $length;
+    }
+
+   /**
+    * Returns the boundary to use in Content-Type header
+    *
+    * @return   string
+    */
+    public function getBoundary()
+    {
+        if (empty($this->_boundary)) {
+            $this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
+        }
+        return $this->_boundary;
+    }
+
+   /**
+    * Returns next chunk of request body
+    *
+    * @param    integer Amount of bytes to read
+    * @return   string  Up to $length bytes of data, empty string if at end
+    */
+    public function read($length)
+    {
+        $ret         = '';
+        $boundary    = $this->getBoundary();
+        $paramCount  = count($this->_params);
+        $uploadCount = count($this->_uploads);
+        while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
+            $oldLength = $length;
+            if ($this->_pos[0] < $paramCount) {
+                $param = sprintf($this->_headerParam, $boundary,
+                                 $this->_params[$this->_pos[0]][0]) .
+                         $this->_params[$this->_pos[0]][1] . "\r\n";
+                $ret    .= substr($param, $this->_pos[1], $length);
+                $length -= min(strlen($param) - $this->_pos[1], $length);
+
+            } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
+                $pos    = $this->_pos[0] - $paramCount;
+                $header = sprintf($this->_headerUpload, $boundary,
+                                  $this->_uploads[$pos]['name'],
+                                  $this->_uploads[$pos]['filename'],
+                                  $this->_uploads[$pos]['type']);
+                if ($this->_pos[1] < strlen($header)) {
+                    $ret    .= substr($header, $this->_pos[1], $length);
+                    $length -= min(strlen($header) - $this->_pos[1], $length);
+                }
+                $filePos  = max(0, $this->_pos[1] - strlen($header));
+                if ($length > 0 && $filePos < $this->_uploads[$pos]['size']) {
+                    $ret     .= fread($this->_uploads[$pos]['fp'], $length);
+                    $length  -= min($length, $this->_uploads[$pos]['size'] - $filePos);
+                }
+                if ($length > 0) {
+                    $start   = $this->_pos[1] + ($oldLength - $length) -
+                               strlen($header) - $this->_uploads[$pos]['size'];
+                    $ret    .= substr("\r\n", $start, $length);
+                    $length -= min(2 - $start, $length);
+                }
+
+            } else {
+                $closing  = '--' . $boundary . "--\r\n";
+                $ret     .= substr($closing, $this->_pos[1], $length);
+                $length  -= min(strlen($closing) - $this->_pos[1], $length);
+            }
+            if ($length > 0) {
+                $this->_pos     = array($this->_pos[0] + 1, 0);
+            } else {
+                $this->_pos[1] += $oldLength;
+            }
+        }
+        return $ret;
+    }
+
+   /**
+    * Sets the current position to the start of the body
+    *
+    * This allows reusing the same body in another request
+    */
+    public function rewind()
+    {
+        $this->_pos = array(0, 0);
+        foreach ($this->_uploads as $u) {
+            rewind($u['fp']);
+        }
+    }
+
+   /**
+    * Returns the body as string
+    *
+    * Note that it reads all file uploads into memory so it is a good idea not
+    * to use this method with large file uploads and rely on read() instead.
+    *
+    * @return   string
+    */
+    public function __toString()
+    {
+        $this->rewind();
+        return $this->read($this->getLength());
+    }
+
+
+   /**
+    * Helper function to change the (probably multidimensional) associative array
+    * into the simple one.
+    *
+    * @param    string  name for item
+    * @param    mixed   item's values
+    * @param    bool    whether to append [] to array variables' names
+    * @return   array   array with the following items: array('item name', 'item value');
+    */
+    private static function _flattenArray($name, $values, $useBrackets)
+    {
+        if (!is_array($values)) {
+            return array(array($name, $values));
+        } else {
+            $ret = array();
+            foreach ($values as $k => $v) {
+                if (empty($name)) {
+                    $newName = $k;
+                } elseif ($useBrackets) {
+                    $newName = $name . '[' . $k . ']';
+                } else {
+                    $newName = $name;
+                }
+                $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
+            }
+            return $ret;
+        }
+    }
+}
+?>
diff --git a/lib/php/HTTP/Request2/Observer/Log.php b/lib/php/HTTP/Request2/Observer/Log.php
new file mode 100644
index 0000000..237563d
--- /dev/null
+++ b/lib/php/HTTP/Request2/Observer/Log.php
@@ -0,0 +1,215 @@
+<?php
+/**
+ * An observer useful for debugging / testing.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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 HTTP
+ * @package  HTTP_Request2
+ * @author   David Jean Louis <izi@php.net>
+ * @author   Alexey Borzov <avb@php.net>
+ * @license  http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version  SVN: $Id: Log.php 308680 2011-02-25 17:40:17Z avb $
+ * @link     http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * A debug observer useful for debugging / testing.
+ *
+ * This observer logs to a log target data corresponding to the various request
+ * and response events, it logs by default to php://output but can be configured
+ * to log to a file or via the PEAR Log package.
+ *
+ * A simple example:
+ * <code>
+ * require_once 'HTTP/Request2.php';
+ * require_once 'HTTP/Request2/Observer/Log.php';
+ *
+ * $request  = new HTTP_Request2('http://www.example.com');
+ * $observer = new HTTP_Request2_Observer_Log();
+ * $request->attach($observer);
+ * $request->send();
+ * </code>
+ *
+ * A more complex example with PEAR Log:
+ * <code>
+ * require_once 'HTTP/Request2.php';
+ * require_once 'HTTP/Request2/Observer/Log.php';
+ * require_once 'Log.php';
+ *
+ * $request  = new HTTP_Request2('http://www.example.com');
+ * // we want to log with PEAR log
+ * $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
+ *
+ * // we only want to log received headers
+ * $observer->events = array('receivedHeaders');
+ *
+ * $request->attach($observer);
+ * $request->send();
+ * </code>
+ *
+ * @category HTTP
+ * @package  HTTP_Request2
+ * @author   David Jean Louis <izi@php.net>
+ * @author   Alexey Borzov <avb@php.net>
+ * @license  http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version  Release: 2.0.0beta3
+ * @link     http://pear.php.net/package/HTTP_Request2
+ */
+class HTTP_Request2_Observer_Log implements SplObserver
+{
+    // properties {{{
+
+    /**
+     * The log target, it can be a a resource or a PEAR Log instance.
+     *
+     * @var resource|Log $target
+     */
+    protected $target = null;
+
+    /**
+     * The events to log.
+     *
+     * @var array $events
+     */
+    public $events = array(
+        'connect',
+        'sentHeaders',
+        'sentBody',
+        'receivedHeaders',
+        'receivedBody',
+        'disconnect',
+    );
+
+    // }}}
+    // __construct() {{{
+
+    /**
+     * Constructor.
+     *
+     * @param mixed $target Can be a file path (default: php://output), a resource,
+     *                      or an instance of the PEAR Log class.
+     * @param array $events Array of events to listen to (default: all events)
+     *
+     * @return void
+     */
+    public function __construct($target = 'php://output', array $events = array())
+    {
+        if (!empty($events)) {
+            $this->events = $events;
+        }
+        if (is_resource($target) || $target instanceof Log) {
+            $this->target = $target;
+        } elseif (false === ($this->target = @fopen($target, 'ab'))) {
+            throw new HTTP_Request2_Exception("Unable to open '{$target}'");
+        }
+    }
+
+    // }}}
+    // update() {{{
+
+    /**
+     * Called when the request notifies us of an event.
+     *
+     * @param HTTP_Request2 $subject The HTTP_Request2 instance
+     *
+     * @return void
+     */
+    public function update(SplSubject $subject)
+    {
+        $event = $subject->getLastEvent();
+        if (!in_array($event['name'], $this->events)) {
+            return;
+        }
+
+        switch ($event['name']) {
+        case 'connect':
+            $this->log('* Connected to ' . $event['data']);
+            break;
+        case 'sentHeaders':
+            $headers = explode("\r\n", $event['data']);
+            array_pop($headers);
+            foreach ($headers as $header) {
+                $this->log('> ' . $header);
+            }
+            break;
+        case 'sentBody':
+            $this->log('> ' . $event['data'] . ' byte(s) sent');
+            break;
+        case 'receivedHeaders':
+            $this->log(sprintf('< HTTP/%s %s %s',
+                $event['data']->getVersion(),
+                $event['data']->getStatus(),
+                $event['data']->getReasonPhrase()));
+            $headers = $event['data']->getHeader();
+            foreach ($headers as $key => $val) {
+                $this->log('< ' . $key . ': ' . $val);
+            }
+            $this->log('< ');
+            break;
+        case 'receivedBody':
+            $this->log($event['data']->getBody());
+            break;
+        case 'disconnect':
+            $this->log('* Disconnected');
+            break;
+        }
+    }
+
+    // }}}
+    // log() {{{
+
+    /**
+     * Logs the given message to the configured target.
+     *
+     * @param string $message Message to display
+     *
+     * @return void
+     */
+    protected function log($message)
+    {
+        if ($this->target instanceof Log) {
+            $this->target->debug($message);
+        } elseif (is_resource($this->target)) {
+            fwrite($this->target, $message . "\r\n");
+        }
+    }
+
+    // }}}
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/HTTP/Request2/Response.php b/lib/php/HTTP/Request2/Response.php
new file mode 100644
index 0000000..35a5ad8
--- /dev/null
+++ b/lib/php/HTTP/Request2/Response.php
@@ -0,0 +1,629 @@
+<?php
+/**
+ * Class representing a HTTP response
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Response.php 309921 2011-04-03 16:43:02Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Exception class for HTTP_Request2 package
+ */
+require_once 'HTTP/Request2/Exception.php';
+
+/**
+ * Class representing a HTTP response
+ *
+ * The class is designed to be used in "streaming" scenario, building the
+ * response as it is being received:
+ * <code>
+ * $statusLine = read_status_line();
+ * $response = new HTTP_Request2_Response($statusLine);
+ * do {
+ *     $headerLine = read_header_line();
+ *     $response->parseHeaderLine($headerLine);
+ * } while ($headerLine != '');
+ *
+ * while ($chunk = read_body()) {
+ *     $response->appendBody($chunk);
+ * }
+ *
+ * var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
+ * </code>
+ *
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @version    Release: 2.0.0beta3
+ * @link       http://tools.ietf.org/html/rfc2616#section-6
+ */
+class HTTP_Request2_Response
+{
+   /**
+    * HTTP protocol version (e.g. 1.0, 1.1)
+    * @var  string
+    */
+    protected $version;
+
+   /**
+    * Status code
+    * @var  integer
+    * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
+    */
+    protected $code;
+
+   /**
+    * Reason phrase
+    * @var  string
+    * @link http://tools.ietf.org/html/rfc2616#section-6.1.1
+    */
+    protected $reasonPhrase;
+
+   /**
+    * Effective URL (may be different from original request URL in case of redirects)
+    * @var  string
+    */
+    protected $effectiveUrl;
+
+   /**
+    * Associative array of response headers
+    * @var  array
+    */
+    protected $headers = array();
+
+   /**
+    * Cookies set in the response
+    * @var  array
+    */
+    protected $cookies = array();
+
+   /**
+    * Name of last header processed by parseHederLine()
+    *
+    * Used to handle the headers that span multiple lines
+    *
+    * @var  string
+    */
+    protected $lastHeader = null;
+
+   /**
+    * Response body
+    * @var  string
+    */
+    protected $body = '';
+
+   /**
+    * Whether the body is still encoded by Content-Encoding
+    *
+    * cURL provides the decoded body to the callback; if we are reading from
+    * socket the body is still gzipped / deflated
+    *
+    * @var  bool
+    */
+    protected $bodyEncoded;
+
+   /**
+    * Associative array of HTTP status code / reason phrase.
+    *
+    * @var  array
+    * @link http://tools.ietf.org/html/rfc2616#section-10
+    */
+    protected static $phrases = array(
+
+        // 1xx: Informational - Request received, continuing process
+        100 => 'Continue',
+        101 => 'Switching Protocols',
+
+        // 2xx: Success - The action was successfully received, understood and
+        // accepted
+        200 => 'OK',
+        201 => 'Created',
+        202 => 'Accepted',
+        203 => 'Non-Authoritative Information',
+        204 => 'No Content',
+        205 => 'Reset Content',
+        206 => 'Partial Content',
+
+        // 3xx: Redirection - Further action must be taken in order to complete
+        // the request
+        300 => 'Multiple Choices',
+        301 => 'Moved Permanently',
+        302 => 'Found',  // 1.1
+        303 => 'See Other',
+        304 => 'Not Modified',
+        305 => 'Use Proxy',
+        307 => 'Temporary Redirect',
+
+        // 4xx: Client Error - The request contains bad syntax or cannot be
+        // fulfilled
+        400 => 'Bad Request',
+        401 => 'Unauthorized',
+        402 => 'Payment Required',
+        403 => 'Forbidden',
+        404 => 'Not Found',
+        405 => 'Method Not Allowed',
+        406 => 'Not Acceptable',
+        407 => 'Proxy Authentication Required',
+        408 => 'Request Timeout',
+        409 => 'Conflict',
+        410 => 'Gone',
+        411 => 'Length Required',
+        412 => 'Precondition Failed',
+        413 => 'Request Entity Too Large',
+        414 => 'Request-URI Too Long',
+        415 => 'Unsupported Media Type',
+        416 => 'Requested Range Not Satisfiable',
+        417 => 'Expectation Failed',
+
+        // 5xx: Server Error - The server failed to fulfill an apparently
+        // valid request
+        500 => 'Internal Server Error',
+        501 => 'Not Implemented',
+        502 => 'Bad Gateway',
+        503 => 'Service Unavailable',
+        504 => 'Gateway Timeout',
+        505 => 'HTTP Version Not Supported',
+        509 => 'Bandwidth Limit Exceeded',
+
+    );
+
+   /**
+    * Constructor, parses the response status line
+    *
+    * @param    string Response status line (e.g. "HTTP/1.1 200 OK")
+    * @param    bool   Whether body is still encoded by Content-Encoding
+    * @param    string Effective URL of the response
+    * @throws   HTTP_Request2_MessageException if status line is invalid according to spec
+    */
+    public function __construct($statusLine, $bodyEncoded = true, $effectiveUrl = null)
+    {
+        if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
+            throw new HTTP_Request2_MessageException(
+                "Malformed response: {$statusLine}",
+                HTTP_Request2_Exception::MALFORMED_RESPONSE
+            );
+        }
+        $this->version = $m[1];
+        $this->code    = intval($m[2]);
+        if (!empty($m[3])) {
+            $this->reasonPhrase = trim($m[3]);
+        } elseif (!empty(self::$phrases[$this->code])) {
+            $this->reasonPhrase = self::$phrases[$this->code];
+        }
+        $this->bodyEncoded  = (bool)$bodyEncoded;
+        $this->effectiveUrl = (string)$effectiveUrl;
+    }
+
+   /**
+    * Parses the line from HTTP response filling $headers array
+    *
+    * The method should be called after reading the line from socket or receiving
+    * it into cURL callback. Passing an empty string here indicates the end of
+    * response headers and triggers additional processing, so be sure to pass an
+    * empty string in the end.
+    *
+    * @param    string  Line from HTTP response
+    */
+    public function parseHeaderLine($headerLine)
+    {
+        $headerLine = trim($headerLine, "\r\n");
+
+        // empty string signals the end of headers, process the received ones
+        if ('' == $headerLine) {
+            if (!empty($this->headers['set-cookie'])) {
+                $cookies = is_array($this->headers['set-cookie'])?
+                           $this->headers['set-cookie']:
+                           array($this->headers['set-cookie']);
+                foreach ($cookies as $cookieString) {
+                    $this->parseCookie($cookieString);
+                }
+                unset($this->headers['set-cookie']);
+            }
+            foreach (array_keys($this->headers) as $k) {
+                if (is_array($this->headers[$k])) {
+                    $this->headers[$k] = implode(', ', $this->headers[$k]);
+                }
+            }
+
+        // string of the form header-name: header value
+        } elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
+            $name  = strtolower($m[1]);
+            $value = trim($m[2]);
+            if (empty($this->headers[$name])) {
+                $this->headers[$name] = $value;
+            } else {
+                if (!is_array($this->headers[$name])) {
+                    $this->headers[$name] = array($this->headers[$name]);
+                }
+                $this->headers[$name][] = $value;
+            }
+            $this->lastHeader = $name;
+
+        // continuation of a previous header
+        } elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
+            if (!is_array($this->headers[$this->lastHeader])) {
+                $this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
+            } else {
+                $key = count($this->headers[$this->lastHeader]) - 1;
+                $this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
+            }
+        }
+    }
+
+   /**
+    * Parses a Set-Cookie header to fill $cookies array
+    *
+    * @param    string    value of Set-Cookie header
+    * @link     http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
+    */
+    protected function parseCookie($cookieString)
+    {
+        $cookie = array(
+            'expires' => null,
+            'domain'  => null,
+            'path'    => null,
+            'secure'  => false
+        );
+
+        // Only a name=value pair
+        if (!strpos($cookieString, ';')) {
+            $pos = strpos($cookieString, '=');
+            $cookie['name']  = trim(substr($cookieString, 0, $pos));
+            $cookie['value'] = trim(substr($cookieString, $pos + 1));
+
+        // Some optional parameters are supplied
+        } else {
+            $elements = explode(';', $cookieString);
+            $pos = strpos($elements[0], '=');
+            $cookie['name']  = trim(substr($elements[0], 0, $pos));
+            $cookie['value'] = trim(substr($elements[0], $pos + 1));
+
+            for ($i = 1; $i < count($elements); $i++) {
+                if (false === strpos($elements[$i], '=')) {
+                    $elName  = trim($elements[$i]);
+                    $elValue = null;
+                } else {
+                    list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
+                }
+                $elName = strtolower($elName);
+                if ('secure' == $elName) {
+                    $cookie['secure'] = true;
+                } elseif ('expires' == $elName) {
+                    $cookie['expires'] = str_replace('"', '', $elValue);
+                } elseif ('path' == $elName || 'domain' == $elName) {
+                    $cookie[$elName] = urldecode($elValue);
+                } else {
+                    $cookie[$elName] = $elValue;
+                }
+            }
+        }
+        $this->cookies[] = $cookie;
+    }
+
+   /**
+    * Appends a string to the response body
+    * @param    string
+    */
+    public function appendBody($bodyChunk)
+    {
+        $this->body .= $bodyChunk;
+    }
+
+   /**
+    * Returns the effective URL of the response
+    *
+    * This may be different from the request URL if redirects were followed.
+    *
+    * @return string
+    * @link   http://pear.php.net/bugs/bug.php?id=18412
+    */
+    public function getEffectiveUrl()
+    {
+        return $this->effectiveUrl;
+    }
+
+   /**
+    * Returns the status code
+    * @return   integer
+    */
+    public function getStatus()
+    {
+        return $this->code;
+    }
+
+   /**
+    * Returns the reason phrase
+    * @return   string
+    */
+    public function getReasonPhrase()
+    {
+        return $this->reasonPhrase;
+    }
+
+   /**
+    * Whether response is a redirect that can be automatically handled by HTTP_Request2
+    * @return   bool
+    */
+    public function isRedirect()
+    {
+        return in_array($this->code, array(300, 301, 302, 303, 307))
+               && isset($this->headers['location']);
+    }
+
+   /**
+    * Returns either the named header or all response headers
+    *
+    * @param    string          Name of header to return
+    * @return   string|array    Value of $headerName header (null if header is
+    *                           not present), array of all response headers if
+    *                           $headerName is null
+    */
+    public function getHeader($headerName = null)
+    {
+        if (null === $headerName) {
+            return $this->headers;
+        } else {
+            $headerName = strtolower($headerName);
+            return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
+        }
+    }
+
+   /**
+    * Returns cookies set in response
+    *
+    * @return   array
+    */
+    public function getCookies()
+    {
+        return $this->cookies;
+    }
+
+   /**
+    * Returns the body of the response
+    *
+    * @return   string
+    * @throws   HTTP_Request2_Exception if body cannot be decoded
+    */
+    public function getBody()
+    {
+        if (0 == strlen($this->body) || !$this->bodyEncoded ||
+            !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
+        ) {
+            return $this->body;
+
+        } else {
+            if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
+                $oldEncoding = mb_internal_encoding();
+                mb_internal_encoding('iso-8859-1');
+            }
+
+            try {
+                switch (strtolower($this->getHeader('content-encoding'))) {
+                    case 'gzip':
+                        $decoded = self::decodeGzip($this->body);
+                        break;
+                    case 'deflate':
+                        $decoded = self::decodeDeflate($this->body);
+                }
+            } catch (Exception $e) {
+            }
+
+            if (!empty($oldEncoding)) {
+                mb_internal_encoding($oldEncoding);
+            }
+            if (!empty($e)) {
+                throw $e;
+            }
+            return $decoded;
+        }
+    }
+
+   /**
+    * Get the HTTP version of the response
+    *
+    * @return   string
+    */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+   /**
+    * Decodes the message-body encoded by gzip
+    *
+    * The real decoding work is done by gzinflate() built-in function, this
+    * method only parses the header and checks data for compliance with
+    * RFC 1952
+    *
+    * @param    string  gzip-encoded data
+    * @return   string  decoded data
+    * @throws   HTTP_Request2_LogicException
+    * @throws   HTTP_Request2_MessageException
+    * @link     http://tools.ietf.org/html/rfc1952
+    */
+    public static function decodeGzip($data)
+    {
+        $length = strlen($data);
+        // If it doesn't look like gzip-encoded data, don't bother
+        if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
+            return $data;
+        }
+        if (!function_exists('gzinflate')) {
+            throw new HTTP_Request2_LogicException(
+                'Unable to decode body: gzip extension not available',
+                HTTP_Request2_Exception::MISCONFIGURATION
+            );
+        }
+        $method = ord(substr($data, 2, 1));
+        if (8 != $method) {
+            throw new HTTP_Request2_MessageException(
+                'Error parsing gzip header: unknown compression method',
+                HTTP_Request2_Exception::DECODE_ERROR
+            );
+        }
+        $flags = ord(substr($data, 3, 1));
+        if ($flags & 224) {
+            throw new HTTP_Request2_MessageException(
+                'Error parsing gzip header: reserved bits are set',
+                HTTP_Request2_Exception::DECODE_ERROR
+            );
+        }
+
+        // header is 10 bytes minimum. may be longer, though.
+        $headerLength = 10;
+        // extra fields, need to skip 'em
+        if ($flags & 4) {
+            if ($length - $headerLength - 2 < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $extraLength = unpack('v', substr($data, 10, 2));
+            if ($length - $headerLength - 2 - $extraLength[1] < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $headerLength += $extraLength[1] + 2;
+        }
+        // file name, need to skip that
+        if ($flags & 8) {
+            if ($length - $headerLength - 1 < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $filenameLength = strpos(substr($data, $headerLength), chr(0));
+            if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $headerLength += $filenameLength + 1;
+        }
+        // comment, need to skip that also
+        if ($flags & 16) {
+            if ($length - $headerLength - 1 < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $commentLength = strpos(substr($data, $headerLength), chr(0));
+            if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $headerLength += $commentLength + 1;
+        }
+        // have a CRC for header. let's check
+        if ($flags & 2) {
+            if ($length - $headerLength - 2 < 8) {
+                throw new HTTP_Request2_MessageException(
+                    'Error parsing gzip header: data too short',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $crcReal   = 0xffff & crc32(substr($data, 0, $headerLength));
+            $crcStored = unpack('v', substr($data, $headerLength, 2));
+            if ($crcReal != $crcStored[1]) {
+                throw new HTTP_Request2_MessageException(
+                    'Header CRC check failed',
+                    HTTP_Request2_Exception::DECODE_ERROR
+                );
+            }
+            $headerLength += 2;
+        }
+        // unpacked data CRC and size at the end of encoded data
+        $tmp = unpack('V2', substr($data, -8));
+        $dataCrc  = $tmp[1];
+        $dataSize = $tmp[2];
+
+        // finally, call the gzinflate() function
+        // don't pass $dataSize to gzinflate, see bugs #13135, #14370
+        $unpacked = gzinflate(substr($data, $headerLength, -8));
+        if (false === $unpacked) {
+            throw new HTTP_Request2_MessageException(
+                'gzinflate() call failed',
+                HTTP_Request2_Exception::DECODE_ERROR
+            );
+        } elseif ($dataSize != strlen($unpacked)) {
+            throw new HTTP_Request2_MessageException(
+                'Data size check failed',
+                HTTP_Request2_Exception::DECODE_ERROR
+            );
+        } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
+            throw new HTTP_Request2_Exception(
+                'Data CRC check failed',
+                HTTP_Request2_Exception::DECODE_ERROR
+            );
+        }
+        return $unpacked;
+    }
+
+   /**
+    * Decodes the message-body encoded by deflate
+    *
+    * @param    string  deflate-encoded data
+    * @return   string  decoded data
+    * @throws   HTTP_Request2_LogicException
+    */
+    public static function decodeDeflate($data)
+    {
+        if (!function_exists('gzuncompress')) {
+            throw new HTTP_Request2_LogicException(
+                'Unable to decode body: gzip extension not available',
+                HTTP_Request2_Exception::MISCONFIGURATION
+            );
+        }
+        // RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
+        // while many applications send raw deflate stream from RFC 1951.
+        // We should check for presence of zlib header and use gzuncompress() or
+        // gzinflate() as needed. See bug #15305
+        $header = unpack('n', substr($data, 0, 2));
+        return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/Net/URL2.php b/lib/php/Net/URL2.php
new file mode 100644
index 0000000..bbc9f12
--- /dev/null
+++ b/lib/php/Net/URL2.php
@@ -0,0 +1,894 @@
+<?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 290036 2009-10-28 19:52:49Z schmidt $
+ * @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
+     */
+    public function __construct($url, array $options = array())
+    {
+        foreach ($options as $optionName => $value) {
+            if (array_key_exists($optionName, $this->_options)) {
+                $this->_options[$optionName] = $value;
+            }
+        }
+
+        // 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;
+    }
+
+    /**
+     * 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 void
+     * @see    getScheme()
+     */
+    public function setScheme($scheme)
+    {
+        $this->_scheme = $scheme;
+    }
+
+    /**
+     * 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 void
+     */
+    public function setUserinfo($userinfo, $password = false)
+    {
+        $this->_userinfo = $userinfo;
+        if ($password !== false) {
+            $this->_userinfo .= ':' . $password;
+        }
+    }
+
+    /**
+     * 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 void
+     */
+    public function setHost($host)
+    {
+        $this->_host = $host;
+    }
+
+    /**
+     * 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 void
+     */
+    public function setPort($port)
+    {
+        $this->_port = $port;
+    }
+
+    /**
+     * 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 void
+     */
+    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];
+            }
+        }
+    }
+
+    /**
+     * 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 void
+     */
+    public function setPath($path)
+    {
+        $this->_path = $path;
+    }
+
+    /**
+     * 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 void
+     * @see   self::setQueryVariables()
+     */
+    public function setQuery($query)
+    {
+        $this->_query = $query;
+    }
+
+    /**
+     * 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 void
+     */
+    public function setFragment($fragment)
+    {
+        $this->_fragment = $fragment;
+    }
+
+    /**
+     * 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 void
+     */
+    public function setQueryVariables(array $array)
+    {
+        if (!$array) {
+            $this->_query = false;
+        } else {
+            foreach ($array as $name => $value) {
+                if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
+                    $name = self::urlencode($name);
+                }
+
+                if (is_array($value)) {
+                    foreach ($value as $k => $v) {
+                        $parts[] = $this->getOption(self::OPTION_USE_BRACKETS)
+                            ? sprintf('%s[%s]=%s', $name, $k, $v)
+                            : ($name . '=' . $v);
+                    }
+                } elseif (!is_null($value)) {
+                    $parts[] = $name . '=' . self::urlencode($value);
+                } else {
+                    $parts[] = $name;
+                }
+            }
+            $this->_query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT),
+                                    $parts);
+        }
+    }
+
+    /**
+     * Sets the specified variable in the query string.
+     *
+     * @param string $name  variable name
+     * @param mixed  $value variable value
+     *
+     * @return  array
+     */
+    public function setQueryVariable($name, $value)
+    {
+        $array = $this->getQueryVariables();
+        $array[$name] = $value;
+        $this->setQueryVariables($array);
+    }
+
+    /**
+     * 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
+     */
+    function getOption($optionName)
+    {
+        return isset($this->_options[$optionName])
+            ? $this->_options[$optionName] : false;
+    }
+}
diff --git a/lib/php/SimpleCAS.php b/lib/php/SimpleCAS.php
new file mode 100644
index 0000000..6de5c28
--- /dev/null
+++ b/lib/php/SimpleCAS.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * This is a CAS client authentication library for PHP 5.
+ * 
+ * <code>
+ * <?php
+ * $protocol = new SimpleCAS_Protocol_Version2('login.unl.edu', 443, 'cas');
+ * $client = SimpleCAS::client($protocol);
+ * $client->forceAuthentication();
+ * 
+ * if (isset($_GET['logout'])) {
+ *     $client->logout();
+ * }
+ * 
+ * if ($client->isAuthenticated()) {
+ *     echo '<h1>Authentication Successful!</h1>';
+ *     echo '<p>The user\'s login is '.$client->getUsername().'</p>';
+ *     echo '<a href="?logout">Logout</a>';
+ * }
+ * </code>
+ * 
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   SimpleCAS
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://code.google.com/p/simplecas/
+ */
+class SimpleCAS
+{
+    /**
+     * Version of the CAS library.
+     */
+    const VERSION = '0.0.1';
+    
+    /**
+     * Singleton CAS object
+     *
+     * @var CAS
+     */
+    static private $_instance;
+    
+    /**
+     * Is user authenticated?
+     *
+     * @var bool
+     */
+    private $_authenticated = false;
+    
+    /**
+     * Protocol for the server running the CAS service.
+     *
+     * @var SimpleCAS_Protocol
+     */
+    protected $protocol;
+    
+    /**
+     * User's login name if authenticated.
+     *
+     * @var string
+     */
+    protected $username;
+
+    /**
+     * (Optional) alternative service URL to return to after CAS authentication.
+     *
+     * @var string
+     */
+    static protected $url;
+    
+    /**
+     * Construct a CAS client object.
+     *
+     * @param SimpleCAS_Protocol $protocol Protocol to use for authentication.
+     */
+    private function __construct(SimpleCAS_Protocol $protocol)
+    {
+        $this->protocol = $protocol;
+        
+        if ($this->protocol instanceof SimpleCAS_SingleSignOut
+            && isset($_POST)) {
+            if ($ticket = $this->protocol->validateLogoutRequest($_POST)) {
+                $this->logout($ticket);
+            }
+        }
+        
+        if (session_id() == '') {
+            session_start();
+        }
+        
+        if (isset($_SESSION['__SIMPLECAS_TICKET'])) {
+            $this->_authenticated = true;
+        }
+        
+        
+        if ($this->_authenticated == false
+            && isset($_GET['ticket'])) {
+            $this->validateTicket($_GET['ticket']);
+        }
+    }
+    
+    /**
+     * Checks a ticket to see if it is valid.
+     * 
+     * If the CAS server verifies the ticket, a session is created and the user
+     * is marked as authenticated.
+     *
+     * @param string $ticket Ticket from the CAS Server
+     * 
+     * @return bool
+     */
+    protected function validateTicket($ticket)
+    {
+        if ($uid = $this->protocol->validateTicket($ticket, self::getURL())) {
+            $this->setAuthenticated($uid);
+            $this->redirect(self::getURL());
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Marks the current session as authenticated.
+     *
+     * @param string $uid User name returned by the CAS server.
+     * 
+     * @return void
+     */
+    protected function setAuthenticated($uid)
+    {
+        $_SESSION['__SIMPLECAS_TICKET'] = true;
+        $_SESSION['__SIMPLECAS_UID']    = $uid;
+        $this->_authenticated           = true;
+    }
+    
+    /**
+     * Return the authenticated user's login name.
+     *
+     * @return string
+     */
+    public function getUsername()
+    {
+        return $_SESSION['__SIMPLECAS_UID'];
+    }
+    
+    /**
+     * Singleton interface, returns CAS object.
+     * 
+     * @param CAS_Server $server CAS Server object
+     * 
+     * @return CAS
+     */
+    static public function client(SimpleCAS_Protocol $protocol)
+    {
+        if (!isset(self::$_instance)) {
+            self::$_instance = new self($protocol);
+        }
+        
+        return self::$_instance;
+    }
+    
+    /**
+     * If client is not authenticated, this will redirecting to login and exit.
+     * 
+     * Otherwise, return the CAS object.
+     *
+     * @return CAS
+     */
+    function forceAuthentication()
+    {
+        if (!$this->isAuthenticated()) {
+            self::redirect($this->protocol->getLoginURL(self::getURL()));
+        }
+        return $this;
+    }
+    
+    /**
+     * Check if this user has been authenticated or not.
+     * 
+     * @return bool
+     */
+    function isAuthenticated()
+    {
+        return $this->_authenticated;
+    }
+    
+    /**
+     * Destroys session data for this client, redirects to the server logout
+     * url.
+     * 
+     * @param string $url URL to provide the client on logout.
+     * 
+     * @return void
+     */
+    public function logout($url = '')
+    {
+        session_destroy();
+        if (empty($url)) {
+            $url = self::getURL();
+        }
+        $this->redirect($this->protocol->getLogoutURL($url));
+    }
+    
+    /**
+     * Returns the current URL without CAS affecting parameters.
+     * 
+     * @return string url
+     */
+    static public function getURL()
+    {
+        if (!empty(self::$url)) {
+            return self::$url;
+        }
+        if (isset($_SERVER['HTTPS'])
+            && !empty($_SERVER['HTTPS'])
+            && $_SERVER['HTTPS'] == 'on') {
+            $protocol = 'https';
+        } else {
+            $protocol = 'http';
+        }
+    
+        $url = $protocol.'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
+        
+        $replacements = array('/\?logout/'        => '',
+                              '/&ticket=[^&]*/'   => '',
+                              '/\?ticket=[^&;]*/' => '?',
+                              '/\?%26/'           => '?',
+                              '/\?&/'             => '?',
+                              '/\?$/'             => '');
+        
+        $url = preg_replace(array_keys($replacements),
+                            array_values($replacements), $url);
+        
+        return $url;
+    }
+    
+   /**
+    * Set an alternative return URL
+    * 
+    * @param string $url alternative return URL
+    * 
+    * @return void
+    */ 
+    public static function setURL($url)
+    {
+        self::$url = $url; 
+    }
+    
+    /**
+     * Send a header to redirect the client to another URL.
+     *
+     * @param string $url URL to redirect the client to.
+     * 
+     * @return void
+     */
+    public static function redirect($url)
+    {
+        header("Location: $url");
+        exit();
+    }
+    
+    /**
+     * Get the version of the CAS library
+     *
+     * @return string
+     */
+    static public function getVersion()
+    {
+        return self::VERSION;
+    }
+}
diff --git a/lib/php/SimpleCAS/Autoload.php b/lib/php/SimpleCAS/Autoload.php
new file mode 100644
index 0000000..b26f5a0
--- /dev/null
+++ b/lib/php/SimpleCAS/Autoload.php
@@ -0,0 +1,62 @@
+<?php
+function SimpleCAS_Autoload($class)
+{
+    if (substr($class, 0, 9) !== 'SimpleCAS') {
+        return false;
+    }
+    $fp = @fopen(str_replace('_', '/', $class) . '.php', 'r', true);
+    if ($fp) {
+        fclose($fp);
+        require str_replace('_', '/', $class) . '.php';
+        if (!class_exists($class, false) && !interface_exists($class, false)) {
+            die(new Exception('Class ' . $class . ' was not present in ' .
+                str_replace('_', '/', $class) . '.php (include_path="' . get_include_path() .
+                '") [SimpleCAS_Autoload version 0.1.0]'));
+        }
+        return true;
+    }
+    $e = new Exception('Class ' . $class . ' could not be loaded from ' .
+        str_replace('_', '/', $class) . '.php, file does not exist (include_path="' . get_include_path() .
+        '") [SimpleCAS_Autoload version 0.1.0]');
+    $trace = $e->getTrace();
+    if (isset($trace[2]) && isset($trace[2]['function']) &&
+          in_array($trace[2]['function'], array('class_exists', 'interface_exists'))) {
+        return false;
+    }
+    if (isset($trace[1]) && isset($trace[1]['function']) &&
+          in_array($trace[1]['function'], array('class_exists', 'interface_exists'))) {
+        return false;
+    }
+    die ((string) $e);
+}
+
+// set up __autoload
+if (function_exists('spl_autoload_register')) {
+    if (!($_____t = spl_autoload_functions()) || !in_array('SimpleCAS_Autoload', spl_autoload_functions())) {
+        spl_autoload_register('SimpleCAS_Autoload');
+        if (function_exists('__autoload') && ($_____t === false)) {
+            // __autoload() was being used, but now would be ignored, add
+            // it to the autoload stack
+            spl_autoload_register('__autoload');
+        }
+    }
+    unset($_____t);
+} elseif (!function_exists('__autoload')) {
+    function __autoload($class) { return SimpleCAS_Autoload($class); }
+}
+
+// set up include_path if it doesn't register our current location
+$____paths = explode(PATH_SEPARATOR, get_include_path());
+$____found = false;
+foreach ($____paths as $____path) {
+    if ($____path == dirname(dirname(__FILE__))) {
+        $____found = true;
+        break;
+    }
+}
+if (!$____found) {
+    set_include_path(get_include_path() . PATH_SEPARATOR . dirname(dirname(__FILE__)));
+}
+unset($____paths);
+unset($____path);
+unset($____found);
diff --git a/lib/php/SimpleCAS/Protocol.php b/lib/php/SimpleCAS/Protocol.php
new file mode 100644
index 0000000..d050a6d
--- /dev/null
+++ b/lib/php/SimpleCAS/Protocol.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Interface all CAS servers must implement.
+ * 
+ * Each concrete class which implements this server interface must provide
+ * all the following functions.
+ * 
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   SimpleCAS
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://code.google.com/p/simplecas/
+ */
+abstract class SimpleCAS_Protocol
+{
+    const DEFAULT_REQUEST_CLASS = 'HTTP_Request2';
+    
+    protected $requestClass;
+    protected $request;
+    
+    /**
+     * Returns the login URL for the cas server.
+     *
+     * @param string $service The URL to the service requesting authentication.
+     * 
+     * @return string
+     */
+    abstract function getLoginURL($service);
+    
+    /**
+     * Returns the logout url for the CAS server.
+     *
+     * @param string $service A URL to provide the user upon logout.
+     * 
+     * @return string
+     */
+    abstract function getLogoutURL($service = null);
+    
+    /**
+     * Returns the version of this cas server.
+     * 
+     * @return string
+     */
+    abstract function getVersion();
+    
+    /**
+     * Function to validate a ticket and service combination.
+     *
+     * @param string $ticket  Ticket given by the CAS Server
+     * @param string $service Service requesting authentication
+     * 
+     * @return false|string False on failure, user name on success.
+     */
+    abstract function validateTicket($ticket, $service);
+    
+    /**
+     * Get the HTTP_Request2 object.
+     *
+     * @return HTTP_Request
+     */
+    function getRequest()
+    {
+        $class = empty($this->requestClass) ? self::DEFAULT_REQUEST_CLASS : $this->requestClass;
+        if (!$this->request instanceof $class) {
+            $this->request = new $class();
+        }
+        return $this->request; 
+    }
+    
+    /**
+     * Set the HTTP Request object.
+     *
+     * @param $request
+     */
+    function setRequest($request)
+    {
+        $this->request = $request;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/Protocol/Version1.php b/lib/php/SimpleCAS/Protocol/Version1.php
new file mode 100644
index 0000000..7879522
--- /dev/null
+++ b/lib/php/SimpleCAS/Protocol/Version1.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Class representing a CAS server which supports the CAS1 protocol.
+ * 
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   SimpleCAS
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://code.google.com/p/simplecas/
+ */
+class SimpleCAS_Protocol_Version1 extends SimpleCAS_Protocol
+{
+    const VERSION = '1.0';
+    
+    protected $request;
+    
+    /**
+     * Construct a new SimpleCAS server object.
+     *
+     *  <code>
+     *  $options = array('hostname' => 'login.unl.edu',
+     *                   'port'     => 443,
+     *                   'uri'      => 'cas');
+     *  $protocol = new SimpleCAS_Protocol_Version1($options);
+     *  </code>
+     *
+     * @param array()
+     */
+    function __construct($options)
+    {
+        foreach ($options as $option=>$val) {
+            $this->$option = $val;
+        }
+    }
+    
+    /**
+     * Returns the URL used to validate a ticket.
+     *
+     * @param string $ticket  Ticket to validate
+     * @param string $service URL to the service requesting authentication
+     * 
+     * @return string
+     */
+    function getValidationURL($ticket, $service)
+    {
+        return 'https://' . $this->hostname . '/'
+                          . $this->uri . '/validate?'
+                          . 'service=' . urlencode($service)
+                          . '&ticket=' . $ticket;
+    }
+    
+    /**
+     * Returns the URL to login form for the CAS server.
+     *
+     * @param string $service Service url requesting authentication.
+     * 
+     * @return string
+     */
+    function getLoginURL($service)
+    {
+        return 'https://' . $this->hostname
+                          . '/'.$this->uri
+                          . '/login?service='
+                          . urlencode($service);
+    }
+    
+    /**
+     * Returns the URL to logout of the CAS server.
+     *
+     * @param string $service Service url provided to the user.
+     * 
+     * @return string
+     */
+    function getLogoutURL($service = '')
+    {
+        if (isset($service)) {
+            $service = '?url='.urlencode($service);
+        }
+        
+        return 'https://' . $this->hostname
+                          . '/'.$this->uri
+                          . '/logout'
+                          . $service;
+    }
+    
+    /**
+     * Function to validate a ticket and service combination.
+     *
+     * @param string $ticket  Ticket given by the CAS Server
+     * @param string $service Service requesting authentication
+     * 
+     * @return false|string False on failure, user name on success.
+     */
+    function validateTicket($ticket, $service)
+    {
+        $validation_url = $this->getValidationURL($ticket, $service);
+        
+        $http_request = clone $this->getRequest();
+        
+        $defaultClass = SimpleCAS_Protocol::DEFAULT_REQUEST_CLASS;
+        if ($http_request instanceof $defaultClass) {
+            $http_request->setURL($validation_url);
+            
+            $response = $http_request->send();
+        } else {
+            $http_request->setUri($validation_url);
+            
+            $response = $http_request->request();
+        }
+        
+        
+        if ($response->getStatus() == 200
+            && substr($response->getBody(), 0, 3) == 'yes') {
+            list($message, $uid) = explode("\n", $response->getBody());
+            return $uid;
+        }
+        return false;
+    }
+    
+    /**
+     * Returns the CAS server protocol this object implements.
+     *
+     * @return string
+     */
+    function getVersion()
+    {
+        return self::VERSION;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/Protocol/Version2.php b/lib/php/SimpleCAS/Protocol/Version2.php
new file mode 100644
index 0000000..e32d665
--- /dev/null
+++ b/lib/php/SimpleCAS/Protocol/Version2.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Class representing a CAS server which supports the CAS2 protocol.
+ *
+ * PHP version 5
+ *
+ * @category  Authentication
+ * @package   SimpleCAS
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://code.google.com/p/simplecas/
+ */
+class SimpleCAS_Protocol_Version2 extends SimpleCAS_Protocol_Version1 implements SimpleCAS_SingleSignOut, SimpleCAS_ProxyGranting
+{
+    const VERSION = '2.0';
+    
+    /**
+     * Returns the URL used to validate a ticket.
+     *
+     * @param string $ticket  Ticket to validate
+     * @param string $service URL to the service requesting authentication
+     *
+     * @return string
+     */
+    function getValidationURL($ticket, $service, $pgtUrl = null)
+    {
+        return 'https://' . $this->hostname . '/'
+                          . $this->uri . '/serviceValidate?'
+                          . 'service=' . urlencode($service)
+                          . '&ticket=' . $ticket
+                          . '&pgtUrl=' . urlencode($pgtUrl);
+    }
+    
+    /**
+     * Function to validate a ticket and service combination.
+     *
+     * @param string $ticket  Ticket given by the CAS Server
+     * @param string $service Service requesting authentication
+     *
+     * @return false|string False on failure, user name on success.
+     */
+    function validateTicket($ticket, $service)
+    {
+        $validation_url = $this->getValidationURL($ticket, $service);
+        
+        $http_request = clone $this->getRequest();
+        
+        $defaultClass = SimpleCAS_Protocol::DEFAULT_REQUEST_CLASS;
+        if ($http_request instanceof $defaultClass) {
+            $http_request->setURL($validation_url);
+            
+            $response = $http_request->send();
+        } else {
+            $http_request->setUri($validation_url);
+            
+            $response = $http_request->request();
+        }
+        
+        if ($response->getStatus() == 200) {
+            $validationResponse = new SimpleCAS_Protocol_Version2_ValidationResponse($response->getBody());
+            if ($validationResponse->authenticationSuccess()) {
+                return $validationResponse->__toString();
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Validates a single sign out logout request.
+     *
+     * @param mixed $post $_POST data
+     *
+     * @return bool
+     */
+    function validateLogoutRequest($post)
+    {
+        if (false) {
+            return $ticket;
+        }
+        return false;
+    }
+    
+    function getProxyTicket()
+    {
+        throw new Exception('not implemented');
+    }
+    
+    function validateProxyTicket($ticket)
+    {
+        throw new Exception('not implemented');
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/Protocol/Version2/ValidationResponse.php b/lib/php/SimpleCAS/Protocol/Version2/ValidationResponse.php
new file mode 100644
index 0000000..225a759
--- /dev/null
+++ b/lib/php/SimpleCAS/Protocol/Version2/ValidationResponse.php
@@ -0,0 +1,62 @@
+<?php
+class SimpleCAS_Protocol_Version2_ValidationResponse
+{
+    protected $authenticationSuccess = false;
+    protected $user    = false;
+    protected $pgtiou  = false;
+    protected $proxies = array();
+
+    /**
+     * Construct a validation repsonse object from the CAS server's response.
+     * 
+     * @param string $response
+     */
+    function __construct($response)
+    {
+        $xml = new DOMDocument();
+        if ($xml->loadXML($response)) {
+            if ($success = $xml->getElementsByTagName('authenticationSuccess')) {
+                if ($success->length > 0
+                    && $uid = $success->item(0)->getElementsByTagName('user')) {
+                    // We have the user name, check for PGTIOU
+                    if ($iou = $success->item(0)->getElementsByTagName('proxyGrantingTicket')) {
+                        if ($iou->length) {
+                            $this->pgtiou = $iou->item(0)->nodeValue;
+                        }
+                    }
+                    $this->authenticationSuccess = true;
+                    $this->user = $uid->item(0)->nodeValue;
+                }
+            }
+        }
+    }
+    
+    function authenticationSuccess()
+    {
+        return $this->authenticationSuccess;
+    }
+    
+    function getPGTIOU()
+    {
+        return $this->pgtiou;
+    }
+    
+    function getUser()
+    {
+        return $this->userid;
+    }
+
+    function __toString()
+    {
+        if ($this->authenticationSuccess()) {
+            return $this->user;
+        }
+        throw new Exception('Validation was not successful');
+    }
+    
+    function logout()
+    {
+        
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/ProxyGranting.php b/lib/php/SimpleCAS/ProxyGranting.php
new file mode 100644
index 0000000..3ab250c
--- /dev/null
+++ b/lib/php/SimpleCAS/ProxyGranting.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Interface for servers that implement proxy granting tickets.
+ *
+ * PHP version 5
+ *
+ * @category  Authentication
+ * @package   SimpleCAS
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://code.google.com/p/simplecas/
+ */
+interface SimpleCAS_ProxyGranting
+{
+    
+    /**
+     * get a proxy ticket
+     *
+     * @return string
+     */
+    function getProxyTicket();
+    
+    /**
+     * try and validate a proxy ticket
+     *
+     * @param unknown_type $ticket
+     */
+    function validateProxyTicket($ticket);
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/ProxyGranting/Storage.php b/lib/php/SimpleCAS/ProxyGranting/Storage.php
new file mode 100644
index 0000000..e556041
--- /dev/null
+++ b/lib/php/SimpleCAS/ProxyGranting/Storage.php
@@ -0,0 +1,7 @@
+<?php
+interface SimpleCAS_ProxyGranting_Storage
+{
+    function saveIOU($iou);
+    function getProxyGrantingTicket($iou);
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/ProxyGranting/Storage/File.php b/lib/php/SimpleCAS/ProxyGranting/Storage/File.php
new file mode 100644
index 0000000..b345c77
--- /dev/null
+++ b/lib/php/SimpleCAS/ProxyGranting/Storage/File.php
@@ -0,0 +1,14 @@
+<?php
+class SimpleCAS_ProxyGranting_Storage_File implements SimpleCAS_ProxyGranting_Storage
+{
+    function saveIOU($iou)
+    {
+        throw new Exception('not implemented');
+    }
+    
+    function getProxyGrantingTicket($iou)
+    {
+        throw new Exception('not implemented');
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/SimpleCAS/SingleSignOut.php b/lib/php/SimpleCAS/SingleSignOut.php
new file mode 100644
index 0000000..1b0e97f
--- /dev/null
+++ b/lib/php/SimpleCAS/SingleSignOut.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Interface for servers that implement single sign out.
+ * 
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   SimpleCAS
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://code.google.com/p/simplecas/
+ */
+interface SimpleCAS_SingleSignOut
+{
+    /**
+     * Determines if the posted request is a valid single sign out request.
+     *
+     * @param mixed $post $_POST data sent to the service.
+     * 
+     * @return bool
+     */
+    function validateLogoutRequest($post);
+}
\ No newline at end of file
diff --git a/lib/php/UNL/Auth.php b/lib/php/UNL/Auth.php
new file mode 100644
index 0000000..a2a403d
--- /dev/null
+++ b/lib/php/UNL/Auth.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * This is a generic authentication framework for UNL which will return customized
+ * containers for use at UNL.
+ * 
+ * <code>
+ * <?php
+ * require_once 'UNL/Auth.php';
+ * $a = UNL_Auth::factory('CAS');
+ * if ($a->isLoggedIn()) {
+ *     echo 'Hello ' . $a->getUser();
+ * } else {
+ *     echo 'Sorry, you must log in.';
+ * }
+ * </code>
+ *
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   UNL_Auth
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/package/UNL_Auth
+ */
+class UNL_Auth
+{
+    protected static $_instance = null;
+    
+    public static function getInstance()
+    {
+        if (null === self::$_instance) {
+            self::$_instance = new self();
+        }
+
+        return self::$_instance;
+    }
+    
+    private function __construct()
+    {}
+    
+    private function __clone()
+    {}
+    
+    /**
+     * Abstract factory, used to get drivers for any of the authentication methods
+     * on campus.
+     *
+     * @param string $auth_type CAS, LDAP, LotusNotes, etc
+     * @param mixed  $options   Options for the specific container
+     * 
+     * @return mixed
+     */
+    public static function factory($auth_type, $options = null)
+    {
+        $auth_class = 'UNL_Auth_'.$auth_type;
+        $class_file = dirname(__FILE__).'/Auth/'.$auth_type.'.php';
+        return self::discoverAndReturn($auth_class, $class_file, $options);
+    }
+    
+    /**
+     * Returns an auth container for use with systems compatible with PEAR Auth
+     *
+     * @param string $auth_type CAS, LDAP, LotusNotes, etc
+     * @param mixed  $options   Options for the container
+     * 
+     * @return mixed
+     */
+    public static function PEARFactory($auth_type, $options = null, $loginFunction = null, $showLogin = true)
+    {
+        require_once 'Auth/Auth.php';
+        /// Get the class... return the pear auth container.
+        $auth_class = 'UNL_Auth_'.$auth_type.'_PEARAuth';
+        $class_file = dirname(__FILE__).'/Auth/'.$auth_type.'/PEARAuth.php';
+        $container = self::discoverAndReturn($auth_class, $class_file, $options);
+        return $container->getPEARAuth($options, $loginFunction, $showLogin);
+    }
+    
+    public static function ZendFactory($auth_type, $options = null)
+    {
+        throw new Exception('not implemented yet!');
+        /// Get the class name, return the Zend Auth extended class
+        $auth_class = 'UNL_Auth_'.$auth_type.'_ZendAuth';
+        $class_file = dirname(__FILE__).'/Auth/'.$auth_type.'/ZendAuth.php';
+        $container = self::discoverAndReturn($auth_class, $class_file, $options);
+        return $container;
+    }
+    
+    /**
+     * This is a class used to discover and return a new class based given a class
+     * name and file.
+     *
+     * @param string $class      name of the class to load UNL_Auth_CAS
+     * @param string $class_file ./Auth/CAS.php
+     * 
+     * @return object
+     */
+    protected static function discoverAndReturn($class, $class_file, $options = null)
+    {
+        if (!class_exists($class)) {
+            if (file_exists($class_file)) {
+                require_once $class_file;
+            } else {
+                throw new Exception('Cannot find authentication class that matches '.
+                                    $auth_type.' I tried '.$class_file);
+            }
+        }
+        if (method_exists($class, 'getInstance')) {
+            return call_user_func(array($class, 'getInstance'), $options);
+        } else {
+            return new $class($options);
+        }
+        
+    }
+}
+
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Auth/CAS.php b/lib/php/UNL/Auth/CAS.php
new file mode 100644
index 0000000..a73d4d1
--- /dev/null
+++ b/lib/php/UNL/Auth/CAS.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * This is a CAS central authentication.
+ *
+ * DO NOT MODIFY THIS FILE.
+ * This file remains part of the UNL Login public API and is subject to change.
+ * If you require features built into this class, please contact us by email at
+ * <accounts@answers4families.org>.
+ *
+ * based on the Answers4Families [http://www.answers4families.org/] Account Services 
+ * LDAP-CAS API.
+ *
+ * 
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   UNL_Auth
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ryan Lim <rlim@ccfl.unl.edu>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/package/UNL_Auth
+ */
+
+require_once 'CAS.php';
+
+
+/**
+ * UNL_Auth_CAS
+ *
+ * This is the CAS UserAccount class.
+ * This class takes care of user authentication using CAS and obtains the user
+ * account information via LDAP.
+ *
+ * This class does not handle changes to the user account information. All account
+ * information changes are handled by http://login.unl.edu/
+ * 
+ */
+class UNL_Auth_CAS extends UNL_Auth
+{
+    
+    /**
+     * Boolean flag to if the user is authenticated or not.
+     * 
+     * @var bool
+     */
+    protected $isAuth = false;
+
+    /**
+     * $uid is the LDAP uid value of the authenticated user.
+     * 
+     * @var string
+     */
+    protected $uid;
+    
+    /**
+     * Options for the CAS server
+     *
+     * @var array
+     */
+    protected $cas_options = array('host' => 'login.unl.edu',
+                                   'port' => 443,
+                                   'path' => 'cas');
+
+    /**
+     * The class constructor used to initialize the phpCAS class settings.
+     */
+    private function __construct(array $options = null)
+    {
+        if (session_id() != '') {
+            $start_session = false;
+        } else {
+            $start_session = true;
+        }
+        phpCAS::setDebug(false);
+        phpCAS::client(CAS_VERSION_2_0,
+            $this->cas_options['host'], $this->cas_options['port'], $this->cas_options['path'],
+            $start_session);
+        phpCAS::setNoCasServerValidation();
+        phpCAS::setCacheTimesForAuthRecheck(-1);
+
+        $this->isAuth = phpCAS::checkAuthentication();
+    }
+    
+    /**
+     * get a singleton instance of this class
+     *
+     * @return UNL_Auth_CAS
+     */
+    public static function getInstance()
+    {
+        if (null === self::$_instance) {
+            self::$_instance = new self();
+        }
+
+        return self::$_instance;
+    }
+    
+    /**
+     * Log in the user.
+     */
+    function login()
+    {
+        phpCAS::forceAuthentication();
+        $this->isAuth = true;
+        $this->uid    = phpCAS::getUser();
+    }
+
+    /**
+     * Log out the user.
+     */
+    function logout()
+    {
+        $this->isAuth = false;
+        phpCAS::forceAuthentication();
+        if (!empty($_SERVER['HTTP_REFERER'])) {
+            phpCAS::logoutWithUrl($_SERVER['HTTP_REFERER']);
+        } else {
+            phpCAS::logout();
+        }
+    }
+
+    /**
+     * Checks to see if the user is logged in.
+     * 
+     * @return bool true if logged in, false otherwise.
+     */
+    function isLoggedIn()
+    {
+        return $this->isAuth;
+    }
+
+    /**
+     * Get the LDAP-uid.
+     *
+     * @return string | bool The LDAP uid of the logged in user.
+     */
+    function getUser()
+    {
+        if ($this->isAuth) {
+            return phpCAS::getUser();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Stores the LDAP-uid internally in this instance of the class.
+     *
+     * @return string The LDAP uid of the logged in user. If the user is not logged in, return false.
+     */
+    function getUid()
+    {
+        $this->uid = $this->getUser();
+        return $this->uid;
+    }
+}
diff --git a/lib/php/UNL/Auth/CAS/PEARAuth.php b/lib/php/UNL/Auth/CAS/PEARAuth.php
new file mode 100644
index 0000000..c2f441b
--- /dev/null
+++ b/lib/php/UNL/Auth/CAS/PEARAuth.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * PEAR Auth compatible container for CAS
+ *
+ * PHP version 5
+ * 
+ * @category  Default 
+ * @package   UNL_Auth
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/package/UNL_Auth
+ */
+
+include_once 'Auth/Container.php';
+require_once 'UNL/Auth/CAS.php';
+
+class UNL_Auth_CAS_PEARAuth extends Auth_Container
+{
+    protected $cas;
+    
+    public function __construct($options)
+    {
+        $this->cas = UNL_Auth_CAS::getInstance();
+    }
+    
+    public function getPEARAuth($options = null, $loginFunction = null, $showLogin = true)
+    {
+        if (!isset($loginFunction)) {
+            $loginFunction = array('UNL_Auth_CAS_PEARAuth', 'login');
+        }
+        $auth = new Auth($this, $options, $loginFunction, $showLogin);
+        if ($this->checkAuth()) {
+            $auth->setAuth($this->getUsername());
+        }
+        $auth->setLogoutCallback(array('UNL_Auth_CAS_PEARAuth','logout'));
+        return $auth;
+    }
+    
+    public function login()
+    {
+        UNL_Auth_CAS::getInstance()->login();
+    }
+    
+    public function logout()
+    {
+        return UNL_Auth_CAS::getInstance()->logout();
+    }
+    
+    public function getAuth()
+    {
+        return UNL_Auth_CAS::getInstance()->isLoggedIn();
+    }
+    
+    public function checkAuth()
+    {
+        return UNL_Auth_CAS::getInstance()->isLoggedIn();
+    }
+    
+    public function getUsername()
+    {
+        return UNL_Auth_CAS::getInstance()->getUser();
+    }
+    
+}
diff --git a/lib/php/UNL/Auth/SimpleCAS.php b/lib/php/UNL/Auth/SimpleCAS.php
new file mode 100644
index 0000000..6f2cd0c
--- /dev/null
+++ b/lib/php/UNL/Auth/SimpleCAS.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * This is a CAS central authentication.
+ *
+ * PHP version 5
+ * 
+ * @category  Authentication 
+ * @package   UNL_Auth
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2008 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/package/UNL_Auth
+ */
+
+require_once 'SimpleCAS/Autoload.php';
+require_once 'HTTP/Request2.php';
+
+/**
+ * UNL_Auth_SimpleCAS
+ *
+ * This is the CAS UserAccount class.
+ * This class takes care of user authentication using CAS and obtains the user
+ * account information via LDAP.
+ *
+ * This class does not handle changes to the user account information. All account
+ * information changes are handled by http://login.unl.edu/
+ * 
+ */
+class UNL_Auth_SimpleCAS extends UNL_Auth
+{
+    /**
+     * Boolean flag to if the user is authenticated or not.
+     * 
+     * @var bool
+     */
+    protected $isAuth = false;
+
+    /**
+     * $uid is the LDAP uid value of the authenticated user.
+     * 
+     * @var string
+     */
+    protected $uid;
+    
+    /**
+     * Options for the CAS server
+     *
+     * @var array
+     */
+    protected $options = array('hostname' => 'login.unl.edu',
+                               'port'     => 443,
+                               'uri'      => 'cas');
+    
+    protected $client;
+    
+    /**
+     * The class constructor used to initialize the SimpleCAS class settings.
+     */
+    private function __construct(array $options = array())
+    {
+        $options = array_merge($this->options, $options);
+        $protocol = new SimpleCAS_Protocol_Version2($this->options);
+        
+        $protocol->getRequest()->setConfig('ssl_verify_peer', false);
+        
+        $this->client = SimpleCAS::client($protocol);
+        if ($this->client->isAuthenticated()) {
+            $this->isAuth = true;
+            $this->uid    = $this->client->getUsername();
+        }
+    }
+    
+    /**
+     * get a singleton instance of this class
+     *
+     * @return UNL_Auth_SimpleCAS
+     */
+    public static function getInstance()
+    {
+        if (null === self::$_instance) {
+            self::$_instance = new self();
+        }
+
+        return self::$_instance;
+    }
+    
+    function isLoggedIn()
+    {
+        return $this->isAuth;
+    }
+    
+    function getUser()
+    {
+        return $this->client->getUsername();
+    }
+    
+    function login()
+    {
+        return $this->client->forceAuthentication();
+    }
+    
+    function logout()
+    {
+        return $this->client->logout();
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Auth/SimpleCAS/ZendAuth.php b/lib/php/UNL/Auth/SimpleCAS/ZendAuth.php
new file mode 100644
index 0000000..8a759b3
--- /dev/null
+++ b/lib/php/UNL/Auth/SimpleCAS/ZendAuth.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * This is a Zend_Auth adapter library for CAS.
+ * It uses SimpleCAS.
+ *
+ * <code>
+ * public function casAction()
+ * {
+ *     $auth = Zend_Auth::getInstance();
+ *     $authAdapter = UNL_Auth::factory('SimpleCAS', Zend_Registry::get('config')->auth->cas);
+ * 
+ *     # User has not been identified, and there's a ticket in the URL
+ *     if (!$auth->hasIdentity() && isset($_GET['ticket'])) {
+ *         $authAdapter->setTicket($_GET['ticket']);
+ *         $result = $auth->authenticate($authAdapter);
+ * 
+ *         if ($result->isValid()) {
+ *             Zend_Session::regenerateId();
+ *         }
+ *     }
+ * 
+ *     # No ticket or ticket was invalid. Redirect to CAS.
+ *     if (!$auth->hasIdentity()) {
+ *         $this->_redirect($authAdapter->getLoginURL());
+ *     }
+ * }
+ * </code>
+ */
+
+
+/**
+ * @see Zend_Auth_Adapter_Interface
+ */
+require_once 'Zend/Auth/Adapter/Interface.php';
+
+require_once 'UNL/Auth/SimpleCAS.php';
+
+class UNL_Auth_SimpleCAS_ZendAuth implements Zend_Auth_Adapter_Interface
+{
+    /**
+     * CAS client
+     * 
+     * @var UNL_Auth_SimpleCAS
+     */
+    protected $_simplecas;
+
+    /**
+     * Constructor
+     *
+     * @return void
+     */ 
+    public function __construct()
+    {
+        $this->_simplecas = UNL_Auth::factory('SimpleCAS');
+    }
+
+    /**
+     * Authenticates the user
+     *
+     * @return Zend_Auth_Result
+     */ 
+    public function authenticate()
+    {
+        $this->_simplecas->login();
+        if ($this->_simplecas->isLoggedIn()) {
+            return new Zend_Auth_Result(
+                Zend_Auth_Result::SUCCESS,
+                $this->_simplecas->getUser(),
+                array("Authentication successful"));
+        } else {
+            return new Zend_Auth_Result(
+                Zend_Auth_Result::FAILURE,
+                null,
+                array("Authentication failed"));
+        }
+    }
+ 
+}
diff --git a/lib/tests/HTTP_Request2/HTTP/AllTests.php b/lib/tests/HTTP_Request2/HTTP/AllTests.php
new file mode 100644
index 0000000..bd3341f
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/AllTests.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: AllTests.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'HTTP_Request2_AllTests::main');
+}
+
+require_once dirname(__FILE__) . '/Request2Test.php';
+require_once dirname(__FILE__) . '/ObserverTest.php';
+require_once dirname(__FILE__) . '/Request2/AllTests.php';
+
+class HTTP_Request2_AllTests
+{
+    public static function main()
+    {
+        if (!function_exists('phpunit_autoload')) {
+            require_once 'PHPUnit/TextUI/TestRunner.php';
+        }
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package');
+
+        $suite->addTest(Request2_AllTests::suite());
+        $suite->addTestSuite('HTTP_Request2Test');
+        $suite->addTestSuite('HTTP_Request2_ObserverTest');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'HTTP_Request2_AllTests::main') {
+    HTTP_Request2_AllTests::main();
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/NetworkConfig.php.dist b/lib/tests/HTTP_Request2/HTTP/NetworkConfig.php.dist
new file mode 100644
index 0000000..0412ca4
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/NetworkConfig.php.dist
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: NetworkConfig.php.dist 308299 2011-02-12 23:20:23Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * This file contains configuration needed for running HTTP_Request2 tests
+ * that interact with the network. Do not edit this file, copy it to
+ * NetworkConfig.php and edit the copy instead.
+ */
+
+/**
+ * Base URL for HTTP_Request2 Adapters tests
+ *
+ * To enable the tests that actually perform network interaction, you should
+ * copy the contents of _network directory to a directory under your web
+ * server's document root or create a symbolic link to _network directory
+ * there. Set this constant to point to the URL of that directory.
+ */
+define('HTTP_REQUEST2_TESTS_BASE_URL',          null);
+
+/**#@+
+ * Proxy setup for Socket Adapter tests
+ *
+ * Set these constants to run additional tests for Socket Adapter using a HTTP
+ * proxy. If proxy host is not set then the tests will not be run.
+ */
+define('HTTP_REQUEST2_TESTS_PROXY_HOST',        null);
+define('HTTP_REQUEST2_TESTS_PROXY_PORT',        8080);
+define('HTTP_REQUEST2_TESTS_PROXY_USER',        '');
+define('HTTP_REQUEST2_TESTS_PROXY_PASSWORD',    '');
+define('HTTP_REQUEST2_TESTS_PROXY_AUTH_SCHEME', 'basic');
+/**#@-*/
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/ObserverTest.php b/lib/tests/HTTP_Request2/HTTP/ObserverTest.php
new file mode 100644
index 0000000..50b22ff
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/ObserverTest.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: ObserverTest.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/** Helper for PHPUnit includes */
+require_once dirname(__FILE__) . '/TestHelper.php';
+
+/**
+ * Mock observer
+ */
+class HTTP_Request2_MockObserver implements SplObserver
+{
+    public $calls = 0;
+
+    public $event;
+
+    public function update (SplSubject $subject)
+    {
+        $this->calls++;
+        $this->event = $subject->getLastEvent();
+    }
+}
+
+/**
+ * Unit test for subject-observer pattern implementation in HTTP_Request2
+ */
+class HTTP_Request2_ObserverTest extends PHPUnit_Framework_TestCase
+{
+    public function testSetLastEvent()
+    {
+        $request  = new HTTP_Request2();
+        $observer = new HTTP_Request2_MockObserver();
+        $request->attach($observer);
+
+        $request->setLastEvent('foo', 'bar');
+        $this->assertEquals(1, $observer->calls);
+        $this->assertEquals(array('name' => 'foo', 'data' => 'bar'), $observer->event);
+
+        $request->setLastEvent('baz');
+        $this->assertEquals(2, $observer->calls);
+        $this->assertEquals(array('name' => 'baz', 'data' => null), $observer->event);
+    }
+
+    public function testAttachOnlyOnce()
+    {
+        $request   = new HTTP_Request2();
+        $observer  = new HTTP_Request2_MockObserver();
+        $observer2 = new HTTP_Request2_MockObserver();
+        $request->attach($observer);
+        $request->attach($observer2);
+        $request->attach($observer);
+
+        $request->setLastEvent('event', 'data');
+        $this->assertEquals(1, $observer->calls);
+        $this->assertEquals(1, $observer2->calls);
+    }
+
+    public function testDetach()
+    {
+        $request   = new HTTP_Request2();
+        $observer  = new HTTP_Request2_MockObserver();
+        $observer2 = new HTTP_Request2_MockObserver();
+
+        $request->attach($observer);
+        $request->detach($observer2); // should not be a error
+        $request->setLastEvent('first');
+
+        $request->detach($observer);
+        $request->setLastEvent('second');
+        $this->assertEquals(1, $observer->calls);
+        $this->assertEquals(array('name' => 'first', 'data' => null), $observer->event);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/AllTests.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/AllTests.php
new file mode 100644
index 0000000..ae6aa96
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/AllTests.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: AllTests.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Request2_Adapter_AllTests::main');
+}
+
+require_once dirname(__FILE__) . '/MockTest.php';
+require_once dirname(__FILE__) . '/SkippedTests.php';
+require_once dirname(__FILE__) . '/SocketTest.php';
+require_once dirname(__FILE__) . '/SocketProxyTest.php';
+require_once dirname(__FILE__) . '/CurlTest.php';
+
+class Request2_Adapter_AllTests
+{
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package - Request2 - Adapter');
+
+        $suite->addTestSuite('HTTP_Request2_Adapter_MockTest');
+        if (defined('HTTP_REQUEST2_TESTS_BASE_URL') && HTTP_REQUEST2_TESTS_BASE_URL) {
+            $suite->addTestSuite('HTTP_Request2_Adapter_SocketTest');
+        } else {
+            $suite->addTestSuite('HTTP_Request2_Adapter_Skip_SocketTest');
+        }
+        if (defined('HTTP_REQUEST2_TESTS_PROXY_HOST') && HTTP_REQUEST2_TESTS_PROXY_HOST
+            && defined('HTTP_REQUEST2_TESTS_BASE_URL') && HTTP_REQUEST2_TESTS_BASE_URL
+        ) {
+            $suite->addTestSuite('HTTP_Request2_Adapter_SocketProxyTest');
+        } else {
+            $suite->addTestSuite('HTTP_Request2_Adapter_Skip_SocketProxyTest');
+        }
+        if (defined('HTTP_REQUEST2_TESTS_BASE_URL') && HTTP_REQUEST2_TESTS_BASE_URL
+            && extension_loaded('curl')
+        ) {
+            $suite->addTestSuite('HTTP_Request2_Adapter_CurlTest');
+        } else {
+            $suite->addTestSuite('HTTP_Request2_Adapter_Skip_CurlTest');
+        }
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Request2_Adapter_AllTests::main') {
+    Request2_Adapter_AllTests::main();
+}
+?>
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CommonNetworkTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CommonNetworkTest.php
new file mode 100644
index 0000000..976aae3
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CommonNetworkTest.php
@@ -0,0 +1,309 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: CommonNetworkTest.php 309921 2011-04-03 16:43:02Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Class representing a HTTP request */
+require_once 'HTTP/Request2.php';
+
+/** Helper for PHPUnit includes */
+require_once dirname(dirname(dirname(__FILE__))) . '/TestHelper.php';
+
+/**
+ * Tests for HTTP_Request2 package that require a working webserver
+ *
+ * The class contains some common tests that should be run for all Adapters,
+ * it is extended by their unit tests.
+ *
+ * You need to properly set up this test suite, refer to NetworkConfig.php.dist
+ */
+abstract class HTTP_Request2_Adapter_CommonNetworkTest extends PHPUnit_Framework_TestCase
+{
+   /**
+    * HTTP Request object
+    * @var HTTP_Request2
+    */
+    protected $request;
+
+   /**
+    * Base URL for remote test files
+    * @var string
+    */
+    protected $baseUrl;
+
+   /**
+    * Configuration for HTTP Request object
+    * @var array
+    */
+    protected $config = array();
+
+    protected function setUp()
+    {
+        if (!defined('HTTP_REQUEST2_TESTS_BASE_URL') || !HTTP_REQUEST2_TESTS_BASE_URL) {
+            $this->markTestSkipped('Base URL is not configured');
+
+        } else {
+            $this->baseUrl = rtrim(HTTP_REQUEST2_TESTS_BASE_URL, '/') . '/';
+            $name = strtolower(preg_replace('/^test/i', '', $this->getName())) . '.php';
+
+            $this->request = new HTTP_Request2(
+                $this->baseUrl . $name, HTTP_Request2::METHOD_GET, $this->config
+            );
+        }
+    }
+
+   /**
+    * Tests possibility to send GET parameters
+    *
+    * NB: Currently there are problems with Net_URL2::setQueryVariables(), thus
+    * array structure is simple: http://pear.php.net/bugs/bug.php?id=18267
+    */
+    public function testGetParameters()
+    {
+        $data = array(
+            'bar' => array(
+                'key' => 'value'
+            ),
+            'foo' => 'some value',
+            'numbered' => array('first', 'second')
+        );
+
+        $this->request->getUrl()->setQueryVariables($data);
+        $response = $this->request->send();
+        $this->assertEquals($response->getBody(), serialize($data));
+    }
+
+    public function testPostParameters()
+    {
+        $data = array(
+            'bar' => array(
+                'key' => 'some other value'
+            ),
+            'baz' => array(
+                'key1' => array(
+                    'key2' => 'yet another value'
+                )
+            ),
+            'foo' => 'some value',
+            'indexed' => array('first', 'second')
+        );
+
+        $this->request->setMethod(HTTP_Request2::METHOD_POST)
+                      ->addPostParameter($data);
+
+        $response = $this->request->send();
+        $this->assertEquals($response->getBody(), serialize($data));
+    }
+
+    public function testUploads()
+    {
+        $this->request->setMethod(HTTP_Request2::METHOD_POST)
+                      ->addUpload('foo', dirname(dirname(dirname(__FILE__))) . '/_files/empty.gif', 'picture.gif', 'image/gif')
+                      ->addUpload('bar', array(
+                                    array(dirname(dirname(dirname(__FILE__))) . '/_files/empty.gif', null, 'image/gif'),
+                                    array(dirname(dirname(dirname(__FILE__))) . '/_files/plaintext.txt', 'secret.txt', 'text/x-whatever')
+                                  ));
+
+        $response = $this->request->send();
+        $this->assertContains("foo picture.gif image/gif 43", $response->getBody());
+        $this->assertContains("bar[0] empty.gif image/gif 43", $response->getBody());
+        $this->assertContains("bar[1] secret.txt text/x-whatever 15", $response->getBody());
+    }
+
+    public function testRawPostData()
+    {
+        $data = 'Nothing to see here, move along';
+
+        $this->request->setMethod(HTTP_Request2::METHOD_POST)
+                      ->setBody($data);
+        $response = $this->request->send();
+        $this->assertEquals($response->getBody(), $data);
+    }
+
+    public function testCookies()
+    {
+        $cookies = array(
+            'CUSTOMER'    => 'WILE_E_COYOTE',
+            'PART_NUMBER' => 'ROCKET_LAUNCHER_0001'
+        );
+
+        foreach ($cookies as $k => $v) {
+            $this->request->addCookie($k, $v);
+        }
+        $response = $this->request->send();
+        $this->assertEquals($response->getBody(), serialize($cookies));
+    }
+
+    public function testTimeout()
+    {
+        $this->request->setConfig('timeout', 2);
+        try {
+            $this->request->send();
+            $this->fail('Expected HTTP_Request2_Exception was not thrown');
+        } catch (HTTP_Request2_MessageException $e) {
+            $this->assertEquals(HTTP_Request2_Exception::TIMEOUT, $e->getCode());
+        }
+    }
+
+    public function testBasicAuth()
+    {
+        $this->request->getUrl()->setQueryVariables(array(
+            'user' => 'luser',
+            'pass' => 'qwerty'
+        ));
+        $wrong = clone $this->request;
+
+        $this->request->setAuth('luser', 'qwerty');
+        $response = $this->request->send();
+        $this->assertEquals(200, $response->getStatus());
+
+        $wrong->setAuth('luser', 'password');
+        $response = $wrong->send();
+        $this->assertEquals(401, $response->getStatus());
+    }
+
+    public function testDigestAuth()
+    {
+        $this->request->getUrl()->setQueryVariables(array(
+            'user' => 'luser',
+            'pass' => 'qwerty'
+        ));
+        $wrong = clone $this->request;
+
+        $this->request->setAuth('luser', 'qwerty', HTTP_Request2::AUTH_DIGEST);
+        $response = $this->request->send();
+        $this->assertEquals(200, $response->getStatus());
+
+        $wrong->setAuth('luser', 'password', HTTP_Request2::AUTH_DIGEST);
+        $response = $wrong->send();
+        $this->assertEquals(401, $response->getStatus());
+    }
+
+    public function testRedirectsDefault()
+    {
+        $this->request->setUrl($this->baseUrl . 'redirects.php')
+                      ->setConfig(array('follow_redirects' => true, 'strict_redirects' => false))
+                      ->setMethod(HTTP_Request2::METHOD_POST)
+                      ->addPostParameter('foo', 'foo value');
+
+        $response = $this->request->send();
+        $this->assertContains('Method=GET', $response->getBody());
+        $this->assertNotContains('foo', $response->getBody());
+        $this->assertEquals($this->baseUrl . 'redirects.php?redirects=0', $response->getEffectiveUrl());
+    }
+
+    public function testRedirectsStrict()
+    {
+        $this->request->setUrl($this->baseUrl . 'redirects.php')
+                      ->setConfig(array('follow_redirects' => true, 'strict_redirects' => true))
+                      ->setMethod(HTTP_Request2::METHOD_POST)
+                      ->addPostParameter('foo', 'foo value');
+
+        $response = $this->request->send();
+        $this->assertContains('Method=POST', $response->getBody());
+        $this->assertContains('foo', $response->getBody());
+    }
+
+    public function testRedirectsLimit()
+    {
+        $this->request->setUrl($this->baseUrl . 'redirects.php?redirects=4')
+                      ->setConfig(array('follow_redirects' => true, 'max_redirects' => 2));
+
+        try {
+            $this->request->send();
+            $this->fail('Expected HTTP_Request2_Exception was not thrown');
+        } catch (HTTP_Request2_MessageException $e) {
+            $this->assertEquals(HTTP_Request2_Exception::TOO_MANY_REDIRECTS, $e->getCode());
+        }
+    }
+
+    public function testRedirectsRelative()
+    {
+        $this->request->setUrl($this->baseUrl . 'redirects.php?special=relative')
+                      ->setConfig(array('follow_redirects' => true));
+
+        $response = $this->request->send();
+        $this->assertContains('did relative', $response->getBody());
+    }
+
+    public function testRedirectsNonHTTP()
+    {
+        $this->request->setUrl($this->baseUrl . 'redirects.php?special=ftp')
+                      ->setConfig(array('follow_redirects' => true));
+
+        try {
+            $this->request->send();
+            $this->fail('Expected HTTP_Request2_Exception was not thrown');
+        } catch (HTTP_Request2_MessageException $e) {
+            $this->assertEquals(HTTP_Request2_Exception::NON_HTTP_REDIRECT, $e->getCode());
+        }
+    }
+
+    public function testCookieJar()
+    {
+        $this->request->setUrl($this->baseUrl . 'setcookie.php?name=cookie_name&value=cookie_value');
+        $req2 = clone $this->request;
+
+        $this->request->setCookieJar()->send();
+        $jar = $this->request->getCookieJar();
+        $jar->store(
+            array('name' => 'foo', 'value' => 'bar'),
+            $this->request->getUrl()
+        );
+
+        $response = $req2->setUrl($this->baseUrl . 'cookies.php')->setCookieJar($jar)->send();
+        $this->assertEquals(
+            serialize(array('cookie_name' => 'cookie_value', 'foo' => 'bar')),
+            $response->getBody()
+        );
+    }
+
+    public function testCookieJarAndRedirect()
+    {
+        $this->request->setUrl($this->baseUrl . 'redirects.php?special=cookie')
+                      ->setConfig('follow_redirects', true)
+                      ->setCookieJar();
+
+        $response = $this->request->send();
+        $this->assertEquals(serialize(array('cookie_on_redirect' => 'success')), $response->getBody());
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CurlTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CurlTest.php
new file mode 100644
index 0000000..05fc508
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/CurlTest.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: CurlTest.php 308629 2011-02-24 17:34:24Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Tests for HTTP_Request2 package that require a working webserver */
+require_once dirname(__FILE__) . '/CommonNetworkTest.php';
+
+/** Adapter for HTTP_Request2 wrapping around cURL extension */
+
+/**
+ * Unit test for Curl Adapter of HTTP_Request2
+ */
+class HTTP_Request2_Adapter_CurlTest extends HTTP_Request2_Adapter_CommonNetworkTest
+{
+   /**
+    * Configuration for HTTP Request object
+    * @var array
+    */
+    protected $config = array(
+        'adapter' => 'HTTP_Request2_Adapter_Curl'
+    );
+
+   /**
+    * Checks whether redirect support in cURL is disabled by safe_mode or open_basedir
+    * @return bool
+    */
+    protected function isRedirectSupportDisabled()
+    {
+        return ini_get('safe_mode') || ini_get('open_basedir');
+    }
+
+    public function testRedirectsDefault()
+    {
+        if ($this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
+        } else {
+            parent::testRedirectsDefault();
+        }
+    }
+
+    public function testRedirectsStrict()
+    {
+        if ($this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
+        } else {
+            parent::testRedirectsStrict();
+        }
+    }
+
+    public function testRedirectsLimit()
+    {
+        if ($this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
+        } else {
+            parent::testRedirectsLimit();
+        }
+    }
+
+    public function testRedirectsRelative()
+    {
+        if ($this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
+        } else {
+            parent::testRedirectsRelative();
+        }
+    }
+
+    public function testRedirectsNonHTTP()
+    {
+        if ($this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
+        } else {
+            parent::testRedirectsNonHTTP();
+        }
+    }
+
+    public function testCookieJarAndRedirect()
+    {
+        if ($this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Redirect support in cURL is disabled by safe_mode or open_basedir setting');
+        } else {
+            parent::testCookieJarAndRedirect();
+        }
+    }
+
+    public function testBug17450()
+    {
+        if (!$this->isRedirectSupportDisabled()) {
+            $this->markTestSkipped('Neither safe_mode nor open_basedir is enabled');
+        }
+
+        $this->request->setUrl($this->baseUrl . 'redirects.php')
+                      ->setConfig(array('follow_redirects' => true));
+
+        try {
+            $this->request->send();
+            $this->fail('Expected HTTP_Request2_Exception was not thrown');
+
+        } catch (HTTP_Request2_LogicException $e) {
+            $this->assertEquals(HTTP_Request2_Exception::MISCONFIGURATION, $e->getCode());
+        }
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/MockTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/MockTest.php
new file mode 100644
index 0000000..06b7a24
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/MockTest.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: MockTest.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/**
+ * Mock adapter intended for testing
+ */
+require_once 'HTTP/Request2/Adapter/Mock.php';
+
+/** Helper for PHPUnit includes */
+require_once dirname(dirname(dirname(__FILE__))) . '/TestHelper.php';
+
+/**
+ * Unit test for HTTP_Request2_Response class
+ */
+class HTTP_Request2_Adapter_MockTest extends PHPUnit_Framework_TestCase
+{
+    public function testDefaultResponse()
+    {
+        $req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_GET,
+                                 array('adapter' => 'mock'));
+        $response = $req->send();
+        $this->assertEquals(400, $response->getStatus());
+        $this->assertEquals(0, count($response->getHeader()));
+        $this->assertEquals('', $response->getBody());
+    }
+
+    public function testResponseFromString()
+    {
+        $mock = new HTTP_Request2_Adapter_Mock();
+        $mock->addResponse(
+            "HTTP/1.1 200 OK\r\n" .
+            "Content-Type: text/plain; charset=iso-8859-1\r\n" .
+            "\r\n" .
+            "This is a string"
+        );
+        $req = new HTTP_Request2('http://www.example.com/');
+        $req->setAdapter($mock);
+
+        $response = $req->send();
+        $this->assertEquals(200, $response->getStatus());
+        $this->assertEquals(1, count($response->getHeader()));
+        $this->assertEquals('This is a string', $response->getBody());
+    }
+
+    public function testResponseFromFile()
+    {
+        $mock = new HTTP_Request2_Adapter_Mock();
+        $mock->addResponse(fopen(dirname(dirname(dirname(__FILE__))) .
+                           '/_files/response_headers', 'rb'));
+
+        $req = new HTTP_Request2('http://www.example.com/');
+        $req->setAdapter($mock);
+
+        $response = $req->send();
+        $this->assertEquals(200, $response->getStatus());
+        $this->assertEquals(7, count($response->getHeader()));
+        $this->assertEquals('Nothing to see here, move along.', $response->getBody());
+    }
+
+    public function testResponsesQueue()
+    {
+        $mock = new HTTP_Request2_Adapter_Mock();
+        $mock->addResponse(
+            "HTTP/1.1 301 Over there\r\n" .
+            "Location: http://www.example.com/newpage.html\r\n" .
+            "\r\n" .
+            "The document is over there"
+        );
+        $mock->addResponse(
+            "HTTP/1.1 200 OK\r\n" .
+            "Content-Type: text/plain; charset=iso-8859-1\r\n" .
+            "\r\n" .
+            "This is a string"
+        );
+
+        $req = new HTTP_Request2('http://www.example.com/');
+        $req->setAdapter($mock);
+        $this->assertEquals(301, $req->send()->getStatus());
+        $this->assertEquals(200, $req->send()->getStatus());
+        $this->assertEquals(400, $req->send()->getStatus());
+    }
+
+    public function testResponseException()
+    {
+        $mock = new HTTP_Request2_Adapter_Mock();
+        $mock->addResponse(
+            new HTTP_Request2_Exception('Shit happens')
+        );
+        $req = new HTTP_Request2('http://www.example.com/');
+        $req->setAdapter($mock);
+        try {
+            $req->send();
+        } catch (Exception $e) {
+            $this->assertEquals('Shit happens', $e->getMessage());
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+}
+?>
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SkippedTests.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SkippedTests.php
new file mode 100644
index 0000000..3b2c494
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SkippedTests.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: SkippedTests.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Helper for PHPUnit includes */
+require_once dirname(dirname(dirname(__FILE__))) . '/TestHelper.php';
+
+/**
+ * Shows a skipped test if networked tests are not configured
+ */
+class HTTP_Request2_Adapter_Skip_SocketTest extends PHPUnit_Framework_TestCase
+{
+    public function testSocketAdapter()
+    {
+        $this->markTestSkipped('Socket Adapter tests need base URL configured.');
+    }
+}
+
+/**
+ * Shows a skipped test if proxy is not configured
+ */
+class HTTP_Request2_Adapter_Skip_SocketProxyTest extends PHPUnit_Framework_TestCase
+{
+    public function testSocketAdapterWithProxy()
+    {
+        $this->markTestSkipped('Socket Adapter proxy tests need base URL and proxy configured');
+    }
+}
+
+/**
+ * Shows a skipped test if networked tests are not configured or cURL extension is unavailable
+ */
+class HTTP_Request2_Adapter_Skip_CurlTest extends PHPUnit_Framework_TestCase
+{
+    public function testCurlAdapter()
+    {
+        $this->markTestSkipped('Curl Adapter tests need base URL configured and curl extension available');
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketProxyTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketProxyTest.php
new file mode 100644
index 0000000..14db863
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketProxyTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: SocketProxyTest.php 308299 2011-02-12 23:20:23Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Tests for HTTP_Request2 package that require a working webserver */
+require_once dirname(__FILE__) . '/CommonNetworkTest.php';
+
+/**
+ * Unit test for Socket Adapter of HTTP_Request2 working through proxy
+ */
+class HTTP_Request2_Adapter_SocketProxyTest extends HTTP_Request2_Adapter_CommonNetworkTest
+{
+   /**
+    * Configuration for HTTP Request object
+    * @var array
+    */
+    protected $config = array(
+        'adapter' => 'HTTP_Request2_Adapter_Socket'
+    );
+
+    protected function setUp()
+    {
+        if (!defined('HTTP_REQUEST2_TESTS_PROXY_HOST') || !HTTP_REQUEST2_TESTS_PROXY_HOST) {
+            $this->markTestSkipped('Proxy is not configured');
+
+        } else {
+            $this->config += array(
+                'proxy_host'        => HTTP_REQUEST2_TESTS_PROXY_HOST,
+                'proxy_port'        => HTTP_REQUEST2_TESTS_PROXY_PORT,
+                'proxy_user'        => HTTP_REQUEST2_TESTS_PROXY_USER,
+                'proxy_password'    => HTTP_REQUEST2_TESTS_PROXY_PASSWORD,
+                'proxy_auth_scheme' => HTTP_REQUEST2_TESTS_PROXY_AUTH_SCHEME,
+            );
+            parent::setUp();
+        }
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketTest.php
new file mode 100644
index 0000000..71ca6e6
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/Adapter/SocketTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: SocketTest.php 308301 2011-02-13 13:02:20Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Tests for HTTP_Request2 package that require a working webserver */
+require_once dirname(__FILE__) . '/CommonNetworkTest.php';
+
+/** Socket-based adapter for HTTP_Request2 */
+require_once 'HTTP/Request2/Adapter/Socket.php';
+
+/**
+ * Unit test for Socket Adapter of HTTP_Request2
+ */
+class HTTP_Request2_Adapter_SocketTest extends HTTP_Request2_Adapter_CommonNetworkTest
+{
+   /**
+    * Configuration for HTTP Request object
+    * @var array
+    */
+    protected $config = array(
+        'adapter' => 'HTTP_Request2_Adapter_Socket'
+    );
+
+    public function testBug17826()
+    {
+        $adapter = new HTTP_Request2_Adapter_Socket();
+
+        $request1 = new HTTP_Request2($this->baseUrl . 'redirects.php?redirects=2');
+        $request1->setConfig(array('follow_redirects' => true, 'max_redirects' => 3))
+                 ->setAdapter($adapter)
+                 ->send();
+
+        $request2 = new HTTP_Request2($this->baseUrl . 'redirects.php?redirects=2');
+        $request2->setConfig(array('follow_redirects' => true, 'max_redirects' => 3))
+                 ->setAdapter($adapter)
+                 ->send();
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/AllTests.php b/lib/tests/HTTP_Request2/HTTP/Request2/AllTests.php
new file mode 100644
index 0000000..0d70907
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/AllTests.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: AllTests.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Request2_AllTests::main');
+}
+
+require_once dirname(__FILE__) . '/CookieJarTest.php';
+require_once dirname(__FILE__) . '/MultipartBodyTest.php';
+require_once dirname(__FILE__) . '/ResponseTest.php';
+require_once dirname(__FILE__) . '/Adapter/AllTests.php';
+
+class Request2_AllTests
+{
+    public static function main()
+    {
+        if (!function_exists('phpunit_autoload')) {
+            require_once 'PHPUnit/TextUI/TestRunner.php';
+        }
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package - Request2');
+
+        $suite->addTestSuite('HTTP_Request2_CookieJarTest');
+        $suite->addTestSuite('HTTP_Request2_MultipartBodyTest');
+        $suite->addTestSuite('HTTP_Request2_ResponseTest');
+        $suite->addTest(Request2_Adapter_AllTests::suite());
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Request2_AllTests::main') {
+    Request2_AllTests::main();
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/CookieJarTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/CookieJarTest.php
new file mode 100644
index 0000000..4529c07
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/CookieJarTest.php
@@ -0,0 +1,393 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: CookieJarTest.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Stores cookies and passes them between HTTP requests */
+require_once 'HTTP/Request2/CookieJar.php';
+/** Helper for PHPUnit includes */
+require_once dirname(dirname(__FILE__)) . '/TestHelper.php';
+
+/**
+ * Unit test for HTTP_Request2_CookieJar class
+ */
+class HTTP_Request2_CookieJarTest extends PHPUnit_Framework_TestCase
+{
+   /**
+    * Cookie jar instance being tested
+    * @var HTTP_Request2_CookieJar
+    */
+    protected $jar;
+
+    protected function setUp()
+    {
+        $this->jar = new HTTP_Request2_CookieJar();
+    }
+
+   /**
+    * Test that we can't store junk "cookies" in jar
+    *
+    * @dataProvider invalidCookieProvider
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testStoreInvalid($cookie)
+    {
+        $this->jar->store($cookie);
+    }
+
+   /**
+    *
+    * @dataProvider noPSLDomainsProvider
+    */
+    public function testDomainMatchNoPSL($requestHost, $cookieDomain, $expected)
+    {
+        $this->jar->usePublicSuffixList(false);
+        $this->assertEquals($expected, $this->jar->domainMatch($requestHost, $cookieDomain));
+    }
+
+   /**
+    *
+    * @dataProvider PSLDomainsProvider
+    */
+    public function testDomainMatchPSL($requestHost, $cookieDomain, $expected)
+    {
+        $this->jar->usePublicSuffixList(true);
+        $this->assertEquals($expected, $this->jar->domainMatch($requestHost, $cookieDomain));
+    }
+
+    public function testConvertExpiresToISO8601()
+    {
+        $dt = new DateTime();
+        $dt->setTimezone(new DateTimeZone('UTC'));
+        $dt->modify('+1 day');
+
+        $this->jar->store(array(
+            'name'    => 'foo',
+            'value'   => 'bar',
+            'domain'  => '.example.com',
+            'path'    => '/',
+            'expires' => $dt->format(DateTime::COOKIE),
+            'secure'  => false
+        ));
+        $cookies = $this->jar->getAll();
+        $this->assertEquals($cookies[0]['expires'], $dt->format(DateTime::ISO8601));
+    }
+
+    public function testProblem2038()
+    {
+        $this->jar->store(array(
+            'name'    => 'foo',
+            'value'   => 'bar',
+            'domain'  => '.example.com',
+            'path'    => '/',
+            'expires' => 'Sun, 01 Jan 2040 03:04:05 GMT',
+            'secure'  => false
+        ));
+        $cookies = $this->jar->getAll();
+        $this->assertEquals(array(array(
+            'name'    => 'foo',
+            'value'   => 'bar',
+            'domain'  => '.example.com',
+            'path'    => '/',
+            'expires' => '2040-01-01T03:04:05+0000',
+            'secure'  => false
+        )), $cookies);
+    }
+
+    public function testStoreExpired()
+    {
+        $base = array(
+            'name'    => 'foo',
+            'value'   => 'bar',
+            'domain'  => '.example.com',
+            'path'    => '/',
+            'secure'  => false
+        );
+
+        $dt = new DateTime();
+        $dt->setTimezone(new DateTimeZone('UTC'));
+        $dt->modify('-1 day');
+        $yesterday = $dt->format(DateTime::COOKIE);
+
+        $dt->modify('+2 days');
+        $tomorrow = $dt->format(DateTime::COOKIE);
+
+        $this->jar->store($base + array('expires' => $yesterday));
+        $this->assertEquals(0, count($this->jar->getAll()));
+
+        $this->jar->store($base + array('expires' => $tomorrow));
+        $this->assertEquals(1, count($this->jar->getAll()));
+        $this->jar->store($base + array('expires' => $yesterday));
+        $this->assertEquals(0, count($this->jar->getAll()));
+    }
+
+   /**
+    *
+    * @dataProvider cookieAndSetterProvider
+    */
+    public function testGetDomainAndPathFromSetter($cookie, $setter, $expected)
+    {
+        $this->jar->store($cookie, $setter);
+        $expected = array_merge($cookie, $expected);
+        $cookies  = $this->jar->getAll();
+        $this->assertEquals($expected, $cookies[0]);
+    }
+
+   /**
+    *
+    * @dataProvider cookieMatchProvider
+    */
+    public function testGetMatchingCookies($url, $expectedCount)
+    {
+        $cookies = array(
+            array('domain' => '.example.com', 'path' => '/', 'secure' => false),
+            array('domain' => '.example.com', 'path' => '/', 'secure' => true),
+            array('domain' => '.example.com', 'path' => '/path', 'secure' => false),
+            array('domain' => '.example.com', 'path' => '/other', 'secure' => false),
+            array('domain' => 'example.com', 'path' => '/', 'secure' => false),
+            array('domain' => 'www.example.com', 'path' => '/', 'secure' => false),
+            array('domain' => 'specific.example.com', 'path' => '/path', 'secure' => false),
+            array('domain' => 'nowww.example.com', 'path' => '/', 'secure' => false),
+        );
+
+        for ($i = 0; $i < count($cookies); $i++) {
+            $this->jar->store($cookies[$i] + array('expires' => null, 'name' => "cookie{$i}", 'value' => "cookie_{$i}_value"));
+        }
+
+        $this->assertEquals($expectedCount, count($this->jar->getMatching(new Net_URL2($url))));
+    }
+
+    public function testLongestPathFirst()
+    {
+        $cookie = array(
+            'name'    => 'foo',
+            'domain'  => '.example.com',
+        );
+        foreach (array('/', '/specific/path/', '/specific/') as $path) {
+            $this->jar->store($cookie + array('path' => $path, 'value' => str_replace('/', '_', $path)));
+        }
+        $this->assertEquals(
+            'foo=_specific_path_; foo=_specific_; foo=_',
+            $this->jar->getMatching(new Net_URL2('http://example.com/specific/path/file.php'), true)
+        );
+    }
+
+    public function testSerializable()
+    {
+        $dt = new DateTime();
+        $dt->setTimezone(new DateTimeZone('UTC'));
+        $dt->modify('+1 day');
+        $cookie = array('domain' => '.example.com', 'path' => '/', 'secure' => false, 'value' => 'foo');
+
+        $this->jar->store($cookie + array('name' => 'session', 'expires' => null));
+        $this->jar->store($cookie + array('name' => 'long', 'expires' => $dt->format(DateTime::COOKIE)));
+
+        $newJar  = unserialize(serialize($this->jar));
+        $cookies = $newJar->getAll();
+        $this->assertEquals(1, count($cookies));
+        $this->assertEquals('long', $cookies[0]['name']);
+
+        $this->jar->serializeSessionCookies(true);
+        $newJar = unserialize(serialize($this->jar));
+        $this->assertEquals($this->jar->getAll(), $newJar->getAll());
+    }
+
+    public function testRemoveExpiredOnUnserialize()
+    {
+        $dt = new DateTime();
+        $dt->setTimezone(new DateTimeZone('UTC'));
+        $dt->modify('+2 seconds');
+
+        $this->jar->store(array(
+            'name'    => 'foo',
+            'value'   => 'bar',
+            'domain'  => '.example.com',
+            'path'    => '/',
+            'expires' => $dt->format(DateTime::COOKIE),
+        ));
+
+        $serialized = serialize($this->jar);
+        sleep(2);
+        $newJar = unserialize($serialized);
+        $this->assertEquals(array(), $newJar->getAll());
+    }
+
+    public static function invalidCookieProvider()
+    {
+        return array(
+            array(array()),
+            array(array('name' => 'foo')),
+            array(array(
+                'name'    => 'a name',
+                'value'   => 'bar',
+                'domain'  => '.example.com',
+                'path'    => '/',
+            )),
+            array(array(
+                'name'    => 'foo',
+                'value'   => 'a value',
+                'domain'  => '.example.com',
+                'path'    => '/',
+            )),
+            array(array(
+                'name'    => 'foo',
+                'value'   => 'bar',
+                'domain'  => '.example.com',
+                'path'    => null,
+            )),
+            array(array(
+                'name'    => 'foo',
+                'value'   => 'bar',
+                'domain'  => null,
+                'path'    => '/',
+            )),
+            array(array(
+                'name'    => 'foo',
+                'value'   => 'bar',
+                'domain'  => '.example.com',
+                'path'    => '/',
+                'expires' => 'invalid date',
+            )),
+        );
+    }
+
+    public static function noPSLdomainsProvider()
+    {
+        return array(
+            array('localhost', 'localhost', true),
+            array('www.example.com', 'www.example.com', true),
+            array('127.0.0.1', '127.0.0.1', true),
+            array('127.0.0.1', '.0.0.1', false),
+            array('www.example.com', '.example.com', true),
+            array('deep.within.example.com', '.example.com', true),
+            array('example.com', '.com', false),
+            array('anotherexample.com', 'example.com', false),
+            array('whatever.msk.ru', '.msk.ru', true),
+            array('whatever.co.uk', '.co.uk', true),
+            array('whatever.uk', '.whatever.uk', true),
+            array('whatever.tokyo.jp', '.whatever.tokyo.jp', true),
+            array('metro.tokyo.jp', '.metro.tokyo.jp', true),
+            array('foo.bar', '.foo.bar', true)
+        );
+    }
+
+    public static function PSLdomainsProvider()
+    {
+        return array(
+            array('localhost', 'localhost', true),
+            array('www.example.com', 'www.example.com', true),
+            array('127.0.0.1', '127.0.0.1', true),
+            array('127.0.0.1', '.0.0.1', false),
+            array('www.example.com', '.example.com', true),
+            array('deep.within.example.com', '.example.com', true),
+            array('example.com', '.com', false),
+            array('anotherexample.com', 'example.com', false),
+            array('whatever.msk.ru', '.msk.ru', false),
+            array('whatever.co.uk', '.co.uk', false),
+            array('whatever.uk', '.whatever.uk', false),
+            array('whatever.tokyo.jp', '.whatever.tokyo.jp', false),
+            array('metro.tokyo.jp', '.metro.tokyo.jp', true),
+            array('foo.bar', '.foo.bar', true)
+        );
+    }
+
+    public static function cookieAndSetterProvider()
+    {
+        return array(
+            array(
+                array(
+                    'name'    => 'foo',
+                    'value'   => 'bar',
+                    'domain'  => null,
+                    'path'    => null,
+                    'expires' => null,
+                    'secure'  => false
+                ),
+                new Net_Url2('http://example.com/directory/file.php'),
+                array(
+                    'domain'  => 'example.com',
+                    'path'    => '/directory/'
+                )
+            ),
+            array(
+                array(
+                    'name'    => 'foo',
+                    'value'   => 'bar',
+                    'domain'  => '.example.com',
+                    'path'    => null,
+                    'expires' => null,
+                    'secure'  => false
+                ),
+                new Net_Url2('http://example.com/path/to/file.php'),
+                array(
+                    'path'    => '/path/to/'
+                )
+            ),
+            array(
+                array(
+                    'name'    => 'foo',
+                    'value'   => 'bar',
+                    'domain'  => null,
+                    'path'    => '/',
+                    'expires' => null,
+                    'secure'  => false
+                ),
+                new Net_Url2('http://example.com/another/file.php'),
+                array(
+                    'domain'  => 'example.com'
+                )
+            )
+        );
+    }
+
+    public static function cookieMatchProvider()
+    {
+        return array(
+            array('http://www.example.com/path/file.php', 4),
+            array('https://www.example.com/path/file.php', 5),
+            array('http://example.com/path/file.php', 3),
+            array('http://specific.example.com/path/file.php', 4),
+            array('http://specific.example.com/other/file.php', 3),
+            array('http://another.example.com/another', 2)
+        );
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/MultipartBodyTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/MultipartBodyTest.php
new file mode 100644
index 0000000..585800f
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/MultipartBodyTest.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: MultipartBodyTest.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/** Helper for PHPUnit includes */
+require_once dirname(dirname(__FILE__)) . '/TestHelper.php';
+
+/**
+ * Unit test for HTTP_Request2_MultipartBody class
+ */
+class HTTP_Request2_MultipartBodyTest extends PHPUnit_Framework_TestCase
+{
+    public function testUploadSimple()
+    {
+        $req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $body = $req->addPostParameter('foo', 'I am a parameter')
+                    ->addUpload('upload', dirname(dirname(__FILE__)) . '/_files/plaintext.txt')
+                    ->getBody();
+
+        $this->assertTrue($body instanceof HTTP_Request2_MultipartBody);
+        $asString = $body->__toString();
+        $boundary = $body->getBoundary();
+        $this->assertEquals($body->getLength(), strlen($asString));
+        $this->assertContains('This is a test.', $asString);
+        $this->assertContains('I am a parameter', $asString);
+        $this->assertRegexp("!--{$boundary}--\r\n$!", $asString);
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testRequest16863()
+    {
+        $req  = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $fp   = fopen(dirname(dirname(__FILE__)) . '/_files/plaintext.txt', 'rb');
+        $body = $req->addUpload('upload', $fp)
+                    ->getBody();
+
+        $asString = $body->__toString();
+        $this->assertContains('name="upload"; filename="anonymous.blob"', $asString);
+        $this->assertContains('This is a test.', $asString);
+
+        $req->addUpload('bad_upload', fopen('php://input', 'rb'));
+    }
+
+    public function testStreaming()
+    {
+        $req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $body = $req->addPostParameter('foo', 'I am a parameter')
+                    ->addUpload('upload', dirname(dirname(__FILE__)) . '/_files/plaintext.txt')
+                    ->getBody();
+        $asString = '';
+        while ($part = $body->read(10)) {
+            $asString .= $part;
+        }
+        $this->assertEquals($body->getLength(), strlen($asString));
+        $this->assertContains('This is a test.', $asString);
+        $this->assertContains('I am a parameter', $asString);
+    }
+
+    public function testUploadArray()
+    {
+        $req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $body = $req->addUpload('upload', array(
+                                    array(dirname(dirname(__FILE__)) . '/_files/plaintext.txt', 'bio.txt', 'text/plain'),
+                                    array(fopen(dirname(dirname(__FILE__)) . '/_files/empty.gif', 'rb'), 'photo.gif', 'image/gif')
+                                ))
+                    ->getBody();
+        $asString = $body->__toString();
+        $this->assertContains(file_get_contents(dirname(dirname(__FILE__)) . '/_files/empty.gif'), $asString);
+        $this->assertContains('name="upload[0]"; filename="bio.txt"', $asString);
+        $this->assertContains('name="upload[1]"; filename="photo.gif"', $asString);
+
+        $body2 = $req->setConfig(array('use_brackets' => false))->getBody();
+        $asString = $body2->__toString();
+        $this->assertContains('name="upload"; filename="bio.txt"', $asString);
+        $this->assertContains('name="upload"; filename="photo.gif"', $asString);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2/ResponseTest.php b/lib/tests/HTTP_Request2/HTTP/Request2/ResponseTest.php
new file mode 100644
index 0000000..a4898f1
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2/ResponseTest.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: ResponseTest.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP response
+ */
+require_once 'HTTP/Request2/Response.php';
+
+/** Helper for PHPUnit includes */
+require_once dirname(dirname(__FILE__)) . '/TestHelper.php';
+
+/**
+ * Unit test for HTTP_Request2_Response class
+ */
+class HTTP_Request2_ResponseTest extends PHPUnit_Framework_TestCase
+{
+   /**
+    *
+    * @expectedException HTTP_Request2_MessageException
+    */
+    public function testParseStatusLine()
+    {
+        $response = new HTTP_Request2_Response('HTTP/1.1 200 OK');
+        $this->assertEquals('1.1', $response->getVersion());
+        $this->assertEquals(200, $response->getStatus());
+        $this->assertEquals('OK', $response->getReasonPhrase());
+
+        $response2 = new HTTP_Request2_Response('HTTP/1.2 222 Nishtyak!');
+        $this->assertEquals('1.2', $response2->getVersion());
+        $this->assertEquals(222, $response2->getStatus());
+        $this->assertEquals('Nishtyak!', $response2->getReasonPhrase());
+
+        $response3 = new HTTP_Request2_Response('Invalid status line');
+    }
+
+    public function testParseHeaders()
+    {
+        $response = $this->readResponseFromFile('response_headers');
+        $this->assertEquals(7, count($response->getHeader()));
+        $this->assertEquals('PHP/6.2.2', $response->getHeader('X-POWERED-BY'));
+        $this->assertEquals('text/html; charset=windows-1251', $response->getHeader('cOnTeNt-TyPe'));
+        $this->assertEquals('accept-charset, user-agent', $response->getHeader('vary'));
+    }
+
+    public function testParseCookies()
+    {
+        $response = $this->readResponseFromFile('response_cookies');
+        $cookies  = $response->getCookies();
+        $this->assertEquals(4, count($cookies));
+        $expected = array(
+            array('name' => 'foo', 'value' => 'bar', 'expires' => null,
+                  'domain' => null, 'path' => null, 'secure' => false),
+            array('name' => 'PHPSESSID', 'value' => '1234567890abcdef1234567890abcdef',
+                  'expires' => null, 'domain' => null, 'path' => '/', 'secure' => true),
+            array('name' => 'A', 'value' => 'B=C', 'expires' => null,
+                  'domain' => null, 'path' => null, 'secure' => false),
+            array('name' => 'baz', 'value' => '%20a%20value', 'expires' => 'Sun, 03 Jan 2010 03:04:05 GMT',
+                  'domain' => 'pear.php.net', 'path' => null, 'secure' => false),
+        );
+        foreach ($cookies as $k => $cookie) {
+            $this->assertEquals($expected[$k], $cookie);
+        }
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_MessageException
+    */
+    public function testGzipEncoding()
+    {
+        $response = $this->readResponseFromFile('response_gzip');
+        $this->assertEquals('0e964e9273c606c46afbd311b5ad4d77', md5($response->getBody()));
+
+        $response = $this->readResponseFromFile('response_gzip_broken');
+        $body = $response->getBody();
+    }
+
+    public function testDeflateEncoding()
+    {
+        $response = $this->readResponseFromFile('response_deflate');
+        $this->assertEquals('0e964e9273c606c46afbd311b5ad4d77', md5($response->getBody()));
+    }
+
+    public function testBug15305()
+    {
+        $response = $this->readResponseFromFile('bug_15305');
+        $this->assertEquals('c8c5088fc8a7652afef380f086c010a6', md5($response->getBody()));
+    }
+
+    public function testBug18169()
+    {
+        $response = $this->readResponseFromFile('bug_18169');
+        $this->assertEquals('', $response->getBody());
+    }
+
+    protected function readResponseFromFile($filename)
+    {
+        $fp       = fopen(dirname(dirname(__FILE__)) . '/_files/' . $filename, 'rb');
+        $response = new HTTP_Request2_Response(fgets($fp));
+        do {
+            $headerLine = fgets($fp);
+            $response->parseHeaderLine($headerLine);
+        } while ('' != trim($headerLine));
+
+        while (!feof($fp)) {
+            $response->appendBody(fread($fp, 1024));
+        }
+        return $response;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/Request2Test.php b/lib/tests/HTTP_Request2/HTTP/Request2Test.php
new file mode 100644
index 0000000..10fc934
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/Request2Test.php
@@ -0,0 +1,381 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: Request2Test.php 309665 2011-03-24 21:03:48Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/** Helper for PHPUnit includes */
+require_once dirname(__FILE__) . '/TestHelper.php';
+
+/**
+ * Unit test for HTTP_Request2 class
+ */
+class HTTP_Request2Test extends PHPUnit_Framework_TestCase
+{
+    public function testConstructorSetsDefaults()
+    {
+        $url = new Net_URL2('http://www.example.com/foo');
+        $req = new HTTP_Request2($url, HTTP_Request2::METHOD_POST, array('connect_timeout' => 666));
+
+        $this->assertSame($url, $req->getUrl());
+        $this->assertEquals(HTTP_Request2::METHOD_POST, $req->getMethod());
+        $this->assertEquals(666, $req->getConfig('connect_timeout'));
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testSetUrl()
+    {
+        $urlString = 'http://www.example.com/foo/bar.php';
+        $url       = new Net_URL2($urlString);
+
+        $req1 = new HTTP_Request2();
+        $req1->setUrl($url);
+        $this->assertSame($url, $req1->getUrl());
+
+        $req2 = new HTTP_Request2();
+        $req2->setUrl($urlString);
+        $this->assertType('Net_URL2', $req2->getUrl());
+        $this->assertEquals($urlString, $req2->getUrl()->getUrl());
+
+        $req3 = new HTTP_Request2();
+        $req3->setUrl(array('This will cause an error'));
+    }
+
+    public function testConvertUserinfoToAuth()
+    {
+        $req = new HTTP_Request2();
+        $req->setUrl('http://foo:b%40r@www.example.com/');
+
+        $this->assertEquals('', (string)$req->getUrl()->getUserinfo());
+        $this->assertEquals(
+            array('user' => 'foo', 'password' => 'b@r', 'scheme' => HTTP_Request2::AUTH_BASIC),
+            $req->getAuth()
+        );
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testSetMethod()
+    {
+        $req = new HTTP_Request2();
+        $req->setMethod(HTTP_Request2::METHOD_PUT);
+        $this->assertEquals(HTTP_Request2::METHOD_PUT, $req->getMethod());
+
+        $req->setMethod('Invalid method');
+    }
+
+    public function testSetAndGetConfig()
+    {
+        $req = new HTTP_Request2();
+        $this->assertArrayHasKey('connect_timeout', $req->getConfig());
+
+        $req->setConfig(array('connect_timeout' => 123));
+        $this->assertEquals(123, $req->getConfig('connect_timeout'));
+        try {
+            $req->setConfig(array('foo' => 'unknown parameter'));
+            $this->fail('Expected HTTP_Request2_LogicException was not thrown');
+        } catch (HTTP_Request2_LogicException $e) {}
+
+        try {
+            $req->getConfig('bar');
+            $this->fail('Expected HTTP_Request2_LogicException was not thrown');
+        } catch (HTTP_Request2_LogicException $e) {}
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testHeaders()
+    {
+        $req = new HTTP_Request2();
+        $autoHeaders = $req->getHeaders();
+
+        $req->setHeader('Foo', 'Bar');
+        $req->setHeader('Foo-Bar: value');
+        $req->setHeader(array('Another-Header' => 'another value', 'Yet-Another: other_value'));
+        $this->assertEquals(
+            array('foo-bar' => 'value', 'another-header' => 'another value',
+            'yet-another' => 'other_value', 'foo' => 'Bar') + $autoHeaders,
+            $req->getHeaders()
+        );
+
+        $req->setHeader('FOO-BAR');
+        $req->setHeader(array('aNOTHER-hEADER'));
+        $this->assertEquals(
+            array('yet-another' => 'other_value', 'foo' => 'Bar') + $autoHeaders,
+            $req->getHeaders()
+        );
+
+        $req->setHeader('Invalid header', 'value');
+    }
+
+    public function testBug15937()
+    {
+        $req = new HTTP_Request2();
+        $autoHeaders = $req->getHeaders();
+
+        $req->setHeader('Expect: ');
+        $req->setHeader('Foo', '');
+        $this->assertEquals(
+            array('expect' => '', 'foo' => '') + $autoHeaders,
+            $req->getHeaders()
+        );
+    }
+
+    public function testRequest17507()
+    {
+        $req = new HTTP_Request2();
+
+        $req->setHeader('accept-charset', 'iso-8859-1');
+        $req->setHeader('accept-charset', array('windows-1251', 'utf-8'), false);
+
+        $req->setHeader(array('accept' => 'text/html'));
+        $req->setHeader(array('accept' => 'image/gif'), null, false);
+
+        $headers = $req->getHeaders();
+
+        $this->assertEquals('iso-8859-1, windows-1251, utf-8', $headers['accept-charset']);
+        $this->assertEquals('text/html, image/gif', $headers['accept']);
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testCookies()
+    {
+        $req = new HTTP_Request2();
+        $req->addCookie('name', 'value');
+        $req->addCookie('foo', 'bar');
+        $headers = $req->getHeaders();
+        $this->assertEquals('name=value; foo=bar', $headers['cookie']);
+
+        $req->addCookie('invalid cookie', 'value');
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testPlainBody()
+    {
+        $req = new HTTP_Request2();
+        $req->setBody('A string');
+        $this->assertEquals('A string', $req->getBody());
+
+        $req->setBody(dirname(__FILE__) . '/_files/plaintext.txt', true);
+        $headers = $req->getHeaders();
+        $this->assertRegexp(
+            '!^(text/plain|application/octet-stream)!',
+            $headers['content-type']
+        );
+        $this->assertEquals('This is a test.', fread($req->getBody(), 1024));
+
+        $req->setBody('missing file', true);
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testRequest16863()
+    {
+        $req = new HTTP_Request2();
+        $req->setBody(fopen(dirname(__FILE__) . '/_files/plaintext.txt', 'rb'));
+        $headers = $req->getHeaders();
+        $this->assertEquals('application/octet-stream', $headers['content-type']);
+
+        $req->setBody(fopen('php://input', 'rb'));
+    }
+
+    public function testUrlencodedBody()
+    {
+        $req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $req->addPostParameter('foo', 'bar');
+        $req->addPostParameter(array('baz' => 'quux'));
+        $req->addPostParameter('foobar', array('one', 'two'));
+        $this->assertEquals(
+            'foo=bar&baz=quux&foobar%5B0%5D=one&foobar%5B1%5D=two',
+            $req->getBody()
+        );
+
+        $req->setConfig(array('use_brackets' => false));
+        $this->assertEquals(
+            'foo=bar&baz=quux&foobar=one&foobar=two',
+            $req->getBody()
+        );
+    }
+
+    public function testRequest15368()
+    {
+        $req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $req->addPostParameter('foo', 'te~st');
+        $this->assertContains('~', $req->getBody());
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testUpload()
+    {
+        $req = new HTTP_Request2(null, HTTP_Request2::METHOD_POST);
+        $req->addUpload('upload', dirname(__FILE__) . '/_files/plaintext.txt');
+
+        $headers = $req->getHeaders();
+        $this->assertEquals('multipart/form-data', $headers['content-type']);
+
+        $req->addUpload('upload_2', 'missing file');
+    }
+
+    public function testPropagateUseBracketsToNetURL2()
+    {
+        $req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_GET,
+                                 array('use_brackets' => false));
+        $req->getUrl()->setQueryVariable('foo', array('bar', 'baz'));
+        $this->assertEquals('http://www.example.com/?foo=bar&foo=baz', $req->getUrl()->__toString());
+
+        $req->setConfig('use_brackets', true)->setUrl('http://php.example.com/');
+        $req->getUrl()->setQueryVariable('foo', array('bar', 'baz'));
+        $this->assertEquals('http://php.example.com/?foo[0]=bar&foo[1]=baz', $req->getUrl()->__toString());
+    }
+
+    public function testSetBodyRemovesPostParameters()
+    {
+        $req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
+        $req->addPostParameter('foo', 'bar');
+        $req->setBody('');
+        $this->assertEquals('', $req->getBody());
+    }
+
+    public function testPostParametersPrecedeSetBodyForPost()
+    {
+        $req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
+        $req->setBody('Request body');
+        $req->addPostParameter('foo', 'bar');
+
+        $this->assertEquals('foo=bar', $req->getBody());
+
+        $req->setMethod(HTTP_Request2::METHOD_PUT);
+        $this->assertEquals('Request body', $req->getBody());
+    }
+
+    public function testSetMultipartBody()
+    {
+        require_once 'HTTP/Request2/MultipartBody.php';
+
+        $req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
+        $body = new HTTP_Request2_MultipartBody(array('foo' => 'bar'), array());
+        $req->setBody($body);
+        $this->assertSame($body, $req->getBody());
+    }
+
+    public function testBug17460()
+    {
+        $req = new HTTP_Request2('http://www.example.com/', HTTP_Request2::METHOD_POST);
+        $req->addPostParameter('foo', 'bar')
+            ->setHeader('content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
+
+        $this->assertEquals('foo=bar', $req->getBody());
+    }
+
+   /**
+    *
+    * @expectedException HTTP_Request2_LogicException
+    */
+    public function testCookieJar()
+    {
+        $req = new HTTP_Request2();
+        $this->assertNull($req->getCookieJar());
+
+        $req->setCookieJar();
+        $jar = $req->getCookieJar();
+        $this->assertType('HTTP_Request2_CookieJar', $jar);
+
+        $req2 = new HTTP_Request2();
+        $req2->setCookieJar($jar);
+        $this->assertSame($jar, $req2->getCookieJar());
+
+        $req2->setCookieJar(null);
+        $this->assertNull($req2->getCookieJar());
+
+        $req2->setCookieJar('foo');
+    }
+
+    public function testAddCookieToJar()
+    {
+        $req = new HTTP_Request2();
+        $req->setCookieJar();
+
+        try {
+            $req->addCookie('foo', 'bar');
+            $this->fail('Expected HTTP_Request2_Exception was not thrown');
+        } catch (HTTP_Request2_LogicException $e) { }
+
+        $req->setUrl('http://example.com/path/file.php');
+        $req->addCookie('foo', 'bar');
+
+        $this->assertArrayNotHasKey('cookie', $req->getHeaders());
+        $cookies = $req->getCookieJar()->getAll();
+        $this->assertEquals(
+            array(
+                'name'    => 'foo',
+                'value'   => 'bar',
+                'domain'  => 'example.com',
+                'path'    => '/path/',
+                'expires' => null,
+                'secure'  => false
+            ),
+            $cookies[0]
+        );
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/TestHelper.php b/lib/tests/HTTP_Request2/HTTP/TestHelper.php
new file mode 100644
index 0000000..bbd2bf6
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/TestHelper.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: TestHelper.php 309682 2011-03-25 09:53:38Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/** Include PHPUnit dependencies based on version */
+require_once 'PHPUnit/Runner/Version.php';
+
+$phpunitVersion = PHPUnit_Runner_Version::id();
+if ($phpunitVersion == '@' . 'package_version@' || !version_compare($phpunitVersion, '3.6', '<=')) {
+    echo "This version of PHPUnit is not supported.";
+    exit(1);
+} elseif (version_compare($phpunitVersion, '3.5.0', '>=')) {
+    require_once 'PHPUnit/Autoload.php';
+} else {
+    require_once 'PHPUnit/Framework.php';
+}
+
+if (!defined('HTTP_REQUEST2_TESTS_BASE_URL')
+    && is_readable(dirname(__FILE__) . '/NetworkConfig.php')
+) {
+    require_once dirname(__FILE__) . '/NetworkConfig.php';
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_files/bug_15305 b/lib/tests/HTTP_Request2/HTTP/_files/bug_15305
new file mode 100644
index 0000000000000000000000000000000000000000..bbf6c70006b8062fd656063ee9cbbff16edf7f04
GIT binary patch
literal 16338
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

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/_files/bug_18169 b/lib/tests/HTTP_Request2/HTTP/_files/bug_18169
new file mode 100644
index 0000000..c50dae1
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_files/bug_18169
@@ -0,0 +1,9 @@
+HTTP/1.1 200 OK
+Date: Fri, 01 Jan 2010 02:03:04 GMT
+Server: Apache/3.0.1 (Unix)
+X-Powered-By: PHP/6.2.2
+Content-Type: text/plain; charset=iso-8859-1
+Content-Encoding: deflate
+Content-Length: 0
+Connection: close
+
diff --git a/lib/tests/HTTP_Request2/HTTP/_files/empty.gif b/lib/tests/HTTP_Request2/HTTP/_files/empty.gif
new file mode 100644
index 0000000000000000000000000000000000000000..1d11fa9ada9e93505b3d736acb204083f45d5fbf
GIT binary patch
literal 43
ucmZ?wbhEHbWMp7uX!y@?;J^U}1_s5SEQ|~c3=BFT0wlx0#N@)rU=0A%AqP7E

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/_files/plaintext.txt b/lib/tests/HTTP_Request2/HTTP/_files/plaintext.txt
new file mode 100644
index 0000000..273c1a9
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_files/plaintext.txt
@@ -0,0 +1 @@
+This is a test.
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_files/response_cookies b/lib/tests/HTTP_Request2/HTTP/_files/response_cookies
new file mode 100644
index 0000000..8f0ab6b
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_files/response_cookies
@@ -0,0 +1,13 @@
+HTTP/1.1 200 OK
+Date: Fri, 01 Jan 2010 02:03:04 GMT
+Server: Apache/3.0.1 (Unix)
+X-Powered-By: PHP/6.2.2
+Set-Cookie: foo=bar
+Set-Cookie: PHPSESSID=1234567890abcdef1234567890abcdef; path=/; secure
+Set-Cookie: A=B=C
+Set-Cookie: baz=%20a%20value; expires=Sun, 03 Jan 2010 03:04:05 GMT; domain=pear.php.net
+Content-Type: text/html; charset=windows-1251
+Content-Length: 32
+Connection: close
+
+Nothing to see here, move along.
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_files/response_deflate b/lib/tests/HTTP_Request2/HTTP/_files/response_deflate
new file mode 100644
index 0000000000000000000000000000000000000000..e4e8adfd0d46af40addef96b0e95dad6243e6232
GIT binary patch
literal 1654
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
J_U*2(wE)T#0{Z{}

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/_files/response_gzip b/lib/tests/HTTP_Request2/HTTP/_files/response_gzip
new file mode 100644
index 0000000000000000000000000000000000000000..79ad3b6eaac6737c9ae4a577347cb52e26ea5209
GIT binary patch
literal 1672
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
b{8oMR6aL%#z%k7$<rlm4ytN6Fco-M}RtE+f

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/_files/response_gzip_broken b/lib/tests/HTTP_Request2/HTTP/_files/response_gzip_broken
new file mode 100644
index 0000000000000000000000000000000000000000..0df0d1522f8a377ac905b20db95eb29dc1428493
GIT binary patch
literal 221
zcmeYW2?@|Q)H75tGB8l^_vYntNi0dVQgAEE)KM@nRPaj7Q!p|xG*B=wvNABXGB8na
z_YL9Y3QjF5OD(cea4bkn&Pdfa)-%vERL}^`%dF7k<%-Y^$S+SVN=?yqs<cuF@CeX1
z(=*aD;^lJA&nrpIE71+9EJ(FdC`qj-(J#nJ%*?Y^NX|$sDo!o2%`DE>wXiU?)HOt?
zcFjx9Psz+nw^B&2$}9kj=cOi>Waj5tDJ19Q7pL-a@p8#`b8u8ARk<@T8^;?M>XlTK
JFl-I;1pr2%Kh*#L

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/_files/response_headers b/lib/tests/HTTP_Request2/HTTP/_files/response_headers
new file mode 100644
index 0000000..f60787b
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_files/response_headers
@@ -0,0 +1,12 @@
+HTTP/1.1 200 OK
+Date: Fri, 01 Jan 2010 02:03:04 GMT
+Vary: accept-charset
+Server: Apache/3.0.1 (Unix)
+X-Powered-By:                PHP/6.2.2
+Vary: user-agent
+Content-Type: text/html;
+    charset=windows-1251
+Content-Length: 32
+Connection: close
+
+Nothing to see here, move along.
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/basicauth.php b/lib/tests/HTTP_Request2/HTTP/_network/basicauth.php
new file mode 100644
index 0000000..383a785
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/basicauth.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: basicauth.php 308300 2011-02-13 12:24:18Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+$user       = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null;
+$pass       = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null;
+$wantedUser = isset($_GET['user']) ? $_GET['user'] : null;
+$wantedPass = isset($_GET['pass']) ? $_GET['pass'] : null;
+
+if (!$user || !$pass || $user != $wantedUser || $pass != $wantedPass) {
+    header('WWW-Authenticate: Basic realm="HTTP_Request2 tests"', true, 401);
+    echo "Login required";
+} else {
+    echo "Username={$user};Password={$pass}";
+}
+
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/cookies.php b/lib/tests/HTTP_Request2/HTTP/_network/cookies.php
new file mode 100644
index 0000000..5ab966c
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/cookies.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: cookies.php 308299 2011-02-12 23:20:23Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+ksort($_COOKIE);
+echo serialize($_COOKIE);
+
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/digestauth.php b/lib/tests/HTTP_Request2/HTTP/_network/digestauth.php
new file mode 100644
index 0000000..463f25a
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/digestauth.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: digestauth.php 308300 2011-02-13 12:24:18Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Mostly borrowed from PHP manual and Socket Adapter implementation
+ *
+ * @link http://php.net/manual/en/features.http-auth.php
+ */
+
+/**
+ * Parses the Digest auth header
+ *
+ * @param string $txt
+ */
+function http_digest_parse($txt)
+{
+    $token  = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';
+    $quoted = '"(?:\\\\.|[^\\\\"])*"';
+
+    // protect against missing data
+    $needed_parts = array_flip(array('nonce', 'nc', 'cnonce', 'qop', 'username', 'uri', 'response'));
+    $data         = array();
+
+    preg_match_all("!({$token})\\s*=\\s*({$token}|{$quoted})!", $txt, $matches);
+    for ($i = 0; $i < count($matches[0]); $i++) {
+        // ignore unneeded parameters
+        if (isset($needed_parts[$matches[1][$i]])) {
+            unset($needed_parts[$matches[1][$i]]);
+            if ('"' == substr($matches[2][$i], 0, 1)) {
+                $data[$matches[1][$i]] = substr($matches[2][$i], 1, -1);
+            } else {
+                $data[$matches[1][$i]] = $matches[2][$i];
+            }
+        }
+    }
+
+    return !empty($needed_parts) ? false : $data;
+}
+
+$realm      = 'HTTP_Request2 tests';
+$wantedUser = isset($_GET['user']) ? $_GET['user'] : null;
+$wantedPass = isset($_GET['pass']) ? $_GET['pass'] : null;
+$validAuth  = false;
+
+if (!empty($_SERVER['PHP_AUTH_DIGEST'])
+    && ($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST']))
+    && $wantedUser == $data['username']
+) {
+    // generate the valid response
+    $a1       = md5($data['username'] . ':' . $realm . ':' . $wantedPass);
+    $a2       = md5($_SERVER['REQUEST_METHOD'] . ':' . $data['uri']);
+    $response = md5($a1. ':' . $data['nonce'] . ':' . $data['nc'] . ':'
+                    . $data['cnonce'] . ':' . $data['qop'] . ':' . $a2);
+
+    // check valid response against existing one
+    $validAuth = ($data['response'] == $response);
+}
+
+if (!$validAuth || empty($_SERVER['PHP_AUTH_DIGEST'])) {
+    header('WWW-Authenticate: Digest realm="' . $realm .
+           '",qop="auth",nonce="' . uniqid() . '"', true, 401);
+    echo "Login required";
+} else {
+    echo "Username={$user}";
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/getparameters.php b/lib/tests/HTTP_Request2/HTTP/_network/getparameters.php
new file mode 100644
index 0000000..334a132
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/getparameters.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: getparameters.php 308299 2011-02-12 23:20:23Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+ksort($_GET);
+echo serialize($_GET);
+
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/postparameters.php b/lib/tests/HTTP_Request2/HTTP/_network/postparameters.php
new file mode 100644
index 0000000..7037d88
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/postparameters.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: postparameters.php 308300 2011-02-13 12:24:18Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+ksort($_POST);
+echo serialize($_POST);
+
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/rawpostdata.php b/lib/tests/HTTP_Request2/HTTP/_network/rawpostdata.php
new file mode 100644
index 0000000..e6a1d26
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/rawpostdata.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: rawpostdata.php 308300 2011-02-13 12:24:18Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+readfile('php://input');
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/redirects.php b/lib/tests/HTTP_Request2/HTTP/_network/redirects.php
new file mode 100644
index 0000000..f7a7f81
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/redirects.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: redirects.php 308480 2011-02-19 11:27:13Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+$redirects = isset($_GET['redirects'])? $_GET['redirects']: 1;
+$https     = !empty($_SERVER['HTTPS']) && ('off' != strtolower($_SERVER['HTTPS']));
+$special   = isset($_GET['special'])? $_GET['special']: null;
+
+if ('ftp' == $special) {
+    header('Location: ftp://localhost/pub/exploit.exe', true, 301);
+
+} elseif ('relative' == $special) {
+    header('Location: ./getparameters.php?msg=did%20relative%20redirect', true, 302);
+
+} elseif ('cookie' == $special) {
+    setcookie('cookie_on_redirect', 'success');
+    header('Location: ./cookies.php', true, 302);
+
+} elseif ($redirects > 0) {
+    $url = ($https? 'https': 'http') . '://' . $_SERVER['SERVER_NAME']
+           . (($https && 443 == $_SERVER['SERVER_PORT'] || !$https && 80 == $_SERVER['SERVER_PORT'])
+              ? '' : ':' . $_SERVER['SERVER_PORT'])
+           . $_SERVER['PHP_SELF'] . '?redirects=' . (--$redirects);
+    header('Location: ' . $url, true, 302);
+
+} else {
+    echo "Method=" . $_SERVER['REQUEST_METHOD'] . ';';
+    var_dump($_POST);
+    var_dump($_GET);
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/setcookie.php b/lib/tests/HTTP_Request2/HTTP/_network/setcookie.php
new file mode 100644
index 0000000..bece103
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/setcookie.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: setcookie.php 308480 2011-02-19 11:27:13Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+$name  = empty($_GET['name'])? 'foo': $_GET['name'];
+$value = empty($_GET['value'])? 'bar': $_GET['value'];
+
+setcookie($name, $value);
+
+echo "Cookie set!";
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/timeout.php b/lib/tests/HTTP_Request2/HTTP/_network/timeout.php
new file mode 100644
index 0000000..f99d871
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/timeout.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: timeout.php 308299 2011-02-12 23:20:23Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+sleep(5);
+
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/_network/uploads.php b/lib/tests/HTTP_Request2/HTTP/_network/uploads.php
new file mode 100644
index 0000000..7a124de
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/_network/uploads.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Helper files for HTTP_Request2 unit tests. Should be accessible via HTTP.
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>
+ * 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.
+ *    * The names of the authors may not 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   HTTP
+ * @package    HTTP_Request2
+ * @author     Alexey Borzov <avb@php.net>
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    SVN: $Id: uploads.php 308300 2011-02-13 12:24:18Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!empty($_FILES)) {
+    foreach ($_FILES as $name => $file) {
+        if (is_array($file['name'])) {
+            foreach($file['name'] as $k => $v) {
+                echo "{$name}[{$k}] {$v} {$file['type'][$k]} {$file['size'][$k]}\n";
+            }
+        } else {
+            echo "{$name} {$file['name']} {$file['type']} {$file['size']}\n";
+        }
+    }
+}
+?>
\ No newline at end of file
-- 
GitLab